commit 32ad61605ca29ce042710656dd1229c6997acaf1 Author: kishan06 Date: Wed Apr 10 12:51:20 2024 +0530 first commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..029412f Binary files /dev/null and b/.DS_Store differ diff --git a/.dart_tool/extension_discovery/README.md b/.dart_tool/extension_discovery/README.md new file mode 100644 index 0000000..9dc6757 --- /dev/null +++ b/.dart_tool/extension_discovery/README.md @@ -0,0 +1,31 @@ +Extension Discovery Cache +========================= + +This folder is used by `package:extension_discovery` to cache lists of +packages that contains extensions for other packages. + +DO NOT USE THIS FOLDER +---------------------- + + * Do not read (or rely) the contents of this folder. + * Do write to this folder. + +If you're interested in the lists of extensions stored in this folder use the +API offered by package `extension_discovery` to get this information. + +If this package doesn't work for your use-case, then don't try to read the +contents of this folder. It may change, and will not remain stable. + +Use package `extension_discovery` +--------------------------------- + +If you want to access information from this folder. + +Feel free to delete this folder +------------------------------- + +Files in this folder act as a cache, and the cache is discarded if the files +are older than the modification time of `.dart_tool/package_config.json`. + +Hence, it should never be necessary to clear this cache manually, if you find a +need to do please file a bug. diff --git a/.dart_tool/extension_discovery/vs_code.json b/.dart_tool/extension_discovery/vs_code.json new file mode 100644 index 0000000..18073f8 --- /dev/null +++ b/.dart_tool/extension_discovery/vs_code.json @@ -0,0 +1 @@ +{"version":2,"entries":[{"package":"icdevicemanager_flutter","rootUri":"../","packageUri":"lib/"}]} \ No newline at end of file diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json new file mode 100644 index 0000000..1455258 --- /dev/null +++ b/.dart_tool/package_config.json @@ -0,0 +1,422 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "_fe_analyzer_shared", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-31.0.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "analyzer", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/analyzer-2.8.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "args", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/args-2.4.0", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "async", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/async-2.10.0", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "boolean_selector", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "build", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build-2.0.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "build_config", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_config-0.4.7", + "packageUri": "lib/", + "languageVersion": "2.11" + }, + { + "name": "build_daemon", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_daemon-2.1.10", + "packageUri": "lib/", + "languageVersion": "2.11" + }, + { + "name": "build_resolvers", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_resolvers-2.0.6", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "build_runner", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner-1.12.2", + "packageUri": "lib/", + "languageVersion": "2.11" + }, + { + "name": "build_runner_core", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner_core-6.1.12", + "packageUri": "lib/", + "languageVersion": "2.11" + }, + { + "name": "built_collection", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_collection-5.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "built_value", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_value-8.4.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "change_app_package_name", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/change_app_package_name-1.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "characters", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/characters-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "checked_yaml", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/checked_yaml-2.0.2", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "cli_util", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/cli_util-0.3.5", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "clock", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/clock-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "code_builder", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/code_builder-3.7.0", + "packageUri": "lib/", + "languageVersion": "2.7" + }, + { + "name": "collection", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/collection-1.17.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "convert", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/convert-3.1.1", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "crypto", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/crypto-3.0.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "dart_style", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/dart_style-2.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "fake_async", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fake_async-1.3.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "file", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/file-6.1.4", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "fixnum", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fixnum-1.1.0", + "packageUri": "lib/", + "languageVersion": "2.19" + }, + { + "name": "flutter", + "rootUri": "file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "flutter_lints", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "flutter_test", + "rootUri": "file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter_test", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "glob", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/glob-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.15" + }, + { + "name": "graphs", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/graphs-1.0.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "http_multi_server", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "http_parser", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_parser-4.0.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "io", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/io-1.0.4", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "js", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/js-0.6.5", + "packageUri": "lib/", + "languageVersion": "2.16" + }, + { + "name": "json_annotation", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_annotation-4.6.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "json_serializable", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_serializable-6.3.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "lints", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/lints-2.0.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "logging", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/logging-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "matcher", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/matcher-0.12.13", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "material_color_utilities", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0", + "packageUri": "lib/", + "languageVersion": "2.13" + }, + { + "name": "meta", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/meta-1.8.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "mime", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/mime-1.0.4", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "package_config", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/package_config-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "path", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/path-1.8.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "pedantic", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pedantic-1.11.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "plugin_platform_interface", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.4", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "pool", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pool-1.5.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "pub_semver", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pub_semver-2.1.3", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "pubspec_parse", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pubspec_parse-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "shelf", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf-1.4.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "shelf_web_socket", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf_web_socket-1.0.3", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "sky_engine", + "rootUri": "file:///Users/macbookpro/flutteroldversion/flutter/bin/cache/pkg/sky_engine", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_gen", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_gen-1.0.5", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_helper", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_helper-1.3.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_span", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_span-1.9.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "stack_trace", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stack_trace-1.11.0", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "stream_channel", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_channel-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "stream_transform", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_transform-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "string_scanner", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/string_scanner-1.2.0", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "term_glyph", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/term_glyph-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "test_api", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/test_api-0.4.16", + "packageUri": "lib/", + "languageVersion": "2.18" + }, + { + "name": "timing", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/timing-1.0.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "typed_data", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/typed_data-1.3.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "vector_math", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/vector_math-2.1.4", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "watcher", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/watcher-1.0.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "web_socket_channel", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/web_socket_channel-2.3.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "yaml", + "rootUri": "file:///Users/macbookpro/.pub-cache/hosted/pub.dev/yaml-3.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "icdevicemanager_flutter", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "2.17" + } + ], + "generated": "2024-04-08T07:22:52.056049Z", + "generator": "pub", + "generatorVersion": "2.19.6" +} diff --git a/.dart_tool/package_config_subset b/.dart_tool/package_config_subset new file mode 100644 index 0000000..cc602fc --- /dev/null +++ b/.dart_tool/package_config_subset @@ -0,0 +1,277 @@ +_fe_analyzer_shared +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-31.0.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-31.0.0/lib/ +analyzer +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/analyzer-2.8.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/analyzer-2.8.0/lib/ +args +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/args-2.4.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/args-2.4.0/lib/ +async +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/async-2.10.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/async-2.10.0/lib/ +boolean_selector +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1/lib/ +build +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build-2.0.3/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build-2.0.3/lib/ +build_config +2.11 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_config-0.4.7/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_config-0.4.7/lib/ +build_daemon +2.11 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_daemon-2.1.10/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_daemon-2.1.10/lib/ +build_resolvers +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_resolvers-2.0.6/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_resolvers-2.0.6/lib/ +build_runner +2.11 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner-1.12.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner-1.12.2/lib/ +build_runner_core +2.11 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner_core-6.1.12/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/build_runner_core-6.1.12/lib/ +built_collection +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_collection-5.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_collection-5.1.1/lib/ +built_value +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_value-8.4.3/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/built_value-8.4.3/lib/ +change_app_package_name +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/change_app_package_name-1.1.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/change_app_package_name-1.1.0/lib/ +characters +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/characters-1.2.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/characters-1.2.1/lib/ +checked_yaml +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/checked_yaml-2.0.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/checked_yaml-2.0.2/lib/ +cli_util +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/cli_util-0.3.5/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/cli_util-0.3.5/lib/ +clock +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/clock-1.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/clock-1.1.1/lib/ +code_builder +2.7 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/code_builder-3.7.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/code_builder-3.7.0/lib/ +collection +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/collection-1.17.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/collection-1.17.0/lib/ +convert +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/convert-3.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/convert-3.1.1/lib/ +crypto +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/crypto-3.0.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/crypto-3.0.2/lib/ +dart_style +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/dart_style-2.2.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/dart_style-2.2.1/lib/ +fake_async +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fake_async-1.3.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fake_async-1.3.1/lib/ +file +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/file-6.1.4/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/file-6.1.4/lib/ +fixnum +2.19 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fixnum-1.1.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib/ +flutter_lints +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/lib/ +glob +2.15 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/glob-2.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/glob-2.1.1/lib/ +graphs +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/graphs-1.0.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/graphs-1.0.0/lib/ +http_multi_server +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1/lib/ +http_parser +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_parser-4.0.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/http_parser-4.0.2/lib/ +io +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/io-1.0.4/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/io-1.0.4/lib/ +js +2.16 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/js-0.6.5/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/js-0.6.5/lib/ +json_annotation +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_annotation-4.6.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_annotation-4.6.0/lib/ +json_serializable +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_serializable-6.3.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/json_serializable-6.3.1/lib/ +lints +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/lints-2.0.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/lints-2.0.1/lib/ +logging +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/logging-1.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/logging-1.1.1/lib/ +matcher +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/matcher-0.12.13/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/matcher-0.12.13/lib/ +material_color_utilities +2.13 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/ +meta +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/meta-1.8.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/meta-1.8.0/lib/ +mime +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/mime-1.0.4/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/mime-1.0.4/lib/ +package_config +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/package_config-2.1.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/package_config-2.1.0/lib/ +path +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/path-1.8.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/path-1.8.2/lib/ +pedantic +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pedantic-1.11.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pedantic-1.11.1/lib/ +plugin_platform_interface +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.4/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.4/lib/ +pool +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pool-1.5.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pool-1.5.1/lib/ +pub_semver +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pub_semver-2.1.3/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pub_semver-2.1.3/lib/ +pubspec_parse +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pubspec_parse-1.2.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/pubspec_parse-1.2.1/lib/ +shelf +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf-1.4.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf-1.4.0/lib/ +shelf_web_socket +2.17 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf_web_socket-1.0.3/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/shelf_web_socket-1.0.3/lib/ +source_gen +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_gen-1.0.5/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_gen-1.0.5/lib/ +source_helper +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_helper-1.3.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_helper-1.3.2/lib/ +source_span +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_span-1.9.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/ +stack_trace +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/ +stream_channel +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/ +stream_transform +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_transform-2.1.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/stream_transform-2.1.0/lib/ +string_scanner +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/lib/ +term_glyph +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib/ +test_api +2.18 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/test_api-0.4.16/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/test_api-0.4.16/lib/ +timing +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/timing-1.0.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/timing-1.0.1/lib/ +typed_data +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/typed_data-1.3.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/typed_data-1.3.1/lib/ +vector_math +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/vector_math-2.1.4/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib/ +watcher +2.14 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/watcher-1.0.2/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/watcher-1.0.2/lib/ +web_socket_channel +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/web_socket_channel-2.3.0/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/web_socket_channel-2.3.0/lib/ +yaml +2.12 +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/yaml-3.1.1/ +file:///Users/macbookpro/.pub-cache/hosted/pub.dev/yaml-3.1.1/lib/ +icdevicemanager_flutter +2.17 +file:///Users/macbookpro/Desktop/Flutter%20Projects%20/GSFV8/ +file:///Users/macbookpro/Desktop/Flutter%20Projects%20/GSFV8/lib/ +sky_engine +2.12 +file:///Users/macbookpro/flutteroldversion/flutter/bin/cache/pkg/sky_engine/ +file:///Users/macbookpro/flutteroldversion/flutter/bin/cache/pkg/sky_engine/lib/ +flutter +2.17 +file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter/ +file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter/lib/ +flutter_test +2.17 +file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter_test/ +file:///Users/macbookpro/flutteroldversion/flutter/packages/flutter_test/lib/ +2 diff --git a/.dart_tool/version b/.dart_tool/version new file mode 100644 index 0000000..bf462cb --- /dev/null +++ b/.dart_tool/version @@ -0,0 +1 @@ +3.7.10 \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/icdevicemanager-flutter-with-scale.iml b/.idea/icdevicemanager-flutter-with-scale.iml new file mode 100644 index 0000000..97d0357 --- /dev/null +++ b/.idea/icdevicemanager-flutter-with-scale.iml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..95eeb23 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..a81ff8d --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..9d5efe5 --- /dev/null +++ b/.metadata @@ -0,0 +1,33 @@ +# 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: f1875d570e39de09040c8f79aa13cc56baab8db1 + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: android + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: ios + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + + # 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/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..45ace8a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "icdevicemanager-flutter-with-scale", + "request": "launch", + "type": "dart" + }, + { + "name": "icdevicemanager-flutter-with-scale (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "icdevicemanager-flutter-with-scale (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "gsf", + "cwd": "gsf", + "request": "launch", + "type": "dart" + }, + { + "name": "gsf (profile mode)", + "cwd": "gsf", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "gsf (release mode)", + "cwd": "gsf", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8257e8d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dart.flutterSdkPath": "~/Flutter/Sdk/3.7.12" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..64c21a1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..97cfb48 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..a66c323 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..a2b1dea --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..968fb32 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,40 @@ +group 'cn.icomon.icdevicemanager.flutter' +version '1.0.0' + +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 31 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + minSdkVersion 21 + } +} +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.alibaba:fastjson:1.2.69' +} + diff --git a/android/libs/ICBleProtocol.jar b/android/libs/ICBleProtocol.jar new file mode 100644 index 0000000..f01d9f3 Binary files /dev/null and b/android/libs/ICBleProtocol.jar differ diff --git a/android/libs/ICBodyFatAlgorithms.jar b/android/libs/ICBodyFatAlgorithms.jar new file mode 100644 index 0000000..2076bbf Binary files /dev/null and b/android/libs/ICBodyFatAlgorithms.jar differ diff --git a/android/libs/ICLogger.jar b/android/libs/ICLogger.jar new file mode 100644 index 0000000..b8eef0a Binary files /dev/null and b/android/libs/ICLogger.jar differ diff --git a/android/libs/icdevicemanager.jar b/android/libs/icdevicemanager.jar new file mode 100644 index 0000000..ba2b17c Binary files /dev/null and b/android/libs/icdevicemanager.jar differ diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..ab4497a --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'flutter_swift' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..06c39fd --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICBluetoothSDKPlugin.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICBluetoothSDKPlugin.java new file mode 100644 index 0000000..f9d639a --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICBluetoothSDKPlugin.java @@ -0,0 +1,332 @@ +package cn.icomon.icdevicemanager.flutter; + + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import cn.icomon.icdevicemanager.model.data.ICSkipLightSettingData; +import cn.icomon.icdevicemanager.model.data.ICSkipSoundSettingData; +import cn.icomon.icdevicemanager.model.data.ICWeightData; +import cn.icomon.icdevicemanager.model.device.ICDevice; +import cn.icomon.icdevicemanager.model.device.ICUserInfo; +import cn.icomon.icdevicemanager.model.other.ICDeviceManagerConfig; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +public class ICBluetoothSDKPlugin implements FlutterPlugin, MethodCallHandler { + + private MethodChannel channel; + + private Context mContext; + + private final String TAG = "ICSDKManager"; + + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { + channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "ic_bluetooth_sdk"); + mContext = flutterPluginBinding.getApplicationContext(); + channel.setMethodCallHandler(this); + ICSDKManager.channel = channel; + + } + + + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { + Object arguments = call.arguments(); + HashMap params = new HashMap<>(); + HashMap resultMap = new HashMap<>(); + + if (arguments instanceof HashMap) { + HashMap map = (HashMap) arguments; + for (Map.Entry entry : map.entrySet()) { + Log.e("Entry", entry.getKey() + " -----" + entry.getValue().toString()); + } + params.putAll(map); + } + Object jsonObj = params.get(ICMapKey.JsonValue); + Object macObj = params.get(ICMapKey.Mac); + Object enumObj = params.get(ICMapKey.EnumName); + Object intObj = params.get(ICMapKey.IntValue); + + + String mac = ""; + String cmdValue = ""; + List devList; + Object path; + String filePath = ""; + int weight = 0; + Log.e("onMethodCall", call.method); + + + if (jsonObj != null) cmdValue = jsonObj.toString(); + if (macObj != null) mac = macObj.toString(); + if (intObj != null) weight = (int) intObj; + + switch (call.method) { + case ICWPublishEvent.InitSDK: + ICDeviceManagerConfig config = new ICDeviceManagerConfig(); + config.setContext(mContext); + ICSDKManager.getInstance().initSdk(config); + break; + case ICWPublishEvent.AddDevice: + ICSDKManager.getInstance().addDevice(mac, (dev, code) -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.AddDevices: + devList = ICJson.toJavaList(cmdValue, ICDevice.class); + ICSDKManager.getInstance().addDevices(devList, (device1, code) -> { + resultMap.put(ICMapKey.EnumName, code.name()); + resultMap.put(ICMapKey.Mac, device1.macAddr); + result.success(resultMap); + }); + break; + case ICWPublishEvent.DeleteDevice: + ICSDKManager.getInstance().removeDevice(mac, (device1, code) -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.DeleteDevices: + devList = ICJson.toJavaList(cmdValue, ICDevice.class); + ICSDKManager.getInstance().removeDevices(devList, (device1, code) -> { + resultMap.put(ICMapKey.EnumName, code.name()); + resultMap.put(ICMapKey.Mac, device1.macAddr); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.OTADevice: + path = params.get(ICMapKey.StringValue); + if (path != null) { + filePath = path.toString(); + } + + ICSDKManager.getInstance().upgradeDevice(mac, filePath, ICDataConvert.getSDKOTAMode(enumObj)); + break; + + case ICWPublishEvent.OTADevices: + devList = ICJson.toJavaList(cmdValue, ICDevice.class); + path = params.get(ICMapKey.StringValue); + if (path != null) { + filePath = path.toString(); + } + ICSDKManager.getInstance().upgradeDevices(devList, filePath, ICDataConvert.getSDKOTAMode(enumObj)); + break; + + case ICWPublishEvent.StopOTADevice: + ICSDKManager.getInstance().stopUpgradeDevice(mac); + break; + + case ICWPublishEvent.StopOTADevices: + devList = ICJson.toJavaList(cmdValue, ICDevice.class); + ICSDKManager.getInstance().stopUpgradeDevices(devList); + break; + case ICWPublishEvent.StartScan: + ICSDKManager.getInstance().scanDevice(); + break; + case ICWPublishEvent.StopScan: + ICSDKManager.getInstance().stopScan(); + break; + case ICWPublishEvent.ScaleConfigWifi: + Object ssidObj = params.get(ICMapKey.SSID); + Object passwordObj = params.get(ICMapKey.Password); + ICSDKManager.getInstance().configWifi(mac, ssidObj, passwordObj, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.ScaleUnitSetting: + ICSDKManager.getInstance().setScaleUnit(mac, ICDataConvert.getSDKScaleUnit(enumObj), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.RulerUnitSetting: + ICSDKManager.getInstance().setRulerUnit(mac, ICDataConvert.getRulerUnit(enumObj), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + + break; + case ICWPublishEvent.RulerModeSetting: + ICSDKManager.getInstance().setRulerMeasureMode(mac, ICDataConvert.getRulerMode(enumObj), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.RulerBodyPartSetting: + ICSDKManager.getInstance().setRulerBodyPartsType(mac, ICDataConvert.getSDKRulerPart(enumObj), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + + break; + + case ICWPublishEvent.KitchenUnitSetting: + ICSDKManager.getInstance().setKitchenScaleUnit(mac, ICDataConvert.getSDKKitchenUnitUnit(enumObj), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + + break; + case ICWPublishEvent.KitchenPowerOff: + ICSDKManager.getInstance().powerOffKitchenScale(mac, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.KitchenCMD: + break; + case ICWPublishEvent.KitchenTareWeight: + + ICSDKManager.getInstance().deleteTareWeight(mac, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.KitchenFactory: + + break; + + case ICWPublishEvent.SetSkipMode: + case ICWPublishEvent.SkipStart: + Object settingObj = params.get(ICMapKey.IntValue); + int nSetting = 0; + if (settingObj != null) nSetting = (int) settingObj; + ICSDKManager.getInstance().startSkip(mac, ICDataConvert.getSkipMode(enumObj), nSetting, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.SkipStop: + ICSDKManager.getInstance().stopSkip(mac, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.SkipLightSetting: + List lightSettingData = ICJson.toJavaList(cmdValue, SkipLightSettingData.class); + List data = new ArrayList<>(); + for (SkipLightSettingData item : lightSettingData) { + data.add(new ICSkipLightSettingData(item.r, item.g, item.b, item.rpm)); + } + ICSDKManager.getInstance().setSkipLightSetting(mac, data, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + + break; + case ICWPublishEvent.SkipSoundSetting: + ICSkipSoundSettingData soundSettingData = ICJson.typeToObject(cmdValue, ICSkipSoundSettingData.class); + if (soundSettingData != null) { + ICSDKManager.getInstance().setSkipVoiceSetting(mac, soundSettingData, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + } + break; + case ICWPublishEvent.SetUserInfo: + ICSDKManager.getInstance().syncUserInfo(ICJson.typeToObject(cmdValue, ICUserInfo.class)); + break; + case ICWPublishEvent.SetUserList: + ICSDKManager.getInstance().syncUserList(ICJson.toJavaList(cmdValue, ICUserInfo.class)); + break; + case ICWPublishEvent.SkipSetWeight: + ICSDKManager.getInstance().setWeight(mac, weight, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.KitchenSetNutritionFacts: + ICSDKManager.getInstance().setNutritionFacts(mac, ICDataConvert.getSDKNutritionFactType(enumObj), weight, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.SetServerUrl: + ICSDKManager.getInstance().setServerUrl(mac, params.get(ICMapKey.StringValue), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.SetOtherParams: + break; + case ICWPublishEvent.SetScaleUIItems: + break; + case ICWPublishEvent.SkipLockSt: + ICSDKManager.getInstance().lockStSkip(mac, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + case ICWPublishEvent.QueryStAllNode: + ICSDKManager.getInstance().queryStAllNode(mac, code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.ChangeStName: + ICSDKManager.getInstance().changeStName(mac, params.get(ICMapKey.StringValue), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + + break; + case ICWPublishEvent.ChangeStNo: + + ICSDKManager.getInstance().changeStNo(mac, params.get(ICMapKey.DstId), params.get(ICMapKey.StNo), code -> { + resultMap.put(ICMapKey.EnumName, code.name()); + result.success(resultMap); + }); + break; + + case ICWPublishEvent.GetLogPath: + String logPath = ICSDKManager.getInstance().getLogPath(); + resultMap.put(ICMapKey.StringValue,logPath); + result.success(resultMap); + break; + + case ICWPublishEvent.CalcBodyFat: + + ICWeightData weightData = ICJson.typeToObject(cmdValue, ICWeightData.class); + Object userJson = params.get(ICMapKey.JsonValue2); + if (userJson != null) { + ICUserInfo userInfo = ICJson.typeToObject((String) userJson, ICUserInfo.class); + ICWeightData resultWeight = ICSDKManager.getInstance().CalcBodyFat(weightData, userInfo); + resultMap.put(ICMapKey.JsonValue, ICJson.beanToJson(resultWeight)); + result.success(resultMap); + } + + break; + default: + break; + } + + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + } + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICDataConvert.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICDataConvert.java new file mode 100644 index 0000000..bb1d4fb --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICDataConvert.java @@ -0,0 +1,224 @@ +package cn.icomon.icdevicemanager.flutter; + + + +import java.lang.reflect.Field; +import java.util.Map; + +import cn.icomon.icdevicemanager.model.data.ICSkipData; +import cn.icomon.icdevicemanager.model.other.ICConstant; + +public class ICDataConvert { + + + public static ISkipData getSkipData(ICSkipData from) { + ISkipData iSkipData = new ISkipData(); + iSkipData.isStabilized = from.isStabilized; + iSkipData.nodeId = from.nodeId; + iSkipData.battery = from.battery; + iSkipData.nodeInfo = from.nodeInfo; + iSkipData.time = from.time; + iSkipData.mode = from.mode.name(); + iSkipData.setting = from.setting; + iSkipData.elapsed_time = from.elapsed_time; + iSkipData.actual_time = from.actual_time; + iSkipData.skip_count = from.skip_count; + iSkipData.avg_freq = from.avg_freq; + iSkipData.fastest_freq = from.fastest_freq; + iSkipData.freq_count = from.freq_count; + iSkipData.most_jump = from.most_jump; + iSkipData.calories_burned = from.calories_burned; + iSkipData.fat_burn_efficiency = from.fat_burn_efficiency; + iSkipData.freqs = ICJson.beanToJson(from.freqs); + return iSkipData; + } + + + + + public static ICConstant.ICWeightUnit getSDKScaleUnit(Object enumName) { + + if (enumName == null) return ICConstant.ICWeightUnit.ICWeightUnitKg; + if (ICConstant.ICWeightUnit.ICWeightUnitJin.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICWeightUnit.ICWeightUnitJin; + } else if (ICConstant.ICWeightUnit.ICWeightUnitLb.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICWeightUnit.ICWeightUnitLb; + } else if (ICConstant.ICWeightUnit.ICWeightUnitSt.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICWeightUnit.ICWeightUnitSt; + } else { + return ICConstant.ICWeightUnit.ICWeightUnitKg; + } + + + } + + + public static ICConstant.ICOTAMode getSDKOTAMode(Object enumName) { + if (enumName == null) return ICConstant.ICOTAMode.ICOTAModeAuto; + if (ICConstant.ICOTAMode.ICOTAMode1.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICOTAMode.ICOTAMode1; + } else if (ICConstant.ICOTAMode.ICOTAMode2.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICOTAMode.ICOTAMode2; + } else if (ICConstant.ICOTAMode.ICOTAMode3.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICOTAMode.ICOTAMode3; + } else { + return ICConstant.ICOTAMode.ICOTAModeAuto; + } + + + } + + + public static ICConstant.ICKitchenScaleUnit getSDKKitchenUnitUnit(Object enumName) { + if (enumName == null) return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitG; + if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMl.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMl; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitLb.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitLb; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitOz.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitOz; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMg.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMg; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater; + } else if (ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk; + } else { + return ICConstant.ICKitchenScaleUnit.ICKitchenScaleUnitG; + } + + + } + + + public static ICConstant.ICRulerUnit getRulerUnit(Object enumName) { + + if (enumName == null) return ICConstant.ICRulerUnit.ICRulerUnitCM; + if (ICConstant.ICRulerUnit.ICRulerUnitFtInch.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerUnit.ICRulerUnitFtInch; + } else if (ICConstant.ICRulerUnit.ICRulerUnitInch.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerUnit.ICRulerUnitInch; + } else { + return ICConstant.ICRulerUnit.ICRulerUnitCM; + } + + + } + + public static ICConstant.ICRulerMeasureMode getRulerMode(Object enumName) { + if (enumName == null) return ICConstant.ICRulerMeasureMode.ICRulerMeasureModeLength; + if (ICConstant.ICRulerMeasureMode.ICRulerMeasureModeGirth.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerMeasureMode.ICRulerMeasureModeGirth; + } else { + return ICConstant.ICRulerMeasureMode.ICRulerMeasureModeLength; + } + + } + + public static ICConstant.ICRulerBodyPartsType getSDKRulerPart(Object enumName) { + if (enumName == null) return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeShoulder; + if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeBicep.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeBicep; + } else if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeChest.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeChest; + } else if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeWaist.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeWaist; + } else if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeHip.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeHip; + } else if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeThigh.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeThigh; + } else if (ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeCalf.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeCalf; + } else { + return ICConstant.ICRulerBodyPartsType.ICRulerPartsTypeShoulder; + } + + } + + + public static ICConstant.ICKitchenScaleNutritionFactType getSDKNutritionFactType(Object enumName) { + if (enumName == null) + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCalorie; + if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCalorie.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCalorie; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalFat.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalFat; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalProtein.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalProtein; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCarbohydrates.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCarbohydrates; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalFiber.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalFiber; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCholesterd.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalCholesterd; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalSodium.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalSodium; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalSugar.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeTotalSugar; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeFat.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeFat; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeProtein.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeProtein; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCarbohydrates.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCarbohydrates; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeFiber.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeFiber; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCholesterd.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCholesterd; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeSodium.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeSodium; + } else if (ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeSugar.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeSugar; + } else { + return ICConstant.ICKitchenScaleNutritionFactType.ICKitchenScaleNutritionFactTypeCalorie; + } + + } + + + public static ICConstant.ICSkipMode getSkipMode(Object enumName) { + if (enumName == null) return ICConstant.ICSkipMode.ICSkipModeFreedom; + if (ICConstant.ICSkipMode.ICSkipModeFreedom.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICSkipMode.ICSkipModeFreedom; + } else if (ICConstant.ICSkipMode.ICSkipModeCount.name().equalsIgnoreCase(enumName.toString())) { + return ICConstant.ICSkipMode.ICSkipModeCount; + } else { + return ICConstant.ICSkipMode.ICSkipModeTiming; + } + + } + + + public static void setMap(Map map, Object obj) { + if (obj != null) { + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + if (!field.isAccessible()) { + field.setAccessible(true); + } + Object value = getDeclaredFieldValue(field, obj); + map.put(field.getName(), value); + + } + } + + } + + /** + * 获取对象属性的值 + * + * @param field + * @return + */ + public static Object getDeclaredFieldValue(Field field, Object obj) { + try { + return field.get(obj); + } catch (IllegalAccessException e) { + e.printStackTrace(); + return null; + } + + } +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICJson.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICJson.java new file mode 100644 index 0000000..d3755de --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICJson.java @@ -0,0 +1,97 @@ +package cn.icomon.icdevicemanager.flutter; + +import android.text.TextUtils; +import android.util.Log; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ICJson { + + public static T toJavaObject(String strJson, Class clazz) { + if (TextUtils.isEmpty(strJson)) { + return null; + } + T object = null; + try { + object = (T) JSON.parseObject(strJson, clazz); + } catch (Exception e) { + e.printStackTrace(); + } + return object; + } + + public static List toJavaList(String strJson, Class clazz) { + if (TextUtils.isEmpty(strJson)) { + return new ArrayList<>(); + } + List list = new ArrayList<>(); + try { + list = JSON.parseArray(strJson, clazz); + } catch (Exception e) { + Log.e("toJavaList", "toJavaList "+e.toString()); + } + return list; + } + + + public static String beanToJson(T info) { + return JSON.toJSONString(info); + } + + + public static T typeToObject(String strJson, Type type) { + if (TextUtils.isEmpty(strJson)) { + return null; + } + T object = null; + try { + object = JSON.parseObject(strJson, type); + } catch (Exception e) { + + } + return object; + } + + public static HashMap toJavaMap(String strJson) { + if (TextUtils.isEmpty(strJson)) { + return new HashMap<>(); + } + + HashMap hashMap = null; + try { + hashMap = JSON.parseObject(strJson, new TypeReference>() { + }); + } catch (Exception e) { + + } + + if (hashMap == null) + hashMap = new HashMap<>(); + return hashMap; + } + + public static HashMap toJavaMapInteger(String strJson) { + if (TextUtils.isEmpty(strJson)) { + return new HashMap<>(); + } + + HashMap hashMap = null; + try { + hashMap = JSON.parseObject(strJson, new TypeReference>() { + }); + } catch (Exception e) { + + } + + if (hashMap == null) + hashMap = new HashMap<>(); + return hashMap; + } + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICMapKey.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICMapKey.java new file mode 100644 index 0000000..425d29b --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICMapKey.java @@ -0,0 +1,18 @@ +package cn.icomon.icdevicemanager.flutter; + +public class ICMapKey { + static String Mac = "Mac"; + static String Password = "Password"; + static String SSID = "SSID"; + static String DstId = "DstId"; + static String StNo = "StNo"; + + static String JsonValue = "JsonValue"; + static String JsonValue2 = "JsonValue2"; + static String EnumName ="EnumName"; + static String BoolValue ="BoolValue"; + static String ObjectValue ="ObjectValue"; + static String IntValue ="IntValue"; + static String StringValue ="StringValue"; + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICSDKManager.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICSDKManager.java new file mode 100644 index 0000000..dfef396 --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICSDKManager.java @@ -0,0 +1,692 @@ +package cn.icomon.icdevicemanager.flutter; + + +import android.os.Handler; +import android.text.TextUtils; +import android.util.Log; + +import java.util.HashMap; +import java.util.List; + +import cn.icomon.icdevicemanager.ICDeviceManager; +import cn.icomon.icdevicemanager.ICDeviceManagerDelegate; +import cn.icomon.icdevicemanager.ICDeviceManagerSettingManager; +import cn.icomon.icdevicemanager.callback.ICScanDeviceDelegate; +import cn.icomon.icdevicemanager.common.ICLoggerHandler; +import cn.icomon.icdevicemanager.model.data.ICCoordData; +import cn.icomon.icdevicemanager.model.data.ICKitchenScaleData; +import cn.icomon.icdevicemanager.model.data.ICRulerData; +import cn.icomon.icdevicemanager.model.data.ICSkipData; +import cn.icomon.icdevicemanager.model.data.ICSkipLightSettingData; +import cn.icomon.icdevicemanager.model.data.ICSkipSoundSettingData; +import cn.icomon.icdevicemanager.model.data.ICWeightCenterData; +import cn.icomon.icdevicemanager.model.data.ICWeightData; +import cn.icomon.icdevicemanager.model.data.ICWeightHistoryData; +import cn.icomon.icdevicemanager.model.device.ICDevice; +import cn.icomon.icdevicemanager.model.device.ICDeviceInfo; +import cn.icomon.icdevicemanager.model.device.ICScanDeviceInfo; +import cn.icomon.icdevicemanager.model.device.ICUserInfo; +import cn.icomon.icdevicemanager.model.other.ICConstant; +import cn.icomon.icdevicemanager.model.other.ICDeviceManagerConfig; +import io.flutter.plugin.common.MethodChannel; + + +public class ICSDKManager implements ICDeviceManagerDelegate, + ICDeviceManagerSettingManager.ICSettingCallback, + ICConstant.ICAddDeviceCallBack, + ICConstant.ICRemoveDeviceCallBack, + ICScanDeviceDelegate { + + private final String TAG = "ICSDKManager"; + + private volatile static ICSDKManager sdkManager; + + + public static MethodChannel channel; + + + + private Handler handler = new Handler(); + /** + * 7-14 1.2.0_build_687_71e503b_20220714164005 + */ + private ICDeviceManager icDeviceManager; + + public static ICSDKManager getInstance() { + if (sdkManager == null) { + synchronized (ICSDKManager.class) { + if (sdkManager == null) { + sdkManager = new ICSDKManager(); + } + } + } + return sdkManager; + + } + + public MethodChannel getChannel() { + if (channel == null) { + // channel = ICFlutterMessageChannel.getInstance().getChannel(); + } + return channel; + } + + public void setChannel(MethodChannel channel) { + ICSDKManager.channel = channel; + } + + + public ICSDKManager() { + icDeviceManager = ICDeviceManager.shared(); + icDeviceManager.setDelegate(this); + } + + + public ICDeviceManager getDeviceMgr() { + if (icDeviceManager == null) { + icDeviceManager = ICDeviceManager.shared(); + icDeviceManager.setDelegate(this); + } + return icDeviceManager; + } + + + public void sendMsgToFlutter(String name, Object obj) { + handler.post(() -> { + MethodChannel channel = getChannel(); + if (channel != null) { + Log.e(TAG, "安卓端发送信息 " + name); + channel.invokeMethod(name, obj); + } + }); + + } + + public void addDevice(String macAddr, ICConstant.ICAddDeviceCallBack callBack) { + if (TextUtils.isEmpty(macAddr)) return; + getDeviceMgr().addDevice(getICDeviceByMac(macAddr), callBack); + } + + public void addDevices(List devices, ICConstant.ICAddDeviceCallBack callBack) { + getDeviceMgr().addDevices(devices, callBack); + } + + + public void removeDevice(String macAddr,ICConstant.ICRemoveDeviceCallBack callBack) { + if (TextUtils.isEmpty(macAddr)) return; + getDeviceMgr().removeDevice(getICDeviceByMac(macAddr), callBack); + + } + + + public void removeDevices(List devices,ICConstant.ICRemoveDeviceCallBack callBack) { + getDeviceMgr().removeDevices(devices, callBack); + + } + + public void upgradeDevice(String macAddr, String path, ICConstant.ICOTAMode icotaMode) { + if (TextUtils.isEmpty(macAddr)) return; + getDeviceMgr().upgradeDevice(getICDeviceByMac(macAddr), path, icotaMode); + + } + + public void upgradeDevices(List devices, String path, ICConstant.ICOTAMode icotaMode) { + getDeviceMgr().upgradeDevices(devices, path, icotaMode); + + } + + public void stopUpgradeDevice(String macAddr) { + if (TextUtils.isEmpty(macAddr)) return; + getDeviceMgr().stopUpgradeDevice(getICDeviceByMac(macAddr)); + + } + + public void stopUpgradeDevices(List devices) { + getDeviceMgr().stopUpgradeDevices(devices); + + } + + public void scanDevice() { + getDeviceMgr().scanDevice(this); + + + } + + public void stopScan() { + getDeviceMgr().stopScan(); + + + } + + public void initSdk(ICDeviceManagerConfig config) { + getDeviceMgr().initMgrWithConfig(config); + } + + + public void configWifi(String macAddr, Object ssid, Object password,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr) || ssid == null || password == null) return; + ICLoggerHandler.logInfo(TAG, "configWifi " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().configWifi(getICDeviceByMac(macAddr), ssid.toString(), password.toString(),callback); + + } + + public void setScaleUnit(String macAddr, ICConstant.ICWeightUnit unit,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setScaleUnit " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setScaleUnit(getICDeviceByMac(macAddr), unit, callback); + + + } + /*尺子设置-----------------------start*/ + + + /** + * 设置尺子单位 + * + * @param macAddr + * @param unit + */ + public void setRulerUnit(String macAddr, ICConstant.ICRulerUnit unit,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setRulerUnit " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setRulerUnit(getICDeviceByMac(macAddr), unit, callback); + + } + + + public void setRulerBodyPartsType(String macAddr, ICConstant.ICRulerBodyPartsType unit,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setRulerBodyPartsType " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setRulerBodyPartsType(getICDeviceByMac(macAddr), unit, callback); + + } + + /** + * 设置测模式 + * + * @param macAddr + * @param mode + */ + public void setRulerMeasureMode(String macAddr, ICConstant.ICRulerMeasureMode mode,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setRulerMeasureMode " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setRulerMeasureMode(getICDeviceByMac(macAddr), mode, callback); + + } + + + + /*尺子设置-----------------------end*/ + + + + + + + + + + + + + + + + /*厨房秤设置-----------------------start*/ + + + /** + * 设置厨房秤单位 + * + * @param macAddr + * @param unit + */ + public void setKitchenScaleUnit(String macAddr, ICConstant.ICKitchenScaleUnit unit,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setKitchenScaleUnit " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setKitchenScaleUnit(getICDeviceByMac(macAddr), unit, callback); + + + } + + /** + * 厨房秤去皮 + */ + public void deleteTareWeight(String macAddr,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "deleteTareWeight " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().deleteTareWeight(getICDeviceByMac(macAddr), callback); + + + } + + + /** + * 关机 + */ + public void powerOffKitchenScale(String macAddr,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "powerOffKitchenScale " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().powerOffKitchenScale(getICDeviceByMac(macAddr), callback); + + + } + + + public void setNutritionFacts(String macAddr, ICConstant.ICKitchenScaleNutritionFactType type, int value,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setNutritionFacts " ); + getDeviceMgr().getSettingManager().setNutritionFacts(getICDeviceByMac(macAddr), type, value, callback); + + + } + + + + /*厨房秤设置-----------------------end*/ + + + /*彩屏称设置-----------------------start*/ + + public void setServerUrl(String macAddr, Object service,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr) || service == null) return; + ICLoggerHandler.logInfo(TAG, "setServerUrl " ); + getDeviceMgr().getSettingManager().setServerUrl(getICDeviceByMac(macAddr), service.toString(), callback); + + } + + + public void setOtherParams(String strMac ,int type, Object object,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac)) return; + ICLoggerHandler.logInfo(TAG, "setOtherParams " ); + getDeviceMgr().getSettingManager().setOtherParams(getICDeviceByMac(strMac),type,object,callback); + + } + + + public void queryStAllNode(String strMac,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac)) return; + ICLoggerHandler.logInfo(TAG, "queryStAllNode " ); + getDeviceMgr().getSettingManager().queryStAllNode(getICDeviceByMac(strMac),callback); + + } + + + public void changeStName(String strMac, Object name,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac) || name == null) return; + ICLoggerHandler.logInfo(TAG, "changeStName " ); + getDeviceMgr().getSettingManager().changeStName(getICDeviceByMac(strMac), name.toString(), callback); + + } + + public void changeStNo(String strMac, Object dstId, Object st_no,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac) || dstId == null || st_no == null) return; + int id = 0, no = 0; + if (dstId instanceof Integer) id = (int) dstId; + if (st_no instanceof Integer) no = (int) st_no; + ICLoggerHandler.logInfo(TAG, "changeStNo " ); + getDeviceMgr().getSettingManager().changeStNo(getICDeviceByMac(strMac), id, no, callback); + + } + public ICWeightData CalcBodyFat(ICWeightData weightData,ICUserInfo userInfo) { + ICLoggerHandler.logInfo(TAG, "CalcBodyFat " ); + return getDeviceMgr().getBodyFatAlgorithmsManager().reCalcBodyFatWithWeightData(weightData,userInfo); + + } + + + public String getLogPath() { + ICLoggerHandler.logInfo(TAG, "getLogPath " ); + return getDeviceMgr().getLogPath(); + + } + + /*彩屏称设置-----------------------end*/ + + public void syncUserInfo(ICUserInfo userInfo) { + if (userInfo == null) return; + getDeviceMgr().updateUserInfo(userInfo); + ICLoggerHandler.logInfo(TAG, "syncUserInfo " ); + } + + public void syncUserList(List list) { + getDeviceMgr().setUserList(list); + ICLoggerHandler.logInfo(TAG, "syncUserList " ); + } + + + public void setWeight(String macAddr, int weight,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(macAddr)) return; + ICLoggerHandler.logInfo(TAG, "setWeight " + " mac: "+macAddr); + getDeviceMgr().getSettingManager().setWeight(getICDeviceByMac(macAddr), weight,callback); + + + } + /*跳绳设置-----------------------start*/ + + public void startSkip(String strMac, ICConstant.ICSkipMode skipMode, int nSetting,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac)) return; + ICLoggerHandler.logInfo(TAG, "startSkip " + " mac: "+strMac); + getDeviceMgr().getSettingManager().startSkipMode(getICDeviceByMac(strMac), skipMode, nSetting,callback); + + } + + public void stopSkip(String strMac,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac)) return; + ICLoggerHandler.logInfo(TAG, "stopSkip " + " mac: "+strMac); + getDeviceMgr().getSettingManager().stopSkip(getICDeviceByMac(strMac),callback); + + } + + /** + * 设置灯效跳绳设备灯效 + */ + public void setSkipLightSetting(String strMac, List data,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac) || data == null) return; + ICLoggerHandler.logInfo(TAG, "setSkipLightSetting " + " mac: "+strMac); + getDeviceMgr().getSettingManager().setSkipLightSetting(getICDeviceByMac(strMac), data, ICConstant.ICSkipLightMode.ICSkipLightModeRPM,callback); + + } + + /** + * 设置语音跳绳语音参数 + */ + public void setSkipVoiceSetting(String strMac, ICSkipSoundSettingData data,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac) || data == null) return; + ICLoggerHandler.logInfo(TAG, "setSkipVoiceSetting " + " mac: "+strMac); + getDeviceMgr().getSettingManager().setSkipSoundSetting(getICDeviceByMac(strMac), data, callback); + + } + + + public void lockStSkip(String strMac,ICDeviceManagerSettingManager.ICSettingCallback callback) { + if (TextUtils.isEmpty(strMac)) return; + ICLoggerHandler.logInfo(TAG, "lockStSkip " + " mac: "+strMac); + getDeviceMgr().getSettingManager().lockStSkip(getICDeviceByMac(strMac),callback); + + } + + + /*跳绳设置-----------------------end*/ + + + public ICDevice getICDeviceByMac(String strMac) { + ICDevice icDevice = new ICDevice(); + icDevice.setMacAddr(strMac); + return icDevice; + } + + + @Override + public void onInitFinish(boolean b) { + ICLoggerHandler.logInfo(TAG, "onInitFinish " + b); + HashMap map = new HashMap<>(); + map.put(ICMapKey.BoolValue, b); + sendMsgToFlutter(ICWUploadEvent.TypeInitSDK, map); + } + + @Override + public void onBleState(ICConstant.ICBleState icBleState) { + ICLoggerHandler.logInfo(TAG, "onBleState " + icBleState.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.EnumName, icBleState.name()); + sendMsgToFlutter(ICWUploadEvent.TypeBluetoothChange, map); + } + + @Override + public void onDeviceConnectionChanged(ICDevice icDevice, ICConstant.ICDeviceConnectState state) { + ICLoggerHandler.logInfo(TAG, "onDeviceConnectionChanged " + state.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, state.name()); + sendMsgToFlutter(ICWUploadEvent.TypeConnectChange, map); + } + + + @Override + public void onNodeConnectionChanged(ICDevice device, int nodeId, ICConstant.ICDeviceConnectState state) { + Log.e(TAG, "onReceiveWeightData " + device.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, device.getMacAddr()); + map.put(ICMapKey.EnumName,state.name()); + map.put(ICMapKey.IntValue,nodeId); + sendMsgToFlutter(ICWUploadEvent.onNodeConnectionChanged, map); + } + + @Override + public void onReceiveWeightData(ICDevice icDevice, ICWeightData data) { + Log.e(TAG, "onReceiveWeightData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeScaleData, map); + + + } + + @Override + public void onReceiveKitchenScaleData(ICDevice icDevice, ICKitchenScaleData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveKitchenScaleData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeKitchenData, map); + } + + @Override + public void onReceiveKitchenScaleUnitChanged(ICDevice icDevice, ICConstant.ICKitchenScaleUnit unit) { + ICLoggerHandler.logInfo(TAG, "onReceiveKitchenScaleUnitChanged " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, unit.name()); + sendMsgToFlutter(ICWUploadEvent.KitchenScaleUnitChanged, map); + } + + @Override + public void onReceiveCoordData(ICDevice icDevice, ICCoordData icCoordData) { + ICLoggerHandler.logInfo(TAG, "onReceiveCoordData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(icCoordData)); + sendMsgToFlutter(ICWUploadEvent.TypeCoordData, map); + } + + @Override + public void onReceiveRulerData(ICDevice icDevice, ICRulerData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveRulerData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeRulerData, map); + } + + @Override + public void onReceiveRulerHistoryData(ICDevice icDevice, ICRulerData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveRulerHistoryData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.RulerHistoryData, map); + } + + @Override + public void onReceiveWeightCenterData(ICDevice icDevice, ICWeightCenterData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveWeightCenterData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeScaleCenterData, map); + } + + @Override + public void onReceiveWeightUnitChanged(ICDevice icDevice, ICConstant.ICWeightUnit unit) { + ICLoggerHandler.logInfo(TAG, "onReceiveWeightUnitChanged " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, unit.name()); + sendMsgToFlutter(ICWUploadEvent.TypeScaleUnitChange, map); + } + + @Override + public void onReceiveRulerUnitChanged(ICDevice icDevice, ICConstant.ICRulerUnit unit) { + ICLoggerHandler.logInfo(TAG, "onReceiveRulerUnitChanged " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, unit.name()); + sendMsgToFlutter(ICWUploadEvent.TypeRulerUnitChange, map); + } + + @Override + public void onReceiveRulerMeasureModeChanged(ICDevice icDevice, ICConstant.ICRulerMeasureMode mode) { + ICLoggerHandler.logInfo(TAG, "onReceiveRulerMeasureModeChanged " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, mode.name()); + sendMsgToFlutter(ICWUploadEvent.TypeRulerModeChange, map); + } + + @Override + public void onReceiveMeasureStepData(ICDevice icDevice, ICConstant.ICMeasureStep step, Object o) { + ICLoggerHandler.logInfo(TAG, "onReceiveMeasureStepData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + // ICWeightData data = (ICWeightData) o; + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, step.name()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(o)); + sendMsgToFlutter(ICWUploadEvent.TypeScaleStepData, map); + } + + @Override + public void onReceiveWeightHistoryData(ICDevice icDevice, ICWeightHistoryData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveWeightHistoryData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeScaleHistoryData, map); + } + + @Override + public void onReceiveSkipData(ICDevice icDevice, ICSkipData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveSkipData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(ICDataConvert.getSkipData(data))); + sendMsgToFlutter(ICWUploadEvent.TypeSkipData, map); + } + + @Override + public void onReceiveHistorySkipData(ICDevice icDevice, ICSkipData data) { + ICLoggerHandler.logInfo(TAG, "onReceiveHistorySkipData " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(ICDataConvert.getSkipData(data))); + sendMsgToFlutter(ICWUploadEvent.TypeSkipHistoryData, map); + } + + @Override + public void onReceiveBattery(ICDevice icDevice, int percent, Object o) { + ICLoggerHandler.logInfo(TAG, "onReceiveBattery " + " mac: "+icDevice.macAddr); + ICLoggerHandler.logInfo(TAG, "onReceiveBattery " + icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.IntValue, percent); + sendMsgToFlutter(ICWUploadEvent.TypeBattery, map); + + + } + + + @Override + public void onReceiveUpgradePercent(ICDevice icDevice, ICConstant.ICUpgradeStatus icUpgradeStatus, int percent) { + ICLoggerHandler.logInfo(TAG, "onReceiveUpgradePercent " + " mac: "+icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.EnumName, icUpgradeStatus.name()); + map.put(ICMapKey.IntValue, percent); + sendMsgToFlutter(ICWUploadEvent.TypeUpgrade, map); + } + + @Override + public void onReceiveDeviceInfo(ICDevice icDevice, ICDeviceInfo data) { + ICLoggerHandler.logInfo(TAG, "onReceiveDeviceInfo " + " mac: "+icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.getMacAddr()); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(data)); + sendMsgToFlutter(ICWUploadEvent.TypeDeviceInfo, map); + } + + + @Override + public void onReceiveDebugData(ICDevice icDevice, int i, Object o) { + ICLoggerHandler.logInfo(TAG, "onReceiveDebugData " + " mac: "+icDevice.macAddr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.macAddr); + map.put(ICMapKey.IntValue, i); + map.put(ICMapKey.ObjectValue, o); + sendMsgToFlutter(ICWUploadEvent.TypeDebugData, map); + } + + @Override + public void onReceiveConfigWifiResult(ICDevice icDevice, ICConstant.ICConfigWifiState result) { + ICLoggerHandler.logInfo(TAG, "onReceiveConfigWifiResult " + result); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.macAddr); + map.put(ICMapKey.EnumName, result.name()); + sendMsgToFlutter(ICWUploadEvent.TypeConfigWifi, map); + } + + @Override + public void onReceiveHR(ICDevice icDevice, int hr) { + ICLoggerHandler.logInfo(TAG, "onReceiveHR " + " mac: "+icDevice.macAddr+" Hr:"+hr); + HashMap map = new HashMap<>(); + map.put(ICMapKey.IntValue, hr); + map.put(ICMapKey.Mac, icDevice.macAddr); + sendMsgToFlutter(ICWUploadEvent.TypeHrData, map); + } + + @Override + public void onReceiveUserInfo(ICDevice device, ICUserInfo userInfo) { + + } + + @Override + public void onReceiveRSSI(ICDevice device, int rssi) { + + } + + @Override + public void onScanResult(ICScanDeviceInfo icScanDeviceInfo) { + ICLoggerHandler.logInfo(TAG, "onScanResult " + icScanDeviceInfo.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.JsonValue, ICJson.beanToJson(icScanDeviceInfo)); + sendMsgToFlutter(ICWUploadEvent.TypeDeviceScan, map); + } + + @Override + public void onCallBack(ICConstant.ICSettingCallBackCode code) { + ICLoggerHandler.logInfo(TAG, "onCallBack " + code.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.EnumName, code.name()); + sendMsgToFlutter(ICWUploadEvent.TypeSettingResult, map); + } + + @Override + public void onCallBack(ICDevice icDevice, ICConstant.ICAddDeviceCallBackCode code) { + ICLoggerHandler.logInfo(TAG, "ICAddDeviceCallBackCode " + code.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.macAddr); + map.put(ICMapKey.EnumName, code.name()); + sendMsgToFlutter(ICWUploadEvent.TypeAddDeviceResult, map); + } + + @Override + public void onCallBack(ICDevice icDevice, ICConstant.ICRemoveDeviceCallBackCode code) { + ICLoggerHandler.logInfo(TAG, "ICRemoveDeviceCallBackCode " + code.toString()); + HashMap map = new HashMap<>(); + map.put(ICMapKey.Mac, icDevice.macAddr); + map.put(ICMapKey.EnumName, code.name()); + sendMsgToFlutter(ICWUploadEvent.TypeRemoveDeviceResult, map); + } + + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWPublishEvent.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWPublishEvent.java new file mode 100644 index 0000000..3ffa482 --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWPublishEvent.java @@ -0,0 +1,62 @@ +package cn.icomon.icdevicemanager.flutter; + + + + +class ICWPublishEvent { + final static String InitSDK = "InitSDK"; + final static String AddDevice = "AddDevice"; + final static String AddDevices = "AddDevices"; + final static String DeleteDevice = "RemoveDevice"; + final static String DeleteDevices = "RemoveDevices"; + + final static String OTADevice = "OTADevice"; + final static String OTADevices = "OTADevices"; + final static String StopOTADevice = "StopOTADevice"; + final static String StopOTADevices = "StopOTADevices"; + + final static String StopScan = "StopScan"; + final static String StartScan = "StartScan"; + final static String SetUserInfo = "SetUserInfo"; + final static String SetUserList = "SetUserList"; + + + + final static String ScaleConfigWifi = "configWifi"; + final static String ScaleUnitSetting = "setScaleUnit"; + final static String RulerUnitSetting = "RulerUnitSetting"; + final static String RulerModeSetting = "RulerModeSetting"; + final static String RulerBodyPartSetting = "RulerBodyPartSetting"; + + + final static String KitchenUnitSetting = "KitchenUnitSetting"; + final static String KitchenPowerOff = "KitchenPowerOff"; + final static String KitchenCMD = "KitchenCMD"; + final static String KitchenTareWeight = "KitchenTareWeight"; + final static String KitchenFactory = "KitchenFactory"; + final static String KitchenSetNutritionFacts = "KitchenSetNutritionFacts"; + + final static String SkipStop = "SkipStop"; + final static String SkipStart = "SkipStart"; + final static String SetSkipMode = "SetSkipMode"; + final static String SkipLightSetting = "SkipLightSetting"; + final static String SkipSoundSetting = "SkipSoundSetting"; + final static String SkipLockSt = "SkipLockSt"; + final static String SkipSetWeight = "SkipSetWeight"; + final static String SkipSetUserInfo = "SkipSetUserInfo"; + + + + + final static String SetServerUrl = "setServerUrl"; + final static String SetOtherParams = "setOtherParams"; + final static String SetScaleUIItems = "setScaleUIItems"; + + final static String QueryStAllNode = "queryStAllNode"; + final static String ChangeStName = "changeStName"; + final static String ChangeStNo = "changeStNo"; + + final static String CalcBodyFat = "CalcBodyFat"; + final static String GetLogPath ="LogPath"; + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWUploadEvent.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWUploadEvent.java new file mode 100644 index 0000000..140f178 --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ICWUploadEvent.java @@ -0,0 +1,55 @@ +package cn.icomon.icdevicemanager.flutter; + + + + + +class ICWUploadEvent { + + static String TypeInitSDK = "InitSDK"; + + static String TypeUpgrade = "onReceiveUpgradePercent"; + static String TypeBattery = "onReceiveBattery"; + static String TypeConfigWifi = "onReceiveConfigWifiResult"; + static String TypeDeviceScan = "onScanResult"; + + static String TypeSettingResult = "onSettingCallBack"; + static String TypeAddDeviceResult = "onAddDeviceCallBack"; + static String TypeRemoveDeviceResult = "onRemoveDeviceCallBack"; + + static String TypeBluetoothChange = "onBleState"; + + static String TypeScaleData = "onReceiveWeightData"; + static String TypeCoordData = "onReceiveCoordData"; + static String TypeScaleStepData = "onReceiveMeasureStepData"; + static String TypeScaleCenterData = "onReceiveWeightCenterData"; + static String TypeScaleHistoryData = "onReceiveWeightHistoryData"; + static String TypeScaleUnitChange = "onReceiveWeightUnitChanged"; + + static String TypeRulerData = "onReceiveRulerData"; + static String RulerHistoryData = "onReceiveRulerHistoryData"; + static String TypeRulerUnitChange = "onReceiveRulerUnitChanged"; + static String TypeRulerModeChange = "onReceiveRulerMeasureModeChanged"; + + + static String TypeKitchenData = "onReceiveKitchenScaleData"; + + static String TypeSkipData = "onReceiveSkipData"; + static String TypeDeviceInfo = "onReceiveDeviceInfo"; + static String TypeSkipBattery = "onReceiveSkipBattery"; + static String TypeSkipHistoryData = "onReceiveHistorySkipData"; + static String TypeHrData = "onReceiveHrData"; + static String TypeDebugData = "TypeDebugData"; + + + + + + static String TypeConnectChange = "onDeviceConnectionChanged"; + static String onNodeConnectionChanged = "onNodeConnectionChanged"; + + + static String KitchenScaleUnitChanged = "onReceiveKitchenScaleUnitChanged"; + + +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/ISkipData.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ISkipData.java new file mode 100644 index 0000000..46f25a8 --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/ISkipData.java @@ -0,0 +1,23 @@ +package cn.icomon.icdevicemanager.flutter; + + + +public class ISkipData { + public boolean isStabilized; + public int nodeId; + public int battery; + public int nodeInfo; + public int time = 0; + public String mode; + public int setting; + public int elapsed_time; + public int actual_time; + public int skip_count; + public int avg_freq; + public int fastest_freq; + public int freq_count; + public int most_jump; + public double calories_burned; + public double fat_burn_efficiency; + public String freqs; +} diff --git a/android/src/main/java/cn/icomon/icdevicemanager/flutter/SkipLightSettingData.java b/android/src/main/java/cn/icomon/icdevicemanager/flutter/SkipLightSettingData.java new file mode 100644 index 0000000..346fd89 --- /dev/null +++ b/android/src/main/java/cn/icomon/icdevicemanager/flutter/SkipLightSettingData.java @@ -0,0 +1,18 @@ +package cn.icomon.icdevicemanager.flutter; + +public class SkipLightSettingData { + public int r; + public int g; + public int b; + public int rpm; + + @Override + public String toString() { + return "SkipLightSettingData{" + + "r=" + r + + ", g=" + g + + ", b=" + b + + ", rpm=" + rpm + + '}'; + } +} diff --git a/android/src/main/jniLibs/arm64-v8a/libICBleProtocol.so b/android/src/main/jniLibs/arm64-v8a/libICBleProtocol.so new file mode 100644 index 0000000..60ce91e Binary files /dev/null and b/android/src/main/jniLibs/arm64-v8a/libICBleProtocol.so differ diff --git a/android/src/main/jniLibs/arm64-v8a/libICBodyFatAlgorithms.so b/android/src/main/jniLibs/arm64-v8a/libICBodyFatAlgorithms.so new file mode 100644 index 0000000..060d2b7 Binary files /dev/null and b/android/src/main/jniLibs/arm64-v8a/libICBodyFatAlgorithms.so differ diff --git a/android/src/main/jniLibs/arm64-v8a/libICLogger.so b/android/src/main/jniLibs/arm64-v8a/libICLogger.so new file mode 100644 index 0000000..d2a2267 Binary files /dev/null and b/android/src/main/jniLibs/arm64-v8a/libICLogger.so differ diff --git a/android/src/main/jniLibs/armeabi-v7a/libICBleProtocol.so b/android/src/main/jniLibs/armeabi-v7a/libICBleProtocol.so new file mode 100644 index 0000000..23cce41 Binary files /dev/null and b/android/src/main/jniLibs/armeabi-v7a/libICBleProtocol.so differ diff --git a/android/src/main/jniLibs/armeabi-v7a/libICBodyFatAlgorithms.so b/android/src/main/jniLibs/armeabi-v7a/libICBodyFatAlgorithms.so new file mode 100644 index 0000000..b782835 Binary files /dev/null and b/android/src/main/jniLibs/armeabi-v7a/libICBodyFatAlgorithms.so differ diff --git a/android/src/main/jniLibs/armeabi-v7a/libICLogger.so b/android/src/main/jniLibs/armeabi-v7a/libICLogger.so new file mode 100644 index 0000000..9f3d3d6 Binary files /dev/null and b/android/src/main/jniLibs/armeabi-v7a/libICLogger.so differ diff --git a/android/src/main/jniLibs/armeabi/libICBleProtocol.so b/android/src/main/jniLibs/armeabi/libICBleProtocol.so new file mode 100644 index 0000000..0398710 Binary files /dev/null and b/android/src/main/jniLibs/armeabi/libICBleProtocol.so differ diff --git a/android/src/main/jniLibs/armeabi/libICBodyFatAlgorithms.so b/android/src/main/jniLibs/armeabi/libICBodyFatAlgorithms.so new file mode 100644 index 0000000..0818dcc Binary files /dev/null and b/android/src/main/jniLibs/armeabi/libICBodyFatAlgorithms.so differ diff --git a/android/src/main/jniLibs/armeabi/libICLogger.so b/android/src/main/jniLibs/armeabi/libICLogger.so new file mode 100644 index 0000000..9175954 Binary files /dev/null and b/android/src/main/jniLibs/armeabi/libICLogger.so differ diff --git a/android/src/main/jniLibs/x86/libICBleProtocol.so b/android/src/main/jniLibs/x86/libICBleProtocol.so new file mode 100644 index 0000000..5f395fe Binary files /dev/null and b/android/src/main/jniLibs/x86/libICBleProtocol.so differ diff --git a/android/src/main/jniLibs/x86/libICBodyFatAlgorithms.so b/android/src/main/jniLibs/x86/libICBodyFatAlgorithms.so new file mode 100644 index 0000000..a3b5c98 Binary files /dev/null and b/android/src/main/jniLibs/x86/libICBodyFatAlgorithms.so differ diff --git a/android/src/main/jniLibs/x86/libICLogger.so b/android/src/main/jniLibs/x86/libICLogger.so new file mode 100644 index 0000000..b2db8b8 Binary files /dev/null and b/android/src/main/jniLibs/x86/libICLogger.so differ diff --git a/android/src/main/jniLibs/x86_64/libICBleProtocol.so b/android/src/main/jniLibs/x86_64/libICBleProtocol.so new file mode 100644 index 0000000..6f14364 Binary files /dev/null and b/android/src/main/jniLibs/x86_64/libICBleProtocol.so differ diff --git a/android/src/main/jniLibs/x86_64/libICBodyFatAlgorithms.so b/android/src/main/jniLibs/x86_64/libICBodyFatAlgorithms.so new file mode 100644 index 0000000..dad43ff Binary files /dev/null and b/android/src/main/jniLibs/x86_64/libICBodyFatAlgorithms.so differ diff --git a/android/src/main/jniLibs/x86_64/libICLogger.so b/android/src/main/jniLibs/x86_64/libICLogger.so new file mode 100644 index 0000000..ad2dcf9 Binary files /dev/null and b/android/src/main/jniLibs/x86_64/libICLogger.so differ diff --git a/gsf/.gitignore b/gsf/.gitignore new file mode 100644 index 0000000..a066f7b --- /dev/null +++ b/gsf/.gitignore @@ -0,0 +1,95 @@ +<<<<<<< HEAD +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release +======= +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/.metadata b/gsf/.metadata new file mode 100644 index 0000000..3f8434c --- /dev/null +++ b/gsf/.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: 7048ed95a5ad3e43d697e0c397464193991fc230 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + - platform: android + create_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + base_revision: 7048ed95a5ad3e43d697e0c397464193991fc230 + + # 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/gsf/README.md b/gsf/README.md new file mode 100644 index 0000000..c7b6dc9 --- /dev/null +++ b/gsf/README.md @@ -0,0 +1,14 @@ +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. \ No newline at end of file diff --git a/gsf/analysis_options.yaml b/gsf/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/gsf/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/gsf/android/.gitignore b/gsf/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/gsf/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +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/gsf/android/.settings/org.eclipse.buildship.core.prefs b/gsf/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..b54ecd2 --- /dev/null +++ b/gsf/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments=--init-script /var/folders/q9/5h6ys3_x50l83ldgtll0fvd80000gn/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle --init-script /var/folders/q9/5h6ys3_x50l83ldgtll0fvd80000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/gsf/android/app/build.gradle b/gsf/android/app/build.gradle new file mode 100644 index 0000000..4680343 --- /dev/null +++ b/gsf/android/app/build.gradle @@ -0,0 +1,116 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw 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' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.crashlytics' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +// def keystorePropertiesFile = rootProject.file("key.properties") +// def keystoreProperties = new Properties() +// keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) + +def keystoreProperties = new Properties() + def keystorePropertiesFile = rootProject.file('key.properties') + if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) + } + + +android { + compileSdkVersion 34 + 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' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.getsetfit.gsf" + // 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 26 + targetSdkVersion 33 + versionCode 14//flutterVersionCode.toInteger()//3 + versionName "1.0"//flutterVersionName //"1.0" + manifestPlaceholders['foregroundServiceType'] = 'health' + + } + + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + // signingConfig signingConfigs.debug + signingConfig signingConfigs.release + shrinkResources false // this line + minifyEnabled false // this line + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + // buildTypes { + // release { + // // TODO: Add your own signing config for the release build. + // // Signing with the debug keys for now, so `flutter run --release` works. + // signingConfig signingConfigs.debug + // // signingConfig signingConfigs.release + // shrinkResources false // this line + // minifyEnabled false // this line + // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + // } + // } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation platform('com.google.firebase:firebase-bom:31.3.0') + // Add the dependencies for the Crashlytics and Analytics libraries + // When using the BoM, you don't specify versions in Firebase library dependencies + implementation("com.google.firebase:firebase-crashlytics") + implementation("com.google.firebase:firebase-analytics") +} diff --git a/gsf/android/app/google-services.json b/gsf/android/app/google-services.json new file mode 100644 index 0000000..919ef07 --- /dev/null +++ b/gsf/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "751933368781", + "project_id": "gsf-live", + "storage_bucket": "gsf-live.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:751933368781:android:020c5f5f7ec8ea880dfc84", + "android_client_info": { + "package_name": "com.getsetfit.gsf" + } + }, + "oauth_client": [ + { + "client_id": "751933368781-v8k9ajguhps61ged7eis0ol1olflhfhv.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDd4MVv-SL6rw3t7aYtCW74_lA_GBMwJ_g" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "751933368781-v8k9ajguhps61ged7eis0ol1olflhfhv.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/gsf/android/app/google-servicesew.json b/gsf/android/app/google-servicesew.json new file mode 100644 index 0000000..e3e24ce --- /dev/null +++ b/gsf/android/app/google-servicesew.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "651220635880", + "project_id": "gsf-onesignal-6f89f", + "storage_bucket": "gsf-onesignal-6f89f.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:651220635880:android:24aee68602d1ef9f35395d", + "android_client_info": { + "package_name": "com.getsetfit.gsf" + } + }, + "oauth_client": [ + { + "client_id": "651220635880-cp0s67o4mqui86pi44ulmld30mds77eb.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCFMQh30hzQwPOBITe1zv-Aeya_Z5j94hg" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "651220635880-cp0s67o4mqui86pi44ulmld30mds77eb.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/gsf/android/app/proguard-rules.pro b/gsf/android/app/proguard-rules.pro new file mode 100644 index 0000000..6d8b64b --- /dev/null +++ b/gsf/android/app/proguard-rules.pro @@ -0,0 +1,10 @@ +-keep class com.android.library.dataModels.** { *; } +-keep class com.android.library.publicInterface.** { *; } +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.** { *; } +-keep class io.flutter.plugins.** { *; } +-keep class io.flutter.embedding.** { *; } +-dontwarn io.flutter.embedding.** \ No newline at end of file diff --git a/gsf/android/app/src/debug/AndroidManifest.xml b/gsf/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..d66671b --- /dev/null +++ b/gsf/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/gsf/android/app/src/main/AndroidManifest.xml b/gsf/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..bd55fd1 --- /dev/null +++ b/gsf/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gsf/android/app/src/main/kotlin/com/getsetfit/gsf/MainActivity.kt b/gsf/android/app/src/main/kotlin/com/getsetfit/gsf/MainActivity.kt new file mode 100644 index 0000000..916876f --- /dev/null +++ b/gsf/android/app/src/main/kotlin/com/getsetfit/gsf/MainActivity.kt @@ -0,0 +1,7 @@ +package com.getsetfit.gsf + +import io.flutter.embedding.android.FlutterFragmentActivity + +class MainActivity: FlutterFragmentActivity() { + // ... +} diff --git a/gsf/android/app/src/main/res/drawable-v21/background.png b/gsf/android/app/src/main/res/drawable-v21/background.png new file mode 100644 index 0000000..e33ac14 Binary files /dev/null and b/gsf/android/app/src/main/res/drawable-v21/background.png differ diff --git a/gsf/android/app/src/main/res/drawable-v21/launch_background.xml b/gsf/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f88598c --- /dev/null +++ b/gsf/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/android/app/src/main/res/drawable/background.png b/gsf/android/app/src/main/res/drawable/background.png new file mode 100644 index 0000000..e33ac14 Binary files /dev/null and b/gsf/android/app/src/main/res/drawable/background.png differ diff --git a/gsf/android/app/src/main/res/drawable/launch_background.xml b/gsf/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..f88598c --- /dev/null +++ b/gsf/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/gsf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..535005a Binary files /dev/null and b/gsf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/gsf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/gsf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..6502168 Binary files /dev/null and b/gsf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/gsf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/gsf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..80b91d5 Binary files /dev/null and b/gsf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/gsf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/gsf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..82b0fa6 Binary files /dev/null and b/gsf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/gsf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/gsf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..cfc13a8 Binary files /dev/null and b/gsf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/gsf/android/app/src/main/res/values-night/styles.xml b/gsf/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/gsf/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/gsf/android/app/src/main/res/values/styles.xml b/gsf/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..0d1fa8f --- /dev/null +++ b/gsf/android/app/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/gsf/android/app/src/profile/AndroidManifest.xml b/gsf/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..d66671b --- /dev/null +++ b/gsf/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/gsf/android/build.gradle b/gsf/android/build.gradle new file mode 100644 index 0000000..e7f44f5 --- /dev/null +++ b/gsf/android/build.gradle @@ -0,0 +1,34 @@ +buildscript { + ext.kotlin_version = '1.8.0' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.2.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.15' + // Add the dependency for the Crashlytics Gradle plugin + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gsf/android/gradle.properties b/gsf/android/gradle.properties new file mode 100644 index 0000000..94adc3a --- /dev/null +++ b/gsf/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/gsf/android/gradle/wrapper/gradle-wrapper.properties b/gsf/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3c472b9 --- /dev/null +++ b/gsf/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/gsf/android/settings.gradle b/gsf/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/gsf/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/gsf/assets/audio/audio_bg.jpg b/gsf/assets/audio/audio_bg.jpg new file mode 100644 index 0000000..f03f44b Binary files /dev/null and b/gsf/assets/audio/audio_bg.jpg differ diff --git a/gsf/assets/audio/besharam.mp3 b/gsf/assets/audio/besharam.mp3 new file mode 100644 index 0000000..45895e9 Binary files /dev/null and b/gsf/assets/audio/besharam.mp3 differ diff --git a/gsf/assets/audio/nature.mp3 b/gsf/assets/audio/nature.mp3 new file mode 100644 index 0000000..80cbe53 Binary files /dev/null and b/gsf/assets/audio/nature.mp3 differ diff --git a/gsf/assets/audio/sample.pdf b/gsf/assets/audio/sample.pdf new file mode 100644 index 0000000..11ec45d --- /dev/null +++ b/gsf/assets/audio/sample.pdf @@ -0,0 +1,198 @@ +%PDF-1.3 +%���� + +1 0 obj +<< +/Type /Catalog +/Outlines 2 0 R +/Pages 3 0 R +>> +endobj + +2 0 obj +<< +/Type /Outlines +/Count 0 +>> +endobj + +3 0 obj +<< +/Type /Pages +/Count 2 +/Kids [ 4 0 R 6 0 R ] +>> +endobj + +4 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 5 0 R +>> +endobj + +5 0 obj +<< /Length 1074 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( A Simple PDF File ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( This is a small demonstration .pdf file - ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 628.8480 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 616.8960 Td +( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj +ET +BT +/F1 0010 Tf +69.2500 604.9440 Td +( more text. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 592.9920 Td +( And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 569.0880 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 557.1360 Td +( text. And more text. And more text. Even more. Continued on page 2 ...) Tj +ET +endstream +endobj + +6 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 7 0 R +>> +endobj + +7 0 obj +<< /Length 676 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( Simple PDF File 2 ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( ...continued from page 1. Yet more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 676.6560 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( paint dry. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 640.8000 Td +( Boring. More, a little more text. The end, and just as well. ) Tj +ET +endstream +endobj + +8 0 obj +[/PDF /Text] +endobj + +9 0 obj +<< +/Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding +>> +endobj + +10 0 obj +<< +/Creator (Rave \(http://www.nevrona.com/rave\)) +/Producer (Nevrona Designs) +/CreationDate (D:20060301072826) +>> +endobj + +xref +0 11 +0000000000 65535 f +0000000019 00000 n +0000000093 00000 n +0000000147 00000 n +0000000222 00000 n +0000000390 00000 n +0000001522 00000 n +0000001690 00000 n +0000002423 00000 n +0000002456 00000 n +0000002574 00000 n + +trailer +<< +/Size 11 +/Root 1 0 R +/Info 10 0 R +>> + +startxref +2714 +%%EOF diff --git a/gsf/assets/fonts/FontsFree-Net-SFProText-Bold-1.ttf b/gsf/assets/fonts/FontsFree-Net-SFProText-Bold-1.ttf new file mode 100644 index 0000000..0cd5ce1 Binary files /dev/null and b/gsf/assets/fonts/FontsFree-Net-SFProText-Bold-1.ttf differ diff --git a/gsf/assets/fonts/FontsFree-Net-SFProText-Heavy-1.ttf b/gsf/assets/fonts/FontsFree-Net-SFProText-Heavy-1.ttf new file mode 100644 index 0000000..5028a83 Binary files /dev/null and b/gsf/assets/fonts/FontsFree-Net-SFProText-Heavy-1.ttf differ diff --git a/gsf/assets/fonts/FontsFree-Net-SFProText-Light-1.ttf b/gsf/assets/fonts/FontsFree-Net-SFProText-Light-1.ttf new file mode 100644 index 0000000..127dc7a Binary files /dev/null and b/gsf/assets/fonts/FontsFree-Net-SFProText-Light-1.ttf differ diff --git a/gsf/assets/fonts/FontsFree-Net-SFProText-Regular-1.ttf b/gsf/assets/fonts/FontsFree-Net-SFProText-Regular-1.ttf new file mode 100644 index 0000000..b63615e Binary files /dev/null and b/gsf/assets/fonts/FontsFree-Net-SFProText-Regular-1.ttf differ diff --git a/gsf/assets/fonts/FontsFree-Net-SFProText-Semibold-1.ttf b/gsf/assets/fonts/FontsFree-Net-SFProText-Semibold-1.ttf new file mode 100644 index 0000000..c4c70d5 Binary files /dev/null and b/gsf/assets/fonts/FontsFree-Net-SFProText-Semibold-1.ttf differ diff --git a/gsf/assets/fonts/Poppins-Black.ttf b/gsf/assets/fonts/Poppins-Black.ttf new file mode 100644 index 0000000..71c0f99 Binary files /dev/null and b/gsf/assets/fonts/Poppins-Black.ttf differ diff --git a/gsf/assets/fonts/Poppins-Bold.ttf b/gsf/assets/fonts/Poppins-Bold.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/gsf/assets/fonts/Poppins-Bold.ttf differ diff --git a/gsf/assets/fonts/Poppins-ExtraBold.ttf b/gsf/assets/fonts/Poppins-ExtraBold.ttf new file mode 100644 index 0000000..df70936 Binary files /dev/null and b/gsf/assets/fonts/Poppins-ExtraBold.ttf differ diff --git a/gsf/assets/fonts/Poppins-ExtraLight.ttf b/gsf/assets/fonts/Poppins-ExtraLight.ttf new file mode 100644 index 0000000..e76ec69 Binary files /dev/null and b/gsf/assets/fonts/Poppins-ExtraLight.ttf differ diff --git a/gsf/assets/fonts/Poppins-Light.ttf b/gsf/assets/fonts/Poppins-Light.ttf new file mode 100644 index 0000000..bc36bcc Binary files /dev/null and b/gsf/assets/fonts/Poppins-Light.ttf differ diff --git a/gsf/assets/fonts/Poppins-Medium.ttf b/gsf/assets/fonts/Poppins-Medium.ttf new file mode 100644 index 0000000..6bcdcc2 Binary files /dev/null and b/gsf/assets/fonts/Poppins-Medium.ttf differ diff --git a/gsf/assets/fonts/Poppins-Regular.ttf b/gsf/assets/fonts/Poppins-Regular.ttf new file mode 100644 index 0000000..9f0c71b Binary files /dev/null and b/gsf/assets/fonts/Poppins-Regular.ttf differ diff --git a/gsf/assets/fonts/Poppins-SemiBold.ttf b/gsf/assets/fonts/Poppins-SemiBold.ttf new file mode 100644 index 0000000..74c726e Binary files /dev/null and b/gsf/assets/fonts/Poppins-SemiBold.ttf differ diff --git a/gsf/assets/fonts/Poppins-Thin.ttf b/gsf/assets/fonts/Poppins-Thin.ttf new file mode 100644 index 0000000..03e7366 Binary files /dev/null and b/gsf/assets/fonts/Poppins-Thin.ttf differ diff --git a/gsf/assets/image/4.png b/gsf/assets/image/4.png new file mode 100644 index 0000000..645b393 Binary files /dev/null and b/gsf/assets/image/4.png differ diff --git a/gsf/assets/image/Icon1MCT.svg b/gsf/assets/image/Icon1MCT.svg new file mode 100644 index 0000000..05b71ef --- /dev/null +++ b/gsf/assets/image/Icon1MCT.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/Icon2MCT.svg b/gsf/assets/image/Icon2MCT.svg new file mode 100644 index 0000000..75545de --- /dev/null +++ b/gsf/assets/image/Icon2MCT.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/Icon3MCT.png b/gsf/assets/image/Icon3MCT.png new file mode 100644 index 0000000..55c265a Binary files /dev/null and b/gsf/assets/image/Icon3MCT.png differ diff --git a/gsf/assets/image/Icon4MCT.png b/gsf/assets/image/Icon4MCT.png new file mode 100644 index 0000000..4d77bd8 Binary files /dev/null and b/gsf/assets/image/Icon4MCT.png differ diff --git a/gsf/assets/image/Icon5MCT.png b/gsf/assets/image/Icon5MCT.png new file mode 100644 index 0000000..076ba5f Binary files /dev/null and b/gsf/assets/image/Icon5MCT.png differ diff --git a/gsf/assets/image/Icon5MCT_new.png b/gsf/assets/image/Icon5MCT_new.png new file mode 100644 index 0000000..a368eb5 Binary files /dev/null and b/gsf/assets/image/Icon5MCT_new.png differ diff --git a/gsf/assets/image/Icon6MCT.svg b/gsf/assets/image/Icon6MCT.svg new file mode 100644 index 0000000..d318898 --- /dev/null +++ b/gsf/assets/image/Icon6MCT.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/IconBookMCT.svg b/gsf/assets/image/IconBookMCT.svg new file mode 100644 index 0000000..57a4f8e --- /dev/null +++ b/gsf/assets/image/IconBookMCT.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/Layer.svg b/gsf/assets/image/Layer.svg new file mode 100644 index 0000000..fd24257 --- /dev/null +++ b/gsf/assets/image/Layer.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/MCT_blue.png b/gsf/assets/image/MCT_blue.png new file mode 100644 index 0000000..6bc5415 Binary files /dev/null and b/gsf/assets/image/MCT_blue.png differ diff --git a/gsf/assets/image/MCT_disabled_center.png b/gsf/assets/image/MCT_disabled_center.png new file mode 100644 index 0000000..4656ac4 Binary files /dev/null and b/gsf/assets/image/MCT_disabled_center.png differ diff --git a/gsf/assets/image/MCT_disabled_center_new.png b/gsf/assets/image/MCT_disabled_center_new.png new file mode 100644 index 0000000..b56fc6e Binary files /dev/null and b/gsf/assets/image/MCT_disabled_center_new.png differ diff --git a/gsf/assets/image/MCT_disabled_next.png b/gsf/assets/image/MCT_disabled_next.png new file mode 100644 index 0000000..fbfcfc8 Binary files /dev/null and b/gsf/assets/image/MCT_disabled_next.png differ diff --git a/gsf/assets/image/MCT_disabled_prev.png b/gsf/assets/image/MCT_disabled_prev.png new file mode 100644 index 0000000..ce380d9 Binary files /dev/null and b/gsf/assets/image/MCT_disabled_prev.png differ diff --git a/gsf/assets/image/MCT_green.png b/gsf/assets/image/MCT_green.png new file mode 100644 index 0000000..51cc229 Binary files /dev/null and b/gsf/assets/image/MCT_green.png differ diff --git a/gsf/assets/image/MCT_purple.png b/gsf/assets/image/MCT_purple.png new file mode 100644 index 0000000..2c67b7a Binary files /dev/null and b/gsf/assets/image/MCT_purple.png differ diff --git a/gsf/assets/image/MCT_purple_new.png b/gsf/assets/image/MCT_purple_new.png new file mode 100644 index 0000000..18e0ad6 Binary files /dev/null and b/gsf/assets/image/MCT_purple_new.png differ diff --git a/gsf/assets/image/MCT_red.png b/gsf/assets/image/MCT_red.png new file mode 100644 index 0000000..0ed2bf8 Binary files /dev/null and b/gsf/assets/image/MCT_red.png differ diff --git a/gsf/assets/image/MCT_red_new.png b/gsf/assets/image/MCT_red_new.png new file mode 100644 index 0000000..6c252c9 Binary files /dev/null and b/gsf/assets/image/MCT_red_new.png differ diff --git a/gsf/assets/image/MCT_yellow.png b/gsf/assets/image/MCT_yellow.png new file mode 100644 index 0000000..423b2c0 Binary files /dev/null and b/gsf/assets/image/MCT_yellow.png differ diff --git a/gsf/assets/image/Thumbprint.svg b/gsf/assets/image/Thumbprint.svg new file mode 100644 index 0000000..cc6f53b --- /dev/null +++ b/gsf/assets/image/Thumbprint.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gsf/assets/image/about_us.jpeg b/gsf/assets/image/about_us.jpeg new file mode 100644 index 0000000..7c1f90c Binary files /dev/null and b/gsf/assets/image/about_us.jpeg differ diff --git a/gsf/assets/image/android_logo.png b/gsf/assets/image/android_logo.png new file mode 100644 index 0000000..2546d82 Binary files /dev/null and b/gsf/assets/image/android_logo.png differ diff --git a/gsf/assets/image/apple.svg b/gsf/assets/image/apple.svg new file mode 100644 index 0000000..8e683b3 --- /dev/null +++ b/gsf/assets/image/apple.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/arrows/arrow_down.svg b/gsf/assets/image/arrows/arrow_down.svg new file mode 100644 index 0000000..3f10102 --- /dev/null +++ b/gsf/assets/image/arrows/arrow_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/arrows/arrow_right.svg b/gsf/assets/image/arrows/arrow_right.svg new file mode 100644 index 0000000..3e67785 --- /dev/null +++ b/gsf/assets/image/arrows/arrow_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/arrows/arrow_up.svg b/gsf/assets/image/arrows/arrow_up.svg new file mode 100644 index 0000000..6b88b97 --- /dev/null +++ b/gsf/assets/image/arrows/arrow_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/avatar.png b/gsf/assets/image/avatar.png new file mode 100644 index 0000000..1934635 Binary files /dev/null and b/gsf/assets/image/avatar.png differ diff --git a/gsf/assets/image/badges/wdi_badge.png b/gsf/assets/image/badges/wdi_badge.png new file mode 100644 index 0000000..31ad80e Binary files /dev/null and b/gsf/assets/image/badges/wdi_badge.png differ diff --git a/gsf/assets/image/blog/philosophyCard.jpg b/gsf/assets/image/blog/philosophyCard.jpg new file mode 100644 index 0000000..4dd0655 Binary files /dev/null and b/gsf/assets/image/blog/philosophyCard.jpg differ diff --git a/gsf/assets/image/calendar.svg b/gsf/assets/image/calendar.svg new file mode 100644 index 0000000..0daa1b0 --- /dev/null +++ b/gsf/assets/image/calendar.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/gsf/assets/image/cardio.jpg b/gsf/assets/image/cardio.jpg new file mode 100644 index 0000000..7853f3e Binary files /dev/null and b/gsf/assets/image/cardio.jpg differ diff --git a/gsf/assets/image/courses/courses_img.jpg b/gsf/assets/image/courses/courses_img.jpg new file mode 100644 index 0000000..c375924 Binary files /dev/null and b/gsf/assets/image/courses/courses_img.jpg differ diff --git a/gsf/assets/image/courses/fitness.jpg b/gsf/assets/image/courses/fitness.jpg new file mode 100644 index 0000000..0779d7b Binary files /dev/null and b/gsf/assets/image/courses/fitness.jpg differ diff --git a/gsf/assets/image/crown.svg b/gsf/assets/image/crown.svg new file mode 100644 index 0000000..de8db7b --- /dev/null +++ b/gsf/assets/image/crown.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/cycle_time.png b/gsf/assets/image/cycle_time.png new file mode 100644 index 0000000..4d0b986 Binary files /dev/null and b/gsf/assets/image/cycle_time.png differ diff --git a/gsf/assets/image/dietbg.jpeg b/gsf/assets/image/dietbg.jpeg new file mode 100644 index 0000000..43a9ef2 Binary files /dev/null and b/gsf/assets/image/dietbg.jpeg differ diff --git a/gsf/assets/image/duration.svg b/gsf/assets/image/duration.svg new file mode 100644 index 0000000..eb88040 --- /dev/null +++ b/gsf/assets/image/duration.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/gsf/assets/image/email.svg b/gsf/assets/image/email.svg new file mode 100644 index 0000000..d00ab7b --- /dev/null +++ b/gsf/assets/image/email.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/face-id-svgrepo-com.svg b/gsf/assets/image/face-id-svgrepo-com.svg new file mode 100644 index 0000000..a7ba69c --- /dev/null +++ b/gsf/assets/image/face-id-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gsf/assets/image/faq/activity.svg b/gsf/assets/image/faq/activity.svg new file mode 100644 index 0000000..676a292 --- /dev/null +++ b/gsf/assets/image/faq/activity.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/bmi_nutrition.svg b/gsf/assets/image/faq/bmi_nutrition.svg new file mode 100644 index 0000000..eceeec5 --- /dev/null +++ b/gsf/assets/image/faq/bmi_nutrition.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/coached.svg b/gsf/assets/image/faq/coached.svg new file mode 100644 index 0000000..dde2e48 --- /dev/null +++ b/gsf/assets/image/faq/coached.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/faq_main_logo.svg b/gsf/assets/image/faq/faq_main_logo.svg new file mode 100644 index 0000000..103cbb7 --- /dev/null +++ b/gsf/assets/image/faq/faq_main_logo.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/gsfCool.svg b/gsf/assets/image/faq/gsfCool.svg new file mode 100644 index 0000000..3038ee8 --- /dev/null +++ b/gsf/assets/image/faq/gsfCool.svg @@ -0,0 +1,709 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #BBF046 + + diff --git a/gsf/assets/image/faq/gsfCool_black.svg b/gsf/assets/image/faq/gsfCool_black.svg new file mode 100644 index 0000000..10349fb --- /dev/null +++ b/gsf/assets/image/faq/gsfCool_black.svg @@ -0,0 +1,709 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #BBF046 + + diff --git a/gsf/assets/image/faq/gsfFit.jpg b/gsf/assets/image/faq/gsfFit.jpg new file mode 100644 index 0000000..199e296 Binary files /dev/null and b/gsf/assets/image/faq/gsfFit.jpg differ diff --git a/gsf/assets/image/faq/logo.svg b/gsf/assets/image/faq/logo.svg new file mode 100644 index 0000000..8a471c7 --- /dev/null +++ b/gsf/assets/image/faq/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/faq/nutrition.svg b/gsf/assets/image/faq/nutrition.svg new file mode 100644 index 0000000..a327524 --- /dev/null +++ b/gsf/assets/image/faq/nutrition.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/progressive.svg b/gsf/assets/image/faq/progressive.svg new file mode 100644 index 0000000..a4d7dab --- /dev/null +++ b/gsf/assets/image/faq/progressive.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/secure_payment.svg b/gsf/assets/image/faq/secure_payment.svg new file mode 100644 index 0000000..a272723 --- /dev/null +++ b/gsf/assets/image/faq/secure_payment.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/transformations.svg b/gsf/assets/image/faq/transformations.svg new file mode 100644 index 0000000..a30cbd8 --- /dev/null +++ b/gsf/assets/image/faq/transformations.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/voucher.svg b/gsf/assets/image/faq/voucher.svg new file mode 100644 index 0000000..1dfd03e --- /dev/null +++ b/gsf/assets/image/faq/voucher.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/faq/workout.jpg b/gsf/assets/image/faq/workout.jpg new file mode 100644 index 0000000..482bac7 Binary files /dev/null and b/gsf/assets/image/faq/workout.jpg differ diff --git a/gsf/assets/image/faq/workout.svg b/gsf/assets/image/faq/workout.svg new file mode 100644 index 0000000..547b0af --- /dev/null +++ b/gsf/assets/image/faq/workout.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/fat_icon.svg b/gsf/assets/image/fat_icon.svg new file mode 100644 index 0000000..7800f8b --- /dev/null +++ b/gsf/assets/image/fat_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/feedback/happy_active.svg b/gsf/assets/image/feedback/happy_active.svg new file mode 100644 index 0000000..4aa2098 --- /dev/null +++ b/gsf/assets/image/feedback/happy_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/feedback/happy_unactive.svg b/gsf/assets/image/feedback/happy_unactive.svg new file mode 100644 index 0000000..7609e17 --- /dev/null +++ b/gsf/assets/image/feedback/happy_unactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/feedback/sad_active.svg b/gsf/assets/image/feedback/sad_active.svg new file mode 100644 index 0000000..35aae1e --- /dev/null +++ b/gsf/assets/image/feedback/sad_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/feedback/sad_unactive.svg b/gsf/assets/image/feedback/sad_unactive.svg new file mode 100644 index 0000000..088efc3 --- /dev/null +++ b/gsf/assets/image/feedback/sad_unactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/feedback_img/active.svg b/gsf/assets/image/feedback_img/active.svg new file mode 100644 index 0000000..710568b --- /dev/null +++ b/gsf/assets/image/feedback_img/active.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/feedback_img/crying.svg b/gsf/assets/image/feedback_img/crying.svg new file mode 100644 index 0000000..442ce15 --- /dev/null +++ b/gsf/assets/image/feedback_img/crying.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/feedback_img/normal.svg b/gsf/assets/image/feedback_img/normal.svg new file mode 100644 index 0000000..83f7b43 --- /dev/null +++ b/gsf/assets/image/feedback_img/normal.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/feedback_img/power.png b/gsf/assets/image/feedback_img/power.png new file mode 100644 index 0000000..d72e54a Binary files /dev/null and b/gsf/assets/image/feedback_img/power.png differ diff --git a/gsf/assets/image/feedback_img/smile.svg b/gsf/assets/image/feedback_img/smile.svg new file mode 100644 index 0000000..86be98a --- /dev/null +++ b/gsf/assets/image/feedback_img/smile.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/feedback_img/upset.svg b/gsf/assets/image/feedback_img/upset.svg new file mode 100644 index 0000000..b31b4f7 --- /dev/null +++ b/gsf/assets/image/feedback_img/upset.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/date_range/daily.svg b/gsf/assets/image/filter_leaderboard/date_range/daily.svg new file mode 100644 index 0000000..0644819 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/date_range/daily.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/date_range/monthly.svg b/gsf/assets/image/filter_leaderboard/date_range/monthly.svg new file mode 100644 index 0000000..f7b187f --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/date_range/monthly.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/date_range/weekly.svg b/gsf/assets/image/filter_leaderboard/date_range/weekly.svg new file mode 100644 index 0000000..7bc0b21 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/date_range/weekly.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/filters/data_time.svg b/gsf/assets/image/filter_leaderboard/filters/data_time.svg new file mode 100644 index 0000000..525f6dd --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/filters/data_time.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/filters/gender.svg b/gsf/assets/image/filter_leaderboard/filters/gender.svg new file mode 100644 index 0000000..e3c11a8 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/filters/gender.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/filters/gender_new.svg b/gsf/assets/image/filter_leaderboard/filters/gender_new.svg new file mode 100644 index 0000000..64a3589 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/filters/gender_new.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/filters/group_level_new.svg b/gsf/assets/image/filter_leaderboard/filters/group_level_new.svg new file mode 100644 index 0000000..931e17a --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/filters/group_level_new.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/filters/slider.svg b/gsf/assets/image/filter_leaderboard/filters/slider.svg new file mode 100644 index 0000000..e3ff82e --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/filters/slider.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/gender/gender_all.svg b/gsf/assets/image/filter_leaderboard/gender/gender_all.svg new file mode 100644 index 0000000..d8c54b9 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/gender/gender_all.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/gender/gender_female.svg b/gsf/assets/image/filter_leaderboard/gender/gender_female.svg new file mode 100644 index 0000000..1dc3c2f --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/gender/gender_female.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/gender/gender_male.svg b/gsf/assets/image/filter_leaderboard/gender/gender_male.svg new file mode 100644 index 0000000..acbebc8 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/gender/gender_male.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/filter_leaderboard/group_level/elites.svg b/gsf/assets/image/filter_leaderboard/group_level/elites.svg new file mode 100644 index 0000000..315a1f5 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/group_level/elites.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/filter_leaderboard/group_level/game_changers.svg b/gsf/assets/image/filter_leaderboard/group_level/game_changers.svg new file mode 100644 index 0000000..090a03f --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/group_level/game_changers.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/filter_leaderboard/group_level/underdogs.svg b/gsf/assets/image/filter_leaderboard/group_level/underdogs.svg new file mode 100644 index 0000000..d45e572 --- /dev/null +++ b/gsf/assets/image/filter_leaderboard/group_level/underdogs.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gsf/assets/image/fitness_regulations.svg b/gsf/assets/image/fitness_regulations.svg new file mode 100644 index 0000000..59c6b86 --- /dev/null +++ b/gsf/assets/image/fitness_regulations.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/gameChanger.png b/gsf/assets/image/gameChanger.png new file mode 100644 index 0000000..324f8cf Binary files /dev/null and b/gsf/assets/image/gameChanger.png differ diff --git a/gsf/assets/image/get_started.jpg b/gsf/assets/image/get_started.jpg new file mode 100644 index 0000000..2a186ff Binary files /dev/null and b/gsf/assets/image/get_started.jpg differ diff --git a/gsf/assets/image/gmail-svg.svg b/gsf/assets/image/gmail-svg.svg new file mode 100644 index 0000000..642320c --- /dev/null +++ b/gsf/assets/image/gmail-svg.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/google.svg b/gsf/assets/image/google.svg new file mode 100644 index 0000000..b276908 --- /dev/null +++ b/gsf/assets/image/google.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/gsf_avatar.png b/gsf/assets/image/gsf_avatar.png new file mode 100644 index 0000000..464be8b Binary files /dev/null and b/gsf/assets/image/gsf_avatar.png differ diff --git a/gsf/assets/image/gsf_logo.png b/gsf/assets/image/gsf_logo.png new file mode 100644 index 0000000..932f1e5 Binary files /dev/null and b/gsf/assets/image/gsf_logo.png differ diff --git a/gsf/assets/image/live-streaming.svg b/gsf/assets/image/live-streaming.svg new file mode 100644 index 0000000..a93dfc9 --- /dev/null +++ b/gsf/assets/image/live-streaming.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/loadder.svg b/gsf/assets/image/loadder.svg new file mode 100644 index 0000000..8eda62c --- /dev/null +++ b/gsf/assets/image/loadder.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L O D I N G + + diff --git a/gsf/assets/image/lock.svg b/gsf/assets/image/lock.svg new file mode 100644 index 0000000..5b659be --- /dev/null +++ b/gsf/assets/image/lock.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/logout.png b/gsf/assets/image/logout.png new file mode 100644 index 0000000..d266302 Binary files /dev/null and b/gsf/assets/image/logout.png differ diff --git a/gsf/assets/image/meditive.jpg b/gsf/assets/image/meditive.jpg new file mode 100644 index 0000000..c12dcff Binary files /dev/null and b/gsf/assets/image/meditive.jpg differ diff --git a/gsf/assets/image/menu.png b/gsf/assets/image/menu.png new file mode 100644 index 0000000..bb05cd7 Binary files /dev/null and b/gsf/assets/image/menu.png differ diff --git a/gsf/assets/image/menu_dark.png b/gsf/assets/image/menu_dark.png new file mode 100644 index 0000000..f0fe7ca Binary files /dev/null and b/gsf/assets/image/menu_dark.png differ diff --git a/gsf/assets/image/menuicon/home.svg b/gsf/assets/image/menuicon/home.svg new file mode 100644 index 0000000..661593b --- /dev/null +++ b/gsf/assets/image/menuicon/home.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/menuicon/home_black.svg b/gsf/assets/image/menuicon/home_black.svg new file mode 100644 index 0000000..c4731ee --- /dev/null +++ b/gsf/assets/image/menuicon/home_black.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/menuicon/live.svg b/gsf/assets/image/menuicon/live.svg new file mode 100644 index 0000000..2d5bff2 --- /dev/null +++ b/gsf/assets/image/menuicon/live.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/menuicon/live_black.svg b/gsf/assets/image/menuicon/live_black.svg new file mode 100644 index 0000000..42c6fad --- /dev/null +++ b/gsf/assets/image/menuicon/live_black.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/menuicon/profile.svg b/gsf/assets/image/menuicon/profile.svg new file mode 100644 index 0000000..56679a0 --- /dev/null +++ b/gsf/assets/image/menuicon/profile.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/menuicon/profile_black.svg b/gsf/assets/image/menuicon/profile_black.svg new file mode 100644 index 0000000..e9ffc6b --- /dev/null +++ b/gsf/assets/image/menuicon/profile_black.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/menuicon/ranking.svg b/gsf/assets/image/menuicon/ranking.svg new file mode 100644 index 0000000..da312aa --- /dev/null +++ b/gsf/assets/image/menuicon/ranking.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/menuicon/ranking_black.svg b/gsf/assets/image/menuicon/ranking_black.svg new file mode 100644 index 0000000..26f53b1 --- /dev/null +++ b/gsf/assets/image/menuicon/ranking_black.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/menuicon/weight_scale.svg b/gsf/assets/image/menuicon/weight_scale.svg new file mode 100644 index 0000000..5b91520 --- /dev/null +++ b/gsf/assets/image/menuicon/weight_scale.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/menuicon/weight_scale_black.svg b/gsf/assets/image/menuicon/weight_scale_black.svg new file mode 100644 index 0000000..29f3495 --- /dev/null +++ b/gsf/assets/image/menuicon/weight_scale_black.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/mood_icons/active/mood_happy_active.svg b/gsf/assets/image/mood_icons/active/mood_happy_active.svg new file mode 100644 index 0000000..0673641 --- /dev/null +++ b/gsf/assets/image/mood_icons/active/mood_happy_active.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/active/mood_ok_active.svg b/gsf/assets/image/mood_icons/active/mood_ok_active.svg new file mode 100644 index 0000000..2ab2977 --- /dev/null +++ b/gsf/assets/image/mood_icons/active/mood_ok_active.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/active/mood_sad_active.svg b/gsf/assets/image/mood_icons/active/mood_sad_active.svg new file mode 100644 index 0000000..4ac91d4 --- /dev/null +++ b/gsf/assets/image/mood_icons/active/mood_sad_active.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/active/mood_very_happy_active.svg b/gsf/assets/image/mood_icons/active/mood_very_happy_active.svg new file mode 100644 index 0000000..0a6be4d --- /dev/null +++ b/gsf/assets/image/mood_icons/active/mood_very_happy_active.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/mood_icons/active/mood_whatever_active.svg b/gsf/assets/image/mood_icons/active/mood_whatever_active.svg new file mode 100644 index 0000000..ec56cd7 --- /dev/null +++ b/gsf/assets/image/mood_icons/active/mood_whatever_active.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/inactive/mood_happy_inactive.svg b/gsf/assets/image/mood_icons/inactive/mood_happy_inactive.svg new file mode 100644 index 0000000..a19d198 --- /dev/null +++ b/gsf/assets/image/mood_icons/inactive/mood_happy_inactive.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/inactive/mood_ok_inactive.svg b/gsf/assets/image/mood_icons/inactive/mood_ok_inactive.svg new file mode 100644 index 0000000..c25e555 --- /dev/null +++ b/gsf/assets/image/mood_icons/inactive/mood_ok_inactive.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/inactive/mood_sad_inactive.svg b/gsf/assets/image/mood_icons/inactive/mood_sad_inactive.svg new file mode 100644 index 0000000..74bd131 --- /dev/null +++ b/gsf/assets/image/mood_icons/inactive/mood_sad_inactive.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/inactive/mood_very_happy_inactive.svg b/gsf/assets/image/mood_icons/inactive/mood_very_happy_inactive.svg new file mode 100644 index 0000000..6e414cc --- /dev/null +++ b/gsf/assets/image/mood_icons/inactive/mood_very_happy_inactive.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/mood_icons/inactive/mood_whatever_inactive.svg b/gsf/assets/image/mood_icons/inactive/mood_whatever_inactive.svg new file mode 100644 index 0000000..87d9c89 --- /dev/null +++ b/gsf/assets/image/mood_icons/inactive/mood_whatever_inactive.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/muscle_rate.svg b/gsf/assets/image/muscle_rate.svg new file mode 100644 index 0000000..92870ac --- /dev/null +++ b/gsf/assets/image/muscle_rate.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/music.png b/gsf/assets/image/music.png new file mode 100644 index 0000000..64f3f67 Binary files /dev/null and b/gsf/assets/image/music.png differ diff --git a/gsf/assets/image/no-wifi-icon.svg b/gsf/assets/image/no-wifi-icon.svg new file mode 100644 index 0000000..e67de45 --- /dev/null +++ b/gsf/assets/image/no-wifi-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/nutrition.svg b/gsf/assets/image/nutrition.svg new file mode 100644 index 0000000..8ddf443 --- /dev/null +++ b/gsf/assets/image/nutrition.svg @@ -0,0 +1 @@ +nutrition \ No newline at end of file diff --git a/gsf/assets/image/overview_guide/list-scale.png b/gsf/assets/image/overview_guide/list-scale.png new file mode 100644 index 0000000..61efbe7 Binary files /dev/null and b/gsf/assets/image/overview_guide/list-scale.png differ diff --git a/gsf/assets/image/overview_guide/scale.png b/gsf/assets/image/overview_guide/scale.png new file mode 100644 index 0000000..87ff88b Binary files /dev/null and b/gsf/assets/image/overview_guide/scale.png differ diff --git a/gsf/assets/image/overview_guide/step-on-scale.png b/gsf/assets/image/overview_guide/step-on-scale.png new file mode 100644 index 0000000..e6ded2f Binary files /dev/null and b/gsf/assets/image/overview_guide/step-on-scale.png differ diff --git a/gsf/assets/image/overview_guide/topbar.png b/gsf/assets/image/overview_guide/topbar.png new file mode 100644 index 0000000..bf48060 Binary files /dev/null and b/gsf/assets/image/overview_guide/topbar.png differ diff --git a/gsf/assets/image/overview_guide/topbar_ios.png b/gsf/assets/image/overview_guide/topbar_ios.png new file mode 100644 index 0000000..5809c59 Binary files /dev/null and b/gsf/assets/image/overview_guide/topbar_ios.png differ diff --git a/gsf/assets/image/personal_details.svg b/gsf/assets/image/personal_details.svg new file mode 100644 index 0000000..8939e46 --- /dev/null +++ b/gsf/assets/image/personal_details.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/phone.svg b/gsf/assets/image/phone.svg new file mode 100644 index 0000000..41becef --- /dev/null +++ b/gsf/assets/image/phone.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/placeholder.jpg b/gsf/assets/image/placeholder.jpg new file mode 100644 index 0000000..12e6125 Binary files /dev/null and b/gsf/assets/image/placeholder.jpg differ diff --git a/gsf/assets/image/podcast/podcastImg.jpg b/gsf/assets/image/podcast/podcastImg.jpg new file mode 100644 index 0000000..8ac6f71 Binary files /dev/null and b/gsf/assets/image/podcast/podcastImg.jpg differ diff --git a/gsf/assets/image/podcastAudio.jpg b/gsf/assets/image/podcastAudio.jpg new file mode 100644 index 0000000..cbfa3cd Binary files /dev/null and b/gsf/assets/image/podcastAudio.jpg differ diff --git a/gsf/assets/image/polygon.svg b/gsf/assets/image/polygon.svg new file mode 100644 index 0000000..527ede5 --- /dev/null +++ b/gsf/assets/image/polygon.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/profile/age.svg b/gsf/assets/image/profile/age.svg new file mode 100644 index 0000000..b671e73 --- /dev/null +++ b/gsf/assets/image/profile/age.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/profile/call.svg b/gsf/assets/image/profile/call.svg new file mode 100644 index 0000000..b5bd838 --- /dev/null +++ b/gsf/assets/image/profile/call.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/profile/crown.svg b/gsf/assets/image/profile/crown.svg new file mode 100644 index 0000000..d7e3e1f --- /dev/null +++ b/gsf/assets/image/profile/crown.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/profile/dumbell.svg b/gsf/assets/image/profile/dumbell.svg new file mode 100644 index 0000000..9e1d92c --- /dev/null +++ b/gsf/assets/image/profile/dumbell.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profile/gender.svg b/gsf/assets/image/profile/gender.svg new file mode 100644 index 0000000..a181a08 --- /dev/null +++ b/gsf/assets/image/profile/gender.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profile/height.svg b/gsf/assets/image/profile/height.svg new file mode 100644 index 0000000..2359b24 --- /dev/null +++ b/gsf/assets/image/profile/height.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profile/location.svg b/gsf/assets/image/profile/location.svg new file mode 100644 index 0000000..36eaf6a --- /dev/null +++ b/gsf/assets/image/profile/location.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/gsf/assets/image/profile/mail.svg b/gsf/assets/image/profile/mail.svg new file mode 100644 index 0000000..9b8e1a6 --- /dev/null +++ b/gsf/assets/image/profile/mail.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/profile/quote.svg b/gsf/assets/image/profile/quote.svg new file mode 100644 index 0000000..53e0e7f --- /dev/null +++ b/gsf/assets/image/profile/quote.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/profile/runner.svg b/gsf/assets/image/profile/runner.svg new file mode 100644 index 0000000..c44e139 --- /dev/null +++ b/gsf/assets/image/profile/runner.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/basal_metabolism.svg b/gsf/assets/image/profileIcons/basal_metabolism.svg new file mode 100644 index 0000000..044e013 --- /dev/null +++ b/gsf/assets/image/profileIcons/basal_metabolism.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/bodyFat.svg b/gsf/assets/image/profileIcons/bodyFat.svg new file mode 100644 index 0000000..fec3fb4 --- /dev/null +++ b/gsf/assets/image/profileIcons/bodyFat.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/profileIcons/body_age.svg b/gsf/assets/image/profileIcons/body_age.svg new file mode 100644 index 0000000..fb3c6e6 --- /dev/null +++ b/gsf/assets/image/profileIcons/body_age.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/bone_mass.svg b/gsf/assets/image/profileIcons/bone_mass.svg new file mode 100644 index 0000000..708240b --- /dev/null +++ b/gsf/assets/image/profileIcons/bone_mass.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/idealWeight.svg b/gsf/assets/image/profileIcons/idealWeight.svg new file mode 100644 index 0000000..d447e65 --- /dev/null +++ b/gsf/assets/image/profileIcons/idealWeight.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/lean_body.svg b/gsf/assets/image/profileIcons/lean_body.svg new file mode 100644 index 0000000..6503411 --- /dev/null +++ b/gsf/assets/image/profileIcons/lean_body.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/profileIcons/moisture.svg b/gsf/assets/image/profileIcons/moisture.svg new file mode 100644 index 0000000..6581af9 --- /dev/null +++ b/gsf/assets/image/profileIcons/moisture.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profileIcons/muscle_rate.svg b/gsf/assets/image/profileIcons/muscle_rate.svg new file mode 100644 index 0000000..954b840 --- /dev/null +++ b/gsf/assets/image/profileIcons/muscle_rate.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/profileIcons/protein_rate.svg b/gsf/assets/image/profileIcons/protein_rate.svg new file mode 100644 index 0000000..f5bac53 --- /dev/null +++ b/gsf/assets/image/profileIcons/protein_rate.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/profile_user.svg b/gsf/assets/image/profile_user.svg new file mode 100644 index 0000000..d26d2ef --- /dev/null +++ b/gsf/assets/image/profile_user.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/quiz.png b/gsf/assets/image/quiz.png new file mode 100644 index 0000000..74bd93a Binary files /dev/null and b/gsf/assets/image/quiz.png differ diff --git a/gsf/assets/image/quiz_imgs/app_usage.png b/gsf/assets/image/quiz_imgs/app_usage.png new file mode 100644 index 0000000..d009c80 Binary files /dev/null and b/gsf/assets/image/quiz_imgs/app_usage.png differ diff --git a/gsf/assets/image/quiz_imgs/badge_dialog.jpg b/gsf/assets/image/quiz_imgs/badge_dialog.jpg new file mode 100644 index 0000000..6a0f144 Binary files /dev/null and b/gsf/assets/image/quiz_imgs/badge_dialog.jpg differ diff --git a/gsf/assets/image/quiz_imgs/bulb.svg b/gsf/assets/image/quiz_imgs/bulb.svg new file mode 100644 index 0000000..df71516 --- /dev/null +++ b/gsf/assets/image/quiz_imgs/bulb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gsf/assets/image/quiz_imgs/cancel_outlined_rounded.svg b/gsf/assets/image/quiz_imgs/cancel_outlined_rounded.svg new file mode 100644 index 0000000..bd9f766 --- /dev/null +++ b/gsf/assets/image/quiz_imgs/cancel_outlined_rounded.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/quiz_imgs/celebration.svg b/gsf/assets/image/quiz_imgs/celebration.svg new file mode 100644 index 0000000..94100ca --- /dev/null +++ b/gsf/assets/image/quiz_imgs/celebration.svg @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/quiz_imgs/exercise.svg b/gsf/assets/image/quiz_imgs/exercise.svg new file mode 100644 index 0000000..51d410b --- /dev/null +++ b/gsf/assets/image/quiz_imgs/exercise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gsf/assets/image/quiz_imgs/general_medical.svg b/gsf/assets/image/quiz_imgs/general_medical.svg new file mode 100644 index 0000000..14a7698 --- /dev/null +++ b/gsf/assets/image/quiz_imgs/general_medical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gsf/assets/image/quiz_imgs/milestone.png b/gsf/assets/image/quiz_imgs/milestone.png new file mode 100644 index 0000000..affab8d Binary files /dev/null and b/gsf/assets/image/quiz_imgs/milestone.png differ diff --git a/gsf/assets/image/quiz_imgs/nutrition.svg b/gsf/assets/image/quiz_imgs/nutrition.svg new file mode 100644 index 0000000..98006f1 --- /dev/null +++ b/gsf/assets/image/quiz_imgs/nutrition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gsf/assets/image/quiz_imgs/padlock.svg b/gsf/assets/image/quiz_imgs/padlock.svg new file mode 100644 index 0000000..b38bf7b --- /dev/null +++ b/gsf/assets/image/quiz_imgs/padlock.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gsf/assets/image/quiz_imgs/quiz_header_bg.jpg b/gsf/assets/image/quiz_imgs/quiz_header_bg.jpg new file mode 100644 index 0000000..fa4a7a9 Binary files /dev/null and b/gsf/assets/image/quiz_imgs/quiz_header_bg.jpg differ diff --git a/gsf/assets/image/quiz_imgs/stopwatch.png b/gsf/assets/image/quiz_imgs/stopwatch.png new file mode 100644 index 0000000..b3a2408 Binary files /dev/null and b/gsf/assets/image/quiz_imgs/stopwatch.png differ diff --git a/gsf/assets/image/quiz_imgs/streaks.png b/gsf/assets/image/quiz_imgs/streaks.png new file mode 100644 index 0000000..27fd84f Binary files /dev/null and b/gsf/assets/image/quiz_imgs/streaks.png differ diff --git a/gsf/assets/image/ratings.svg b/gsf/assets/image/ratings.svg new file mode 100644 index 0000000..6b22145 --- /dev/null +++ b/gsf/assets/image/ratings.svg @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/runner.svg b/gsf/assets/image/runner.svg new file mode 100644 index 0000000..3b31a1d --- /dev/null +++ b/gsf/assets/image/runner.svg @@ -0,0 +1,546 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/runnerBg.svg b/gsf/assets/image/runnerBg.svg new file mode 100644 index 0000000..3e08c68 --- /dev/null +++ b/gsf/assets/image/runnerBg.svg @@ -0,0 +1,575 @@ + + + + Get + Get Fit + Rewarded + + + + + Monthly Winners + Amazing Rewards + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/runnerBg_black.svg b/gsf/assets/image/runnerBg_black.svg new file mode 100644 index 0000000..ab72091 --- /dev/null +++ b/gsf/assets/image/runnerBg_black.svg @@ -0,0 +1,575 @@ + + + + Get + Get Fit + Rewarded + + + + + Monthly Winners + Amazing Rewards + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/setting/lock.svg b/gsf/assets/image/setting/lock.svg new file mode 100644 index 0000000..e2cebf1 --- /dev/null +++ b/gsf/assets/image/setting/lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/setting/lock_black.svg b/gsf/assets/image/setting/lock_black.svg new file mode 100644 index 0000000..ab2ab2a --- /dev/null +++ b/gsf/assets/image/setting/lock_black.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/setting/notification.svg b/gsf/assets/image/setting/notification.svg new file mode 100644 index 0000000..89da591 --- /dev/null +++ b/gsf/assets/image/setting/notification.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/setting/notification_black.svg b/gsf/assets/image/setting/notification_black.svg new file mode 100644 index 0000000..8782283 --- /dev/null +++ b/gsf/assets/image/setting/notification_black.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gsf/assets/image/setting/passwordreset.svg b/gsf/assets/image/setting/passwordreset.svg new file mode 100644 index 0000000..69a48ce --- /dev/null +++ b/gsf/assets/image/setting/passwordreset.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/setting/passwordreset_black.svg b/gsf/assets/image/setting/passwordreset_black.svg new file mode 100644 index 0000000..c124127 --- /dev/null +++ b/gsf/assets/image/setting/passwordreset_black.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/share.svg b/gsf/assets/image/share.svg new file mode 100644 index 0000000..dfdb629 --- /dev/null +++ b/gsf/assets/image/share.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/gsf/assets/image/share_black.svg b/gsf/assets/image/share_black.svg new file mode 100644 index 0000000..22bedf4 --- /dev/null +++ b/gsf/assets/image/share_black.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/about.svg b/gsf/assets/image/sidebarIcons/about.svg new file mode 100644 index 0000000..fc64029 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/about.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/about_black.svg b/gsf/assets/image/sidebarIcons/about_black.svg new file mode 100644 index 0000000..a66331e --- /dev/null +++ b/gsf/assets/image/sidebarIcons/about_black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/chat.svg b/gsf/assets/image/sidebarIcons/chat.svg new file mode 100644 index 0000000..6c7ff05 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/chat.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/diet.svg b/gsf/assets/image/sidebarIcons/diet.svg new file mode 100644 index 0000000..eb73316 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/diet.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/help_info.svg b/gsf/assets/image/sidebarIcons/help_info.svg new file mode 100644 index 0000000..56c4235 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/help_info.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/help_info_black.svg b/gsf/assets/image/sidebarIcons/help_info_black.svg new file mode 100644 index 0000000..a0fcb9b --- /dev/null +++ b/gsf/assets/image/sidebarIcons/help_info_black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/instagram.svg b/gsf/assets/image/sidebarIcons/instagram.svg new file mode 100644 index 0000000..c37cb5b --- /dev/null +++ b/gsf/assets/image/sidebarIcons/instagram.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/instagram_black.svg b/gsf/assets/image/sidebarIcons/instagram_black.svg new file mode 100644 index 0000000..3684b69 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/instagram_black.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/logout.svg b/gsf/assets/image/sidebarIcons/logout.svg new file mode 100644 index 0000000..e94460d --- /dev/null +++ b/gsf/assets/image/sidebarIcons/logout.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/logout_black.svg b/gsf/assets/image/sidebarIcons/logout_black.svg new file mode 100644 index 0000000..e8c6159 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/logout_black.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/news_articles.svg b/gsf/assets/image/sidebarIcons/news_articles.svg new file mode 100644 index 0000000..5403bcb --- /dev/null +++ b/gsf/assets/image/sidebarIcons/news_articles.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/gsf/assets/image/sidebarIcons/phone.svg b/gsf/assets/image/sidebarIcons/phone.svg new file mode 100644 index 0000000..44cfa37 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/sidebarIcons/phone_black.svg b/gsf/assets/image/sidebarIcons/phone_black.svg new file mode 100644 index 0000000..33c38bb --- /dev/null +++ b/gsf/assets/image/sidebarIcons/phone_black.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/sidebarIcons/podcast.svg b/gsf/assets/image/sidebarIcons/podcast.svg new file mode 100644 index 0000000..7c573a7 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/podcast.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/previous.svg b/gsf/assets/image/sidebarIcons/previous.svg new file mode 100644 index 0000000..b5df9a8 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/previous.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/sidebarIcons/quiz.svg b/gsf/assets/image/sidebarIcons/quiz.svg new file mode 100644 index 0000000..f9def7c --- /dev/null +++ b/gsf/assets/image/sidebarIcons/quiz.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/rank.svg b/gsf/assets/image/sidebarIcons/rank.svg new file mode 100644 index 0000000..ae6d797 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/rank.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/sidebarIcons/short_video.svg b/gsf/assets/image/sidebarIcons/short_video.svg new file mode 100644 index 0000000..89663b1 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/short_video.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/gsf/assets/image/sidebarIcons/short_video_black.svg b/gsf/assets/image/sidebarIcons/short_video_black.svg new file mode 100644 index 0000000..89663b1 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/short_video_black.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/gsf/assets/image/sidebarIcons/short_videos.svg b/gsf/assets/image/sidebarIcons/short_videos.svg new file mode 100644 index 0000000..c724473 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/short_videos.svg @@ -0,0 +1 @@ +videos \ No newline at end of file diff --git a/gsf/assets/image/sidebarIcons/subscriptions.svg b/gsf/assets/image/sidebarIcons/subscriptions.svg new file mode 100644 index 0000000..2eeb3c8 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/subscriptions.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/sidebarIcons/video.svg b/gsf/assets/image/sidebarIcons/video.svg new file mode 100644 index 0000000..bdc3101 --- /dev/null +++ b/gsf/assets/image/sidebarIcons/video.svg @@ -0,0 +1,46 @@ + + + + + + + + + diff --git a/gsf/assets/image/sidebarIcons/video_black.svg b/gsf/assets/image/sidebarIcons/video_black.svg new file mode 100644 index 0000000..2fa65da --- /dev/null +++ b/gsf/assets/image/sidebarIcons/video_black.svg @@ -0,0 +1,46 @@ + + + + + + + + + diff --git a/gsf/assets/image/slider_img.png b/gsf/assets/image/slider_img.png new file mode 100644 index 0000000..7c9e435 Binary files /dev/null and b/gsf/assets/image/slider_img.png differ diff --git a/gsf/assets/image/splash.png b/gsf/assets/image/splash.png new file mode 100644 index 0000000..e33ac14 Binary files /dev/null and b/gsf/assets/image/splash.png differ diff --git a/gsf/assets/image/summerSweet.jpg b/gsf/assets/image/summerSweet.jpg new file mode 100644 index 0000000..38d2ec0 Binary files /dev/null and b/gsf/assets/image/summerSweet.jpg differ diff --git a/gsf/assets/image/thanksContact.png b/gsf/assets/image/thanksContact.png new file mode 100644 index 0000000..7131ce6 Binary files /dev/null and b/gsf/assets/image/thanksContact.png differ diff --git a/gsf/assets/image/user.svg b/gsf/assets/image/user.svg new file mode 100644 index 0000000..963fe96 --- /dev/null +++ b/gsf/assets/image/user.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/gsf/assets/image/weight_scales.svg b/gsf/assets/image/weight_scales.svg new file mode 100644 index 0000000..f929ad1 --- /dev/null +++ b/gsf/assets/image/weight_scales.svg @@ -0,0 +1,3 @@ + + + diff --git a/gsf/assets/image/whatsapp.svg b/gsf/assets/image/whatsapp.svg new file mode 100644 index 0000000..9046cb1 --- /dev/null +++ b/gsf/assets/image/whatsapp.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/gsf/assets/image/yoga.jpg b/gsf/assets/image/yoga.jpg new file mode 100644 index 0000000..c9fa691 Binary files /dev/null and b/gsf/assets/image/yoga.jpg differ diff --git a/gsf/assets/image/yoga1.jpg b/gsf/assets/image/yoga1.jpg new file mode 100644 index 0000000..e9f689a Binary files /dev/null and b/gsf/assets/image/yoga1.jpg differ diff --git a/gsf/assets/lottie/add.json b/gsf/assets/lottie/add.json new file mode 100644 index 0000000..e8082d6 --- /dev/null +++ b/gsf/assets/lottie/add.json @@ -0,0 +1 @@ +{"v":"5.7.6","fr":24,"ip":0,"op":37,"w":500,"h":500,"nm":"49-plus-circle-outline","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"NULL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[374,374,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"NULL 4","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":18,"s":[-90]},{"t":35,"s":[-90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[60,60,0],"to":[-0.021,0.167,0],"ti":[0.021,-0.167,0]},{"t":27,"s":[59.875,61,0]}],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[-9,-9,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":27,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Warstwa 8","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[1111.111,1111.111,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":1,"s":[{"i":[[-3.03,-10.073],[0.261,-5.147],[21.998,-1.115],[4.635,1.394],[-7.438,7.438],[0,0]],"o":[[1.394,4.635],[-1.115,21.998],[-5.147,0.261],[-10.073,-3.03],[0,0],[7.438,-7.438]],"v":[[40.917,-12.455],[42.689,2.289],[1.701,43.277],[-13.043,41.505],[-18.765,18.249],[17.661,-18.177]],"c":true}]},{"t":26,"s":[{"i":[[-3.03,-10.073],[0.261,-5.147],[21.998,-1.115],[4.635,1.394],[-7.438,7.438],[0,0]],"o":[[1.394,4.635],[-1.115,21.998],[-5.147,0.261],[-10.073,-3.03],[0,0],[7.438,-7.438]],"v":[[40.249,-12.321],[42.02,2.423],[1.033,43.41],[-13.711,41.639],[-19.433,18.383],[16.993,-18.043]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.03137254902,0.658823529412,0.541176470588,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5.2,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(6.2 / 100, comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":69,"ix":1},"e":{"a":0,"k":94.8,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.536],"y":[0.356]},"o":{"x":[0.514],"y":[0.714]},"t":0,"s":[-32]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[-396]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[-390]},{"i":{"x":[0.22],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-394]},{"t":35,"s":[-392]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":27,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":3,"nm":"NULL 3","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":18,"s":[-90]},{"t":35,"s":[-90]}],"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[9,9,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Warstwa 7","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[1111.111,1111.111,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.002,-9.98],[0.258,-5.099],[21.794,-1.104],[4.592,1.381],[-7.369,7.369],[0,0]],"o":[[1.381,4.592],[-1.104,21.794],[-5.099,0.258],[-9.98,-3.002],[0,0],[7.369,-7.369]],"v":[[41.034,-12.317],[42.79,2.29],[2.183,42.897],[-12.424,41.142],[-18.093,18.102],[17.995,-17.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.03137254902,0.658823529412,0.541176470588,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5.2,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(6.2 / 100, comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":69,"ix":1},"e":{"a":0,"k":94.8,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.536],"y":[0.356]},"o":{"x":[0.514],"y":[0.714]},"t":0,"s":[-32]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[-396]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[-390]},{"i":{"x":[0.22],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-394]},{"t":35,"s":[-392]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":1,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":3,"nm":"NULL 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8,"s":[-90]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":18,"s":[-180]},{"t":35,"s":[-180]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[60,60,0],"to":[-0.021,0.167,0],"ti":[0.021,-0.167,0]},{"t":27,"s":[59.875,61,0]}],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[-9,-9,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":27,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Warstwa 6","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[1111.111,1111.111,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":1,"s":[{"i":[[-3.003,-9.983],[0.258,-5.1],[21.8,-1.105],[4.593,1.382],[-7.371,7.371],[0,0]],"o":[[1.382,4.593],[-1.105,21.8],[-5.1,0.258],[-9.983,-3.003],[0,0],[7.371,-7.371]],"v":[[41.255,-12.359],[43.01,2.252],[2.392,42.87],[-12.219,41.114],[-17.889,18.068],[18.208,-18.03]],"c":true}]},{"t":26,"s":[{"i":[[-3.003,-9.983],[0.258,-5.1],[21.8,-1.105],[4.593,1.382],[-7.371,7.371],[0,0]],"o":[[1.382,4.593],[-1.105,21.8],[-5.1,0.258],[-9.983,-3.003],[0,0],[7.371,-7.371]],"v":[[40.987,-12.894],[42.743,1.717],[2.125,42.335],[-12.486,40.579],[-18.157,17.533],[17.941,-18.565]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.03137254902,0.658823529412,0.541176470588,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5.2,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(6.2 / 100, comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":69,"ix":1},"e":{"a":0,"k":94.8,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.536],"y":[0.356]},"o":{"x":[0.514],"y":[0.714]},"t":0,"s":[-32]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[-396]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[-390]},{"i":{"x":[0.22],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-394]},{"t":35,"s":[-392]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":1,"op":27,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":3,"nm":"NULL","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8,"s":[-90]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":18,"s":[-180]},{"t":35,"s":[-180]}],"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[9,9,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Warstwa 3","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[1111.111,1111.111,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.01,-10.006],[0.259,-5.112],[21.851,-1.107],[4.604,1.385],[-7.389,7.389],[0,0]],"o":[[1.385,4.604],[-1.107,21.851],[-5.112,0.259],[-10.006,-3.01],[0,0],[7.389,-7.389]],"v":[[41.194,-12.571],[42.954,2.075],[2.24,42.789],[-12.406,41.029],[-18.09,17.928],[18.093,-18.255]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.03137254902,0.658823529412,0.541176470588,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5.2,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(6.2 / 100, comp('49-plus-circle-outline').layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":69,"ix":1},"e":{"a":0,"k":94.8,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.536],"y":[0.356]},"o":{"x":[0.514],"y":[0.714]},"t":0,"s":[-32]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[-396]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[-390]},{"i":{"x":[0.22],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-394]},{"t":35,"s":[-392]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"0bbf046","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-105,15,0],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"0bbf046002","np":3,"mn":"ADBE Checkbox Control","ix":1,"en":1,"ef":[{"ty":7,"nm":"Checkbox","mn":"ADBE Checkbox Control-0001","ix":1,"v":{"a":0,"k":0,"ix":1}}]}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"cl":"com","sr":1,"ks":{"o":{"a":0,"k":20,"ix":11,"x":"var $bm_rt;\nvar checkbox = thisComp.layer('0bbf046').effect('0bbf046002')('Checkbox');\nif (checkbox == 1) {\n $bm_rt = 20;\n} else {\n $bm_rt = 0;\n}\n;"},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.934,481.369,0],"ix":2,"l":2},"a":{"a":0,"k":[79.934,0.369,0],"ix":1,"l":2},"s":{"a":0,"k":[265.159,265.159,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.415,0],[11.014,0],[11.014,-2.523],[4.656,-2.523],[4.656,-14.809],[1.415,-14.809]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"l","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[11.167,-7.199],[12.992,-1.661],[18.243,0.369],[23.514,-1.743],[25.381,-7.548],[23.494,-13.127],[18.284,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[14.49,-7.302],[15.577,-11.609],[18.305,-12.86],[21.689,-10.235],[22.058,-7.589],[21.053,-3.343],[18.284,-1.969],[15.597,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"o","np":5,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-0.287,-0.841],[-0.144,-0.82],[0,0],[0.164,0.656],[0.226,1.743],[2.236,0.205],[0,2.769],[0.923,0.8],[1.641,-0.021],[0,0]],"o":[[0,0],[0,0],[0,0],[0.533,0],[0.205,0.574],[0,0],[-0.164,-0.246],[-0.103,-0.41],[-0.267,-1.928],[0.718,-0.205],[0,-0.964],[-1.19,-1.026],[0,0],[0,0]],"v":[[27.381,0],[30.622,0],[30.622,-5.989],[33.411,-5.989],[35.011,-5.148],[35.811,0],[39.318,0],[38.867,-1.067],[38.416,-3.938],[35.749,-7.343],[38.847,-10.973],[37.554,-13.824],[33.063,-14.829],[27.381,-14.829]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.492,-0.349],[0,-1.005],[0.226,-0.164],[0.369,0],[0,0]],"o":[[0,0],[1.005,0],[0.287,0.185],[0,1.046],[-0.513,0.41],[0,0],[0,0]],"v":[[30.519,-12.491],[32.652,-12.491],[34.744,-12.142],[35.524,-10.481],[34.703,-8.758],[33.083,-8.348],[30.519,-8.348]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"r","np":5,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.554,0.103],[0,4.553],[1.866,1.374],[0.82,0],[0,0]],"o":[[0,0],[1.497,0],[2.81,-0.513],[0,-2.113],[-1.784,-1.313],[0,0],[0,0]],"v":[[41.068,0],[45.683,0],[48.349,-0.164],[53.6,-7.609],[51.077,-13.434],[45.97,-14.768],[41.068,-14.788]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.656,-0.185],[0,-2.092],[1.251,-1.251],[1.354,0],[0.349,0.021]],"o":[[1.825,-0.082],[1.99,0.554],[0,0.718],[-0.923,0.923],[-0.369,0],[0,0]],"v":[[44.288,-12.388],[47.611,-12.183],[50.318,-7.609],[48.985,-3.425],[45.539,-2.4],[44.288,-2.441]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d","np":5,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[55.669,0],[58.849,0],[58.849,-14.87],[55.669,-14.87]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"i","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.241,0],[0,-4.697],[-5.107,0],[-1.313,1.354],[-0.062,0.882],[0,0],[1.333,0],[0,0.882],[-2.359,0],[-0.062,-0.513]],"o":[[0,-2.954],[-4.164,0],[0,3.671],[1.354,0],[1.19,-1.231],[0,0],[-0.062,1.969],[-3.097,0],[0,-3.056],[2.154,0],[0,0]],"v":[[73.104,-9.989],[67.587,-14.911],[60.798,-7.097],[67.566,0.349],[71.894,-1.313],[73.227,-4.799],[69.884,-4.799],[67.218,-1.99],[64.121,-7.076],[67.464,-12.593],[69.864,-9.989]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[74.546,-7.199],[76.372,-1.661],[81.622,0.369],[86.894,-1.743],[88.76,-7.548],[86.873,-13.127],[81.663,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[77.869,-7.302],[78.956,-11.609],[81.684,-12.86],[85.068,-10.235],[85.437,-7.589],[84.432,-3.343],[81.663,-1.969],[78.977,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"o","np":5,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[91.007,0],[94.001,0],[94.001,-12.306],[99.744,0],[104.113,0],[104.113,-14.829],[101.159,-14.829],[101.159,-3.159],[95.601,-14.829],[91.007,-14.829]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"n","np":3,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.893,0],[109.497,0],[109.497,-2.728],[106.893,-2.728]],"c":true},"ix":2},"nm":".","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":".","np":3,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.241,0],[0,-4.697],[-5.107,0],[-1.313,1.354],[-0.062,0.882],[0,0],[1.333,0],[0,0.882],[-2.359,0],[-0.062,-0.513]],"o":[[0,-2.954],[-4.164,0],[0,3.671],[1.354,0],[1.19,-1.231],[0,0],[-0.062,1.969],[-3.097,0],[0,-3.056],[2.154,0],[0,0]],"v":[[124.04,-9.989],[118.523,-14.911],[111.734,-7.097],[118.502,0.349],[122.83,-1.313],[124.163,-4.799],[120.82,-4.799],[118.154,-1.99],[115.057,-7.076],[118.4,-12.593],[120.8,-9.989]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c","np":3,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[125.482,-7.199],[127.308,-1.661],[132.558,0.369],[137.829,-1.743],[139.696,-7.548],[137.809,-13.127],[132.599,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[128.805,-7.302],[129.892,-11.609],[132.62,-12.86],[136.004,-10.235],[136.373,-7.589],[135.368,-3.343],[132.599,-1.969],[129.912,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"o","np":5,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[141.696,0],[144.67,0],[144.67,-12.716],[148.629,0],[151.254,0],[155.295,-12.716],[155.295,0],[158.453,0],[158.453,-14.829],[153.408,-14.829],[150.024,-4.041],[146.885,-14.829],[141.696,-14.829]],"c":true},"ix":2},"nm":"m","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"m","np":3,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":10,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Color & Stroke Change","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Primary","np":3,"mn":"ADBE Color Control","ix":1,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.071,0.075,0.192],"ix":1}}]},{"ty":5,"nm":"Secondary","np":3,"mn":"ADBE Color Control","ix":2,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.733,0.941,0.275],"ix":1}}]},{"ty":5,"nm":"Stroke","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":70,"ix":1}}]},{"ty":5,"nm":"Scale","np":3,"mn":"ADBE Slider Control","ix":4,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1}}]},{"ty":5,"nm":"Axis","np":3,"mn":"ADBE Point Control","ix":5,"en":1,"ef":[{"ty":3,"nm":"Point","mn":"ADBE Point Control-0001","ix":1,"v":{"a":0,"k":[250,250],"ix":1}}]}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":3,"nm":"NULL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Axis')('Point');"},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2,"x":"var $bm_rt;\nvar temp;\ntemp = thisComp.layer('Color & Stroke Change').effect('Scale')('Slider');\n$bm_rt = [\n temp,\n temp\n];"}},"ao":0,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"outline 11","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-113.435],[113.435,0],[0,113.435],[-113.435,0]],"o":[[0,113.435],[-113.435,0],[0,-113.435],[113.435,0]],"v":[[205.393,0],[0,205.393],[-205.393,0],[0,-205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[25]},{"t":27,"s":[0]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":19,"op":139,"st":19,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"outline 10","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-113.435],[113.435,0],[0,113.435],[-113.435,0]],"o":[[0,113.435],[-113.435,0],[0,-113.435],[113.435,0]],"v":[[205.393,0],[0,205.393],[-205.393,0],[0,-205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[25]},{"t":27,"s":[0]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":19,"op":139,"st":19,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"outline 9","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-113.435],[113.435,0],[0,113.435],[-113.435,0]],"o":[[0,113.435],[-113.435,0],[0,-113.435],[113.435,0]],"v":[[205.393,0],[0,205.393],[-205.393,0],[0,-205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[25]},{"t":27,"s":[0]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":19,"op":139,"st":19,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"outline 8","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-113.435],[113.435,0],[0,113.435],[-113.435,0]],"o":[[0,113.435],[-113.435,0],[0,-113.435],[113.435,0]],"v":[[205.393,0],[0,205.393],[-205.393,0],[0,-205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[25]},{"t":27,"s":[0]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":19,"op":139,"st":19,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"outline 4","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,113.435],[113.435,0],[0,-113.435],[-113.435,0]],"o":[[0,-113.435],[-113.435,0],[0,113.435],[113.435,0]],"v":[[205.393,0],[0,-205.393],[-205.393,0],[0,205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[6]},{"t":7,"s":[25]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"outline 3","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,113.435],[113.435,0],[0,-113.435],[-113.435,0]],"o":[[0,-113.435],[-113.435,0],[0,113.435],[113.435,0]],"v":[[205.393,0],[0,-205.393],[-205.393,0],[0,205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[6]},{"t":7,"s":[25]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"outline 2","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,113.435],[113.435,0],[0,-113.435],[-113.435,0]],"o":[[0,-113.435],[-113.435,0],[0,113.435],[113.435,0]],"v":[[205.393,0],[0,-205.393],[-205.393,0],[0,205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[6]},{"t":7,"s":[25]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"outline","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,113.435],[113.435,0],[0,-113.435],[-113.435,0]],"o":[[0,-113.435],[-113.435,0],[0,113.435],[113.435,0]],"v":[[205.393,0],[0,-205.393],[-205.393,0],[0,205.393]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.070588238537,0.074509806931,0.192156866193,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5,"x":"var $bm_rt;\n$bm_rt = $bm_mul(20 / 100, thisComp.layer('Color & Stroke Change').effect('Stroke')('Slider'));"},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[6]},{"t":7,"s":[25]}],"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":0,"k":-41,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":8,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"Plus","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45.892,"ix":10},"p":{"a":0,"k":[251.612,252.016,0],"ix":2,"l":2},"a":{"a":0,"k":[250,250,0],"ix":1,"l":2},"s":{"a":0,"k":[89,89,100],"ix":6,"l":2}},"ao":0,"w":500,"h":500,"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} diff --git a/gsf/assets/lottie/confetti.json b/gsf/assets/lottie/confetti.json new file mode 100644 index 0000000..8dccc18 --- /dev/null +++ b/gsf/assets/lottie/confetti.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":166,"w":500,"h":500,"nm":"1103-confetti-flat","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"watermark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11,"x":"var $bm_rt;\nvar checkbox = thisComp.layer('02092020').effect('02092020002')('Checkbox');\nif (checkbox == 1) {\n $bm_rt = 20;\n} else {\n $bm_rt = 0;\n}\n;"},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.934,481.369,0],"ix":2,"l":2},"a":{"a":0,"k":[79.934,0.369,0],"ix":1,"l":2},"s":{"a":0,"k":[265.159,265.159,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.415,0],[11.014,0],[11.014,-2.523],[4.656,-2.523],[4.656,-14.809],[1.415,-14.809]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[11.167,-7.199],[12.992,-1.661],[18.243,0.369],[23.514,-1.743],[25.381,-7.548],[23.494,-13.127],[18.284,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[14.49,-7.302],[15.577,-11.609],[18.305,-12.86],[21.689,-10.235],[22.058,-7.589],[21.053,-3.343],[18.284,-1.969],[15.597,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-0.287,-0.841],[-0.144,-0.82],[0,0],[0.164,0.656],[0.226,1.743],[2.236,0.205],[0,2.769],[0.923,0.8],[1.641,-0.021],[0,0]],"o":[[0,0],[0,0],[0,0],[0.533,0],[0.205,0.574],[0,0],[-0.164,-0.246],[-0.103,-0.41],[-0.267,-1.928],[0.718,-0.205],[0,-0.964],[-1.19,-1.026],[0,0],[0,0]],"v":[[27.381,0],[30.622,0],[30.622,-5.989],[33.411,-5.989],[35.011,-5.148],[35.811,0],[39.318,0],[38.867,-1.067],[38.416,-3.938],[35.749,-7.343],[38.847,-10.973],[37.554,-13.824],[33.063,-14.829],[27.381,-14.829]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.492,-0.349],[0,-1.005],[0.226,-0.164],[0.369,0],[0,0]],"o":[[0,0],[1.005,0],[0.287,0.185],[0,1.046],[-0.513,0.41],[0,0],[0,0]],"v":[[30.519,-12.491],[32.652,-12.491],[34.744,-12.142],[35.524,-10.481],[34.703,-8.758],[33.083,-8.348],[30.519,-8.348]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.554,0.103],[0,4.553],[1.866,1.374],[0.82,0],[0,0]],"o":[[0,0],[1.497,0],[2.81,-0.513],[0,-2.113],[-1.784,-1.313],[0,0],[0,0]],"v":[[41.068,0],[45.683,0],[48.349,-0.164],[53.6,-7.609],[51.077,-13.434],[45.97,-14.768],[41.068,-14.788]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[0,0],[-0.656,-0.185],[0,-2.092],[1.251,-1.251],[1.354,0],[0.349,0.021]],"o":[[1.825,-0.082],[1.99,0.554],[0,0.718],[-0.923,0.923],[-0.369,0],[0,0]],"v":[[44.288,-12.388],[47.611,-12.183],[50.318,-7.609],[48.985,-3.425],[45.539,-2.4],[44.288,-2.441]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[55.669,0],[58.849,0],[58.849,-14.87],[55.669,-14.87]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":8,"ty":"sh","ix":9,"ks":{"a":0,"k":{"i":[[0,0],[3.241,0],[0,-4.697],[-5.107,0],[-1.313,1.354],[-0.062,0.882],[0,0],[1.333,0],[0,0.882],[-2.359,0],[-0.062,-0.513]],"o":[[0,-2.954],[-4.164,0],[0,3.671],[1.354,0],[1.19,-1.231],[0,0],[-0.062,1.969],[-3.097,0],[0,-3.056],[2.154,0],[0,0]],"v":[[73.104,-9.989],[67.587,-14.911],[60.798,-7.097],[67.566,0.349],[71.894,-1.313],[73.227,-4.799],[69.884,-4.799],[67.218,-1.99],[64.121,-7.076],[67.464,-12.593],[69.864,-9.989]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false},{"ind":9,"ty":"sh","ix":10,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[74.546,-7.199],[76.372,-1.661],[81.622,0.369],[86.894,-1.743],[88.76,-7.548],[86.873,-13.127],[81.663,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":10,"ty":"sh","ix":11,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[77.869,-7.302],[78.956,-11.609],[81.684,-12.86],[85.068,-10.235],[85.437,-7.589],[84.432,-3.343],[81.663,-1.969],[78.977,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":11,"ty":"sh","ix":12,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[91.007,0],[94.001,0],[94.001,-12.306],[99.744,0],[104.113,0],[104.113,-14.829],[101.159,-14.829],[101.159,-3.159],[95.601,-14.829],[91.007,-14.829]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false},{"ind":12,"ty":"sh","ix":13,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.893,0],[109.497,0],[109.497,-2.728],[106.893,-2.728]],"c":true},"ix":2},"nm":".","mn":"ADBE Vector Shape - Group","hd":false},{"ind":13,"ty":"sh","ix":14,"ks":{"a":0,"k":{"i":[[0,0],[3.241,0],[0,-4.697],[-5.107,0],[-1.313,1.354],[-0.062,0.882],[0,0],[1.333,0],[0,0.882],[-2.359,0],[-0.062,-0.513]],"o":[[0,-2.954],[-4.164,0],[0,3.671],[1.354,0],[1.19,-1.231],[0,0],[-0.062,1.969],[-3.097,0],[0,-3.056],[2.154,0],[0,0]],"v":[[124.04,-9.989],[118.523,-14.911],[111.734,-7.097],[118.502,0.349],[122.83,-1.313],[124.163,-4.799],[120.82,-4.799],[118.154,-1.99],[115.057,-7.076],[118.4,-12.593],[120.8,-9.989]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false},{"ind":14,"ty":"sh","ix":15,"ks":{"a":0,"k":{"i":[[0,-3.938],[-1.62,-1.723],[-1.949,0],[-1.641,1.846],[0,2.154],[1.579,1.805],[1.579,0]],"o":[[0,1.354],[1.354,1.415],[1.231,0],[1.21,-1.354],[0,-1.456],[-1.456,-1.641],[-5.333,0]],"v":[[125.482,-7.199],[127.308,-1.661],[132.558,0.369],[137.829,-1.743],[139.696,-7.548],[137.809,-13.127],[132.599,-15.137]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":15,"ty":"sh","ix":16,"ks":{"a":0,"k":{"i":[[0,1.415],[-0.841,1.026],[-1.19,0],[-0.615,-1.825],[0,-0.718],[0.492,-0.738],[1.292,0],[0.451,0.615]],"o":[[0,-1.682],[0.595,-0.759],[1.518,0],[0.308,0.902],[0,2.359],[-0.595,0.923],[-1.477,0],[-0.882,-1.149]],"v":[[128.805,-7.302],[129.892,-11.609],[132.62,-12.86],[136.004,-10.235],[136.373,-7.589],[135.368,-3.343],[132.599,-1.969],[129.912,-3.159]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":16,"ty":"sh","ix":17,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[141.696,0],[144.67,0],[144.67,-12.716],[148.629,0],[151.254,0],[155.295,-12.716],[155.295,0],[158.453,0],[158.453,-14.829],[153.408,-14.829],[150.024,-4.041],[146.885,-14.829],[141.696,-14.829]],"c":true},"ix":2},"nm":"m","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":2.5,"op":25,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"02092020","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-105,15,0],"ix":2,"l":2},"a":{"a":0,"k":[60,60,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"02092020002","np":3,"mn":"ADBE Checkbox Control","ix":1,"en":1,"ef":[{"ty":7,"nm":"Checkbox","mn":"ADBE Checkbox Control-0001","ix":1,"v":{"a":0,"k":0,"ix":1}}]}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Color & Stroke Change","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2,"x":"var $bm_rt;\n$bm_rt = effect('Axis')('Point');"},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2,"x":"var $bm_rt;\nvar temp;\ntemp = effect('Scale')('Slider');\n$bm_rt = [\n temp,\n temp\n];"}},"ao":0,"ef":[{"ty":5,"nm":"Axis","np":3,"mn":"ADBE Point Control","ix":1,"en":1,"ef":[{"ty":3,"nm":"Point","mn":"ADBE Point Control-0001","ix":1,"v":{"a":0,"k":[250,250],"ix":1}}]},{"ty":5,"nm":"Scale","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1}}]},{"ty":5,"nm":"Primary","np":3,"mn":"ADBE Color Control","ix":3,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.733,0.941,0.275],"ix":1}}]},{"ty":5,"nm":"Secondary","np":3,"mn":"ADBE Color Control","ix":4,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.949,0.545,0.659],"ix":1}}]},{"ty":5,"nm":"Tertiary","np":3,"mn":"ADBE Color Control","ix":5,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.329,0.329,0.329],"ix":1}}]},{"ty":5,"nm":"Quaternary","np":3,"mn":"ADBE Color Control","ix":6,"en":1,"ef":[{"ty":2,"nm":"Color","mn":"ADBE Color Control-0001","ix":1,"v":{"a":0,"k":[0.949,0.298,0],"ix":1}}]}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"small-confetti—16","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":61,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-123]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[30.317,40.186,0],"to":[18.417,-7.833,0],"ti":[-18.417,7.833,0]},{"t":120,"s":[140.817,-6.814,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1.929,6.852],[-1.929,-6.852]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.780392156863,0.219607843137,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"small-confetti—15","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":63,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-81]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[-51.411,3.17,0],"to":[-10.917,-12.583,0],"ti":[10.917,12.583,0]},{"t":120,"s":[-116.911,-72.33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-5.396,-4.643],[5.396,4.643]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.780392156863,0.219607843137,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"small-confetti—14","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":67,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-243]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[-18.644,94.971,0],"to":[3.833,8.167,0],"ti":[-3.833,-8.167,0]},{"t":120,"s":[4.356,143.971,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.569,6.639],[-2.569,-6.639]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"small-confetti—13","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":61,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-40]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[14.08,35.3,0],"to":[18.667,-28.167,0],"ti":[-18.667,28.167,0]},{"t":120,"s":[126.08,-133.7,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[5.034,5.034],[-5.034,-5.034]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156862745,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"small-confetti—12","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":67,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[126]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[-76.584,15.423,0],"to":[-11.417,-0.25,0],"ti":[11.417,0.25,0]},{"t":120,"s":[-145.084,13.923,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-5.034,5.034],[5.034,-5.034]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156862745,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"small-confetti—11","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":62,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-232]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[55.481,65.473,0],"to":[17.833,1.5,0],"ti":[-17.833,-1.5,0]},{"t":120,"s":[162.481,74.473,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-3.639,6.119],[3.639,-6.119]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"small-confetti—10","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":62,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[82]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[15.339,96.436,0],"to":[15.167,8.25,0],"ti":[-15.167,-8.25,0]},{"t":120,"s":[106.339,145.936,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[7.648,-4.641],[-7.648,4.641]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156922583,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"small-confetti—9","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":59,"s":[0],"h":1},{"t":61,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[36]},{"t":120,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":59,"s":[-47.675,-4.301,0],"to":[3.75,-24,0],"ti":[-3.75,24,0]},{"t":120,"s":[-25.175,-148.301,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-3.639,6.119],[3.639,-6.119]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":844,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"small-confetti—8","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[100]},{"t":50,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":50,"s":[176]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[140.817,-6.814,0],"to":[14.5,-10.667,0],"ti":[-14.5,10.667,0]},{"t":50,"s":[227.817,-70.814,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1.929,6.852],[-1.929,-6.852]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.780392156863,0.219607843137,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"small-confetti—7","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[100]},{"t":59,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":59,"s":[139]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[-116.911,-72.33,0],"to":[-15.5,-17.333,0],"ti":[15.5,17.333,0]},{"t":59,"s":[-209.911,-176.33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-5.396,-4.643],[5.396,4.643]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.780392156863,0.219607843137,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"small-confetti—6","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[100]},{"t":55,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":55,"s":[463]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[4.356,143.971,0],"to":[6.833,14.667,0],"ti":[-6.833,-14.667,0]},{"t":55,"s":[45.356,231.971,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.569,6.639],[-2.569,-6.639]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019667682,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"small-confetti—5","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":53,"s":[100]},{"t":70,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":70,"s":[450]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[126.08,-133.7,0],"to":[12,-15.833,0],"ti":[-12,15.833,0]},{"t":70,"s":[198.08,-228.7,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[5.034,5.034],[-5.034,-5.034]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156862745,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"small-confetti—4","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[100]},{"t":37,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":37,"s":[179]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[-145.084,13.923,0],"to":[-15.5,15.5,0],"ti":[15.5,-15.5,0]},{"t":37,"s":[-238.084,106.923,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-5.034,5.034],[5.034,-5.034]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156862745,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"small-confetti—3","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[100]},{"t":48,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":48,"s":[107]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[162.481,74.473,0],"to":[13.167,-1.333,0],"ti":[-13.167,1.333,0]},{"t":48,"s":[241.481,66.473,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-3.639,6.119],[3.639,-6.119]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019667682,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"small-confetti—2","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[100]},{"t":55,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":55,"s":[-214]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[106.339,145.936,0],"to":[15.167,8.5,0],"ti":[-15.167,-8.5,0]},{"t":55,"s":[197.339,196.936,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[7.648,-4.641],[-7.648,4.641]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.701960784314,0.992156862745,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"small-confetti—1","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[100]},{"t":62,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":62,"s":[-344]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[-25.175,-148.301,0],"to":[-0.5,-13.667,0],"ti":[0.5,13.667,0]},{"t":62,"s":[-28.175,-230.301,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-3.639,6.119],[3.639,-6.119]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019667682,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":92,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":3,"nm":"Front-cup","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":59,"s":[-15]},{"i":{"x":[0.317],"y":[1]},"o":{"x":[0.114],"y":[0]},"t":95,"s":[6]},{"t":165,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[-47.848,58.315,0],"to":[3.833,-1.167,0],"ti":[-4.75,2.5,0]},{"i":{"x":0.213,"y":1},"o":{"x":0.333,"y":0},"t":58,"s":[-24.848,51.315,0],"to":[-4.291,4.987,0],"ti":[7.502,-2.88,0]},{"i":{"x":0.448,"y":1},"o":{"x":0.333,"y":0},"t":83,"s":[-113.545,105.848,0],"to":[-0.584,0.224,0],"ti":[-10.95,7.922,0]},{"t":165,"s":[-47.848,58.315,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Confetti-2","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":45,"s":[100],"h":1},{"t":60,"s":[0],"h":1},{"t":65,"s":[100],"h":1}],"ix":11},"r":{"a":0,"k":44,"ix":10},"p":{"a":0,"k":[82.862,-39.979,0],"ix":2,"l":2},"a":{"a":1,"k":[{"t":58,"s":[0,0,0],"h":1},{"i":{"x":0.21,"y":1},"o":{"x":0.167,"y":0.167},"t":62,"s":[0,-48,0],"to":[0,0,0],"ti":[0,-8,0]},{"t":118,"s":[0,0,0]}],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.534,-14.606],[-0.534,-14.608],[0,0],[-0.534,-14.606],[-0.534,-14.608],[-0.534,-14.608],[0,0],[-0.534,-14.608],[-0.534,-14.608]],"o":[[0.534,14.606],[0.534,14.608],[0,0],[0.534,14.606],[0.534,14.608],[0.534,14.608],[0,0],[0.534,14.608],[0.534,14.608],[0,0]],"v":[[8.502,-102.511],[-15.046,-72.399],[10.637,-44.083],[10.549,-43.886],[-12.999,-13.774],[12.684,14.542],[-10.864,44.657],[-10.864,44.657],[15.046,72.395],[-8.502,102.511]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.79],"y":[0]},"t":0,"s":[29]},{"t":58,"s":[0],"h":1},{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[100]},{"t":118,"s":[29]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.79],"y":[0]},"t":0,"s":[72]},{"t":58,"s":[0],"h":1},{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[100]},{"t":118,"s":[72]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Confetti-1","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":44,"s":[100],"h":1},{"t":59,"s":[0],"h":1},{"t":64,"s":[100],"h":1}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[22]},{"t":141,"s":[0]}],"ix":10},"p":{"a":0,"k":[27.862,-100.979,0],"ix":2,"l":2},"a":{"a":1,"k":[{"t":58,"s":[0,0,0],"h":1},{"i":{"x":0.21,"y":1},"o":{"x":0.167,"y":0.167},"t":62,"s":[0,-48,0],"to":[0,0,0],"ti":[0,-8,0]},{"t":109,"s":[0,0,0]}],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.534,-14.606],[-0.534,-14.608],[0,0],[-0.534,-14.606],[-0.534,-14.608],[-0.534,-14.608],[0,0],[-0.534,-14.608],[-0.534,-14.608]],"o":[[0.534,14.606],[0.534,14.608],[0,0],[0.534,14.606],[0.534,14.608],[0.534,14.608],[0,0],[0.534,14.608],[0.534,14.608],[0,0]],"v":[[8.502,-102.511],[-15.046,-72.399],[10.637,-44.083],[10.549,-43.886],[-12.999,-13.774],[12.684,14.542],[-10.864,44.657],[-10.864,44.657],[15.046,72.395],[-8.502,102.511]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.79],"y":[0]},"t":0,"s":[29]},{"t":58,"s":[0],"h":1},{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[100]},{"t":109,"s":[29]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.79],"y":[0]},"t":0,"s":[72]},{"t":58,"s":[0],"h":1},{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[100]},{"t":109,"s":[72]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.545098039216,0.658823529412,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Secondary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Warstwa 6","parent":20,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-0.313,"ix":10},"p":{"a":0,"k":[0.582,-1.855,0],"ix":2,"l":2},"a":{"a":0,"k":[194.802,304.812,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.889,5.105],[0,0],[0,0],[-4.985,-6.399]],"o":[[-4.844,-5.593],[0,0],[0,0],[3.323,5.346],[0,0]],"v":[[-0.887,28.627],[-14.025,12.505],[-3.051,-16.571],[1.496,-28.627],[14.025,-10.893]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.29411765933,0.701960802078,0.992156863213,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[145.668,282.354],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":1,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.651,0.651],[3.769,4.066],[0,0],[0,0],[0,0],[0,0],[-4.822,-5.133],[0,0],[0,0]],"o":[[-0.658,-0.643],[-4.136,-4.136],[0,0],[0,0],[0,0],[0,0],[4.172,4.907],[0,0],[0,0],[0,0]],"v":[[-0.255,26.545],[-2.213,24.6],[-14.086,12.275],[-7.043,-6.406],[-6.371,-8.181],[-0.424,-23.928],[0.566,-26.545],[14.086,-11.455],[11.872,-5.579],[11.229,-3.889]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.29411765933,0.701960802078,0.992156863213,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[116.1,361.115],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":1,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.757,19.757],[9.129,14.701],[0,0],[0,0],[-13.555,-13.555],[-11.83,-8.987],[0,0],[0,0]],"o":[[-19.749,-19.749],[0,0],[0,0],[8.987,11.83],[13.562,13.562],[0,0],[0,0],[-14.708,-9.122]],"v":[[3.2,-3.21],[-41.603,-57.12],[-46.149,-45.064],[-57.124,-15.988],[-22.829,22.818],[15.984,57.12],[45.06,46.146],[57.124,41.592]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.29411765933,0.701960802078,0.992156863213,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.766,310.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.549,8.549],[6.873,8.075],[0,0],[0,0],[0,0],[0,0],[-4.137,-4.137],[-4.073,-3.776],[0,0],[0,0],[0,0],[0,0]],"o":[[-8.549,-8.549],[0,0],[0,0],[0,0],[0,0],[3.769,4.066],[4.136,4.136],[0,0],[0,0],[0,0],[0,0],[-8.082,-6.88]],"v":[[6.385,-6.396],[-16.864,-31.512],[-17.854,-28.896],[-23.801,-13.148],[-24.473,-11.374],[-31.516,7.308],[-19.643,19.633],[-7.312,31.512],[11.017,24.597],[13.428,23.685],[28.892,17.851],[31.516,16.868]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.29411765933,0.701960802078,0.992156863213,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Primary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.527,366.079],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.551,-1.428],[0,0],[0.057,4.568],[-0.332,0.884],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-6.767,-10.345],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[-4.759,1.803],[-0.007,-0.856],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.177,4.886],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.629,1.662]],"v":[[-21.892,95.818],[-31.883,99.587],[-41.373,93.181],[-40.899,90.571],[-31.699,66.183],[-24.657,47.501],[-23.985,45.726],[-17.232,27.829],[-17.048,27.363],[-17.055,27.356],[-14.814,21.437],[-14.821,21.43],[-14.814,21.423],[-2.072,-12.348],[13.456,-53.474],[13.45,-53.481],[31.035,-100.058],[41.373,-76.525],[25.979,-35.746],[11.066,3.774],[2.998,25.15],[2.991,25.157],[-3.535,42.445],[-5.749,48.321],[-6.392,50.012],[-17.868,80.453],[-21.878,91.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.780392169952,0.219607844949,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.721,307.213],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":1,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-18.448,-18.448],[-11.625,0.467],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.057,4.568],[-0.332,0.884],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.021,0.177],[-0.021,0.148],[0,0.014],[-0.007,0.007],[-0.042,0.141],[-0.043,0.141],[-0.014,0.014],[-0.064,0.12],[0.085,-0.495],[0.014,-0.368],[0,0],[-6.767,-10.345]],"o":[[31.806,31.806],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.759,1.803],[-0.014,-0.849],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.014,-0.184],[0.014,-0.155],[0,-0.014],[0,-0.014],[0.028,-0.156],[0.035,-0.149],[0.007,-0.021],[0.049,-0.134],[-0.191,0.403],[-0.057,0.325],[0,0],[-0.177,4.886],[9.348,14.298]],"v":[[25.58,-24.376],[100.067,28.855],[53.476,46.441],[41.412,50.995],[12.336,61.969],[-21.011,74.555],[-21.025,74.555],[-27.368,76.952],[-29.991,77.935],[-45.449,83.776],[-47.86,84.688],[-80.585,97.034],[-90.576,100.803],[-100.066,94.397],[-99.599,91.78],[-90.392,67.399],[-90.4,67.392],[-83.35,48.718],[-82.678,46.943],[-76.738,31.188],[-75.925,29.046],[-75.748,28.572],[-73.514,22.647],[-73.514,22.632],[-60.765,-11.132],[-60.772,-11.139],[-49.797,-40.215],[-45.244,-52.264],[-45.251,-52.272],[-27.658,-98.87],[-27.651,-98.891],[-27.609,-99.429],[-27.545,-99.888],[-27.538,-99.937],[-27.531,-99.973],[-27.425,-100.418],[-27.297,-100.843],[-27.276,-100.892],[-27.106,-101.274],[-27.531,-99.93],[-27.644,-98.884],[-27.658,-98.841],[-17.32,-75.309]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.780392169952,0.219607844949,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.414,305.997],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[192.414,305.997],"ix":2},"a":{"a":0,"k":[192.414,305.997],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":6,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Confetti-3","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":44,"s":[100],"h":1},{"t":59,"s":[0],"h":1},{"t":66,"s":[100],"h":1}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[56.582,105.237,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-30.129,22.077],[-5.745,-68.014],[40.651,6.94],[-38.411,-29.291]],"o":[[0,0],[31.985,-23.437],[4.449,52.672],[-36.11,-6.165],[12.034,9.177]],"v":[[-130.082,4.263],[-60.453,-58.314],[59.815,-12.161],[4.748,72.396],[25.088,29.196]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.298039215686,0,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Quaternary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[17.5]},{"t":48,"s":[100],"h":1},{"i":{"x":[0.739],"y":[0.937]},"o":{"x":[0.435],"y":[0.032]},"t":62,"s":[0]},{"i":{"x":[0.099],"y":[1]},"o":{"x":[0.09],"y":[-1.452]},"t":66,"s":[15.21]},{"t":131,"s":[11.5]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[53]},{"t":48,"s":[100],"h":1},{"i":{"x":[0.739],"y":[0.86]},"o":{"x":[0.435],"y":[0.07]},"t":62,"s":[0]},{"i":{"x":[0.099],"y":[1]},"o":{"x":[0.09],"y":[0.444]},"t":66,"s":[19.164]},{"t":131,"s":[53]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Confetti-4","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"t":44,"s":[100],"h":1},{"t":59,"s":[0],"h":1},{"t":66,"s":[100],"h":1}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-120.635,-90.959,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-27.335,47.563],[91.745,-25.291],[-28.328,40.721],[24.22,-24.571],[-17.615,7.486]],"o":[[0,0],[27.335,-47.563],[-66.038,18.205],[21.138,-30.385],[-21.816,22.132],[6.699,-2.847]],"v":[[24.635,167.459],[84.4,111.806],[-11.373,-38.493],[-84.017,-100.435],[-37.338,-68.818],[-58.035,-81.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[12]},{"t":59,"s":[100],"h":1},{"i":{"x":[0.71],"y":[0.956]},"o":{"x":[0.389],"y":[0.025]},"t":62,"s":[0]},{"i":{"x":[0.131],"y":[1]},"o":{"x":[0.116],"y":[-1.248]},"t":66,"s":[11.155]},{"t":147,"s":[8]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[53]},{"t":59,"s":[100],"h":1},{"i":{"x":[0.71],"y":[0.83]},"o":{"x":[0.389],"y":[0.096]},"t":62,"s":[0]},{"i":{"x":[0.131],"y":[1]},"o":{"x":[0.116],"y":[0.324]},"t":66,"s":[10.079]},{"t":147,"s":[53]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.949019607843,0.298039215686,0,1],"ix":3,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Quaternary')('Color');"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Warstwa 7","parent":20,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-0.313,"ix":10},"p":{"a":0,"k":[0.582,-1.855,0],"ix":2,"l":2},"a":{"a":0,"k":[194.802,304.812,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.187,-7.187],[35.87,35.87],[-7.187,7.187],[-35.87,-35.87]],"o":[[-7.187,7.187],[-35.87,-35.87],[7.187,-7.187],[35.87,35.87]],"v":[[65.985,63.913],[-33.438,33.438],[-63.913,-65.985],[14.049,-14.049]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.780392169952,0.219607844949,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.780392169952,0.219607844949,1],"ix":4,"x":"var $bm_rt;\n$bm_rt = comp('1103-confetti-flat').layer('Color & Stroke Change').effect('Tertiary')('Color');"},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[229.968,269.641],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":844,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/gsf/assets/lottie/no-data-found.json b/gsf/assets/lottie/no-data-found.json new file mode 100644 index 0000000..859b3d4 --- /dev/null +++ b/gsf/assets/lottie/no-data-found.json @@ -0,0 +1 @@ +{"nm":"Pre-comp 2","ddd":0,"h":690,"w":620,"meta":{"g":"@lottiefiles/toolkit-js 0.26.1"},"layers":[{"ty":4,"nm":"bottom_right 3","sr":1,"st":0,"op":90,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[97.496,-65.355,0],"ix":1},"s":{"a":0,"k":[117.486,89.612,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[211.343,208.143,0],"t":0,"ti":[0,-30,0],"to":[0,36.6666679382324,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[211.343,428.143,0],"t":15,"ti":[0,6.66666650772095,0],"to":[0,30,0]},{"s":[211.343,388.143,0],"t":19}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"s":[100],"t":15}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":3,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.25,0.643],[9.638,27.694],[-0.545,1.799],[-2.253,0.087],[-49.028,-1.083],[-2.41,-2.312],[-1.521,-3.891],[-8.485,-26.666],[1.229,0.008],[53.092,-0.118]],"o":[[-10.659,-27.407],[-0.62,-1.781],[0.577,-1.904],[48.997,-1.881],[3.579,0.079],[3.17,3.04],[10.237,26.193],[0.329,1.034],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-14.216,-147.833],[-15.21,-153.348],[-11.12,-158.055],[136.006,-159.153],[145.395,-154.598],[152.084,-143.734],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":15},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.424,0.569],[15.558,22.754],[-0.549,0.524],[-1.831,0.039],[-48.815,-0.529],[-2.518,-1.52],[-1.695,-2.278],[-14.928,-21.952],[1.229,0.008],[53.092,-0.118]],"o":[[-16.558,-22.209],[-0.417,-0.61],[1.236,-1.18],[48.804,-1.038],[3.061,0.033],[2.559,1.544],[15.934,21.406],[0.628,0.923],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-32.223,-132.662],[-32.193,-134.793],[-27.451,-137.218],[119.002,-138.009],[127.738,-135.536],[133.603,-129.197],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":17},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.755,0.163],[22.491,4.893],[-0.583,-0.1],[-1.798,0.007],[-48.594,0.029],[-2.65,-0.445],[-1.767,-0.37],[-22.306,-4.387],[1.229,0.008],[53.092,-0.118]],"o":[[-22.5,-4.861],[-0.577,-0.125],[1.764,0.304],[48.593,-0.202],[2.699,-0.002],[1.785,0.3],[22.233,4.66],[1.199,0.236],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-51.645,-80.621],[-50.591,-79.366],[-45.198,-79.511],[100.583,-79.994],[108.666,-79.602],[113.707,-77.789],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":19},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.247,-0.644],[6.169,-21.714],[-1.621,-1.738],[-2.463,-0.053],[-48.247,0.874],[-2.012,1.421],[-0.72,1.893],[-6.492,22.149],[1.229,0.008],[53.092,-0.118]],"o":[[-8.129,21.216],[-0.618,2.176],[1.556,1.668],[48.242,1.039],[2.587,-0.047],[1.776,-1.254],[8.252,-21.697],[0.305,-1.04],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-7.072,-0.833],[-4.48,5.499],[1.889,8.776],[146.661,8.755],[153.766,6.024],[157.571,1.048],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":24},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.209,-0.654],[5.451,-24.026],[-1.771,-2.15],[-2.692,-0.074],[-48.163,1.073],[-1.776,1.712],[-0.734,2.328],[-5.933,24.38],[1.229,0.008],[53.092,-0.118]],"o":[[-7.558,23.588],[-0.59,2.598],[1.573,1.909],[48.155,1.326],[2.644,-0.059],[1.856,-1.789],[7.579,-24.03],[0.256,-1.05],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-5.266,6.219],[-2.315,13.736],[4.282,17.811],[148.818,17.898],[155.694,14.438],[159.211,7.879],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":26},{"s":[{"c":true,"i":[[-0.148,-0.667],[-8.331,-32.489],[-1.771,-2.15],[-2.692,-0.074],[-48.163,1.073],[-1.776,1.712],[0.45,2.382],[8.874,32.748],[1.229,0.008],[53.092,-0.118]],"o":[[7.251,32.686],[0.663,2.585],[1.573,1.909],[48.155,1.326],[2.644,-0.059],[1.856,-1.789],[-6.275,-33.203],[-0.283,-1.045],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[39.561,32.675],[42.512,40.192],[49.109,44.267],[193.645,44.354],[200.521,40.894],[204.038,34.335],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":29}],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7333,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[91.803,91.525],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[13.186,-121.197],"ix":2},"r":{"a":0,"k":36.852,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"bottom_right 2","sr":1,"st":0,"op":90,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[97.496,-65.355,0],"ix":1},"s":{"a":0,"k":[98.474,89.612,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[239.343,81.393,0],"t":0,"ti":[0,-30,0],"to":[0,36.6666679382324,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[239.343,301.393,0],"t":15,"ti":[0,6.66666650772095,0],"to":[0,30,0]},{"s":[239.343,261.393,0],"t":19}],"ix":2},"r":{"a":0,"k":149.892,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"s":[100],"t":15}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":3,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.669,0.345],[13.132,7.662],[2.349,2.068],[-2.927,0.191],[-50.571,-0.547],[-6.093,-2.696],[-4.316,-2.999],[-10.975,-8.181],[1.229,0.008],[53.092,-0.118]],"o":[[-13.598,-7.014],[-2.773,-1.618],[-2.067,-1.82],[50.434,-3.288],[6.83,0.074],[4.92,2.177],[11.291,7.846],[0.935,0.697],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-24.326,-87.334],[-32.133,-92.799],[-37.475,-98.911],[114.198,-102.339],[133.777,-97.06],[146.651,-87.982],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":15},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.747,0.188],[12.353,3.718],[3.201,1.325],[-2.289,0.161],[-51.584,1.049],[-5.74,-1.85],[-5.003,-2.301],[-10.051,-5.077],[1.229,0.008],[53.092,-0.118]],"o":[[-12.557,-3.155],[-3.35,-1.008],[-2.075,-0.859],[51.43,-3.628],[6.117,-0.124],[5.305,1.71],[10.274,4.724],[1.064,0.537],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-21.74,-75.551],[-31.537,-79.151],[-37.545,-82.094],[117.008,-89.63],[134.773,-85.599],[149.964,-79.007],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":16},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.707,-0.283],[9.564,-3.731],[1.953,-1.212],[-3.397,-0.096],[-49.861,1.406],[-5.083,1.281],[-6.291,2.258],[-7.299,3.525],[1.229,0.008],[53.092,-0.118]],"o":[[-9.521,3.814],[-2.188,0.853],[-2.77,1.719],[49.86,1.408],[5.288,-0.149],[6.535,-1.647],[7.715,-2.769],[1.076,-0.519],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-12.916,-53.343],[-19.686,-51.237],[-26.711,-44.785],[122.922,-47.209],[138.586,-49.446],[157.584,-55.946],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":17},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.289,-0.63],[10.587,-24.925],[0.029,-1.947],[-2.074,-0.06],[-50.642,0.949],[-2.605,1.76],[-1.445,3.288],[-8.597,24.745],[1.229,0.008],[53.092,-0.118]],"o":[[-11.328,24.675],[-0.776,1.826],[-0.027,1.812],[50.625,1.473],[3.293,-0.062],[3.19,-2.155],[10.612,-24.141],[0.357,-1.027],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-16.787,9.609],[-18.533,15.249],[-16.949,20.506],[135.009,19.717],[144.552,17.48],[151.303,8.711],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":18},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.015,-0.679],[-0.933,-32.194],[-1.771,-2.15],[-2.692,-0.074],[-48.163,1.073],[-1.776,1.712],[-0.093,2.413],[1.011,32.595],[1.229,0.008],[53.092,-0.118]],"o":[[-0.71,32.199],[0.077,2.648],[1.573,1.909],[48.155,1.326],[2.644,-0.059],[1.856,-1.789],[1.258,-32.589],[-0.033,-1.073],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[15.61,31.635],[18.561,39.152],[25.158,43.227],[169.694,43.314],[176.57,39.854],[180.087,33.295],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":22},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[-0.367,-0.599],[-12.262,-18.403],[-2.375,-2.331],[-2.692,-0.074],[-48.163,1.073],[-1.429,1.944],[1.167,2.11],[12.725,18.474],[1.229,0.008],[53.092,-0.118]],"o":[[11.502,18.773],[1.797,2.697],[1.79,1.757],[48.155,1.326],[2.644,-0.059],[1.45,-1.972],[-10.733,-19.414],[-0.634,-0.92],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[52.062,-9.636],[57.718,-1.684],[64.315,2.39],[208.851,2.477],[215.727,-0.983],[216.538,-7.976],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":27},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[-0.773,-0.069],[-19.217,-1.218],[-4.041,-0.075],[-3.068,0.066],[-48.612,1.57],[-0.169,0.371],[0.533,-0.005],[20.288,-0.298],[1.229,0.008],[53.092,-0.118]],"o":[[19.169,1.705],[4.031,0.255],[3.068,0.057],[48.631,-1.041],[0.457,-0.015],[0.197,-0.433],[-20.29,0.171],[-1.229,0.018],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[73.139,-60.703],[85.264,-60.561],[94.465,-60.309],[240.345,-63.881],[240.721,-65.033],[241.436,-66.283],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":29},{"s":[{"c":true,"i":[[-0.777,-0.032],[-19.66,-0.5],[-4.041,-0.075],[-3.069,0.014],[-48.162,0.703],[-0.169,0.371],[0.533,-0.005],[20.288,-0.298],[1.229,0.008],[53.092,-0.118]],"o":[[19.646,0.801],[4.04,0.103],[3.068,0.057],[48.168,-0.223],[0.457,-0.007],[0.197,-0.433],[-20.29,0.171],[-1.229,0.018],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[74.516,-63.312],[86.641,-63.171],[95.842,-62.919],[240.345,-63.881],[240.721,-65.033],[241.436,-66.283],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":30}],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7333,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2},{"ty":4,"nm":"bottom_right","sr":1,"st":0,"op":90,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[97.496,-65.355,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[98.088,89.612,100],"t":15},{"s":[98.088,-94.196,100],"t":29}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[380.355,161.774,0],"t":0,"ti":[0,-30,0],"to":[0,36.6666679382324,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[380.355,381.774,0],"t":15,"ti":[0,6.66666650772095,0],"to":[0,30,0]},{"s":[380.355,341.774,0],"t":19}],"ix":2},"r":{"a":0,"k":-210.358,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"s":[100],"t":15}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":3,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[-0.109,-0.76],[-5.613,-30.321],[-1.711,-2.078],[-2.584,-0.071],[-48.167,1.073],[-1.847,1.781],[0.28,2.465],[6.015,30.617],[1.22,0.008],[53.092,-0.118]],"o":[[4.359,30.527],[0.49,2.647],[1.643,1.995],[48.16,1.326],[2.565,-0.057],[1.786,-1.722],[-3.518,-31.003],[-0.235,-1.197],[-53.09,-0.359],[-0.768,0.002]],"v":[[15.543,-64.979],[30.873,26.25],[33.824,33.768],[40.421,37.842],[184.957,37.929],[191.833,34.469],[195.35,27.91],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":15},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.518,-0.567],[23.77,-30.027],[-1.711,-2.078],[-2.584,-0.071],[-48.167,1.073],[-1.847,1.781],[-1.623,1.876],[-24.922,29.639],[1.22,0.008],[53.092,-0.118]],"o":[[-25.845,28.261],[-1.671,2.111],[1.643,1.995],[48.16,1.326],[2.565,-0.057],[1.786,-1.722],[25.334,-29.288],[0.785,-0.934],[-53.09,-0.359],[-0.768,0.002]],"v":[[15.543,-64.979],[-61.106,20.603],[-58.155,28.121],[-51.559,32.196],[92.977,32.283],[99.854,28.823],[103.37,22.263],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":19},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.277,-0.716],[14.523,-44.035],[-1.711,-2.078],[-2.584,-0.071],[-48.167,1.073],[-1.847,1.781],[-0.882,2.319],[-15.196,44.277],[1.22,0.008],[53.092,-0.118]],"o":[[-16.715,43.25],[-0.843,2.556],[1.643,1.995],[48.16,1.326],[2.565,-0.057],[1.786,-1.722],[16.636,-43.756],[0.396,-1.154],[-53.09,-0.359],[-0.768,0.002]],"v":[[15.543,-64.979],[-32.893,65.419],[-29.942,72.936],[-23.345,77.011],[121.191,77.098],[128.067,73.638],[131.584,67.079],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":25},{"s":[{"c":true,"i":[[0.037,-0.767],[-0.173,-31.248],[-1.711,-2.078],[-2.584,-0.071],[-48.167,1.073],[-1.847,1.781],[-0.158,2.476],[0.199,31.655],[1.22,0.008],[53.092,-0.118]],"o":[[-1.522,31.211],[0.015,2.692],[1.643,1.995],[48.16,1.326],[2.565,-0.057],[1.786,-1.722],[2.019,-31.591],[-0.008,-1.22],[-53.09,-0.359],[-0.768,0.002]],"v":[[15.543,-64.979],[13.154,28.735],[16.104,36.252],[22.701,40.327],[167.237,40.414],[174.113,36.954],[177.63,30.395],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":29}],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7333,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,-0.107],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3},{"ty":4,"nm":"box","sr":1,"st":0,"op":90,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[114.5,111.5,0],"ix":1},"s":{"a":0,"k":[210,210,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[310,220,0],"t":0,"ti":[0,-30,0],"to":[0,36.6666679382324,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[310,440,0],"t":15,"ti":[0,6.66666650772095,0],"to":[0,30,0]},{"s":[310,400,0],"t":19}],"ix":2},"r":{"a":0,"k":-0.138,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"s":[100],"t":15}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"box","ix":1,"cix":2,"np":5,"it":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[2.676,1.529],[0,0],[0,1.437],[0,0],[-2.676,-1.53],[0,0],[0,-1.436],[0,0]],"o":[[0,0],[-1.249,-0.714],[0,0],[0,-3.077],[0,0],[1.249,0.714],[0,0],[0,3.078]],"v":[[7.814,14.89],[-11.803,3.682],[-13.822,0.205],[-13.822,-11.413],[-7.814,-14.889],[11.802,-3.68],[13.822,-0.204],[13.822,11.413]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[67.059,135.614],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 2","ix":2,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[2.16,1.318],[0,0],[-0.504,0.292],[-4.258,2.805],[0.212,0.123],[12.284,6.925]],"o":[[0,0],[0.456,-0.01],[17.4,-10.058],[-0.172,-0.191],[-6.276,-3.627],[-2.13,-1.2]],"v":[[-33.579,-39.177],[-33.4,37.332],[-32.002,36.86],[33.4,-1.005],[32.879,-1.57],[-26.565,-35.369]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.6078,0.6941,0.7725],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[147.882,65.668],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 3","ix":3,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0.213,0.123],[6.288,3.607],[12.284,6.924],[0.894,0.379],[2.252,-1.314],[1.819,-1.791],[-17.273,-10.007],[-0.95,0.549],[-17.4,10.06],[-4.258,2.805]],"o":[[-6.275,-3.627],[-5.131,-2.943],[-2.494,-1.405],[-1.22,0.528],[-14.667,8.562],[4.538,2.653],[1.046,0.606],[17.401,-10.059],[4.408,-2.549],[-0.171,-0.191]],"v":[[66.278,-1.562],[47.435,-12.418],[6.835,-35.361],[-0.379,-39.182],[-8.488,-35.245],[-66.799,-0.937],[-1.311,36.948],[1.397,36.868],[53.62,6.732],[66.799,-0.997]]},"ix":2}},{"ty":"mm","bm":0,"hd":false,"mn":"ADBE Vector Filter - Merge","nm":"Merge Paths 1","mm":4},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.851,0.8784,0.902],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[114.462,65.66],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 4","ix":4,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.005,-24.322],[1.903,1.096],[2.616,1.472],[-0.03,5.005],[0.01,9.844]],"o":[[0,0],[-2.239,0.118],[-15.611,-8.992],[-4.347,-2.446],[0.059,-9.842],[4.384,2.492]],"v":[[33.613,-38.028],[33.609,37.91],[27.456,36.222],[-27.186,4.76],[-33.583,-6.359],[-33.594,-76.364]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.6039,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[80.871,141.03],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 5","ix":5,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-4.147,2.385],[-0.029,-4.102],[4.338,-2.47],[10.47,-6.046],[2.548,0.242]],"o":[[0,0],[0.031,5.777],[0.036,4.968],[-7.538,4.292],[-2.117,1.223],[-0.005,-24.322]],"v":[[-33.625,-38.09],[33.024,-76.375],[33.598,-6.383],[27.179,4.728],[-26.801,35.827],[-33.629,37.848]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.6039,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[148.109,141.092],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"tr","a":{"a":0,"k":[114.5,111.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[114.5,111.5],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":4},{"ty":4,"nm":"bottom_right 4","sr":1,"st":0,"op":90,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[97.496,-65.355,0],"ix":1},"s":{"a":0,"k":[97.228,95.215,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[379.843,80.643,0],"t":0,"ti":[0,-30,0],"to":[0,36.6666679382324,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[379.843,300.643,0],"t":15,"ti":[0,6.66666650772095,0],"to":[0,30,0]},{"s":[379.843,260.643,0],"t":19}],"ix":2},"r":{"a":0,"k":-150.704,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"s":[100],"t":15}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":3,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[-0.643,-0.382],[-18.864,-10.591],[-1.644,-0.89],[-2.802,-0.07],[-48.163,1.073],[-0.716,2.224],[2.199,1.39],[17.518,9.202],[1.065,0.003],[53.092,-0.118]],"o":[[18.548,11.008],[1.627,0.914],[2.383,1.289],[48.159,1.198],[2.644,-0.059],[0.735,-2.282],[-16.56,-10.467],[-0.912,-0.479],[-53.092,-0.136],[-0.777,0.002]],"v":[[15.543,-64.979],[72.21,-33.309],[77.014,-30.466],[84.284,-26.777],[228.82,-26.69],[235.696,-30.15],[231.972,-36.474],[180.221,-65.213],[177.029,-65.337],[17.754,-65.628]]}],"t":15},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.015,-0.679],[-0.933,-32.194],[-1.771,-2.15],[-2.692,-0.074],[-48.163,1.073],[-1.776,1.712],[-0.093,2.413],[1.011,32.595],[1.229,0.008],[53.092,-0.118]],"o":[[-0.71,32.199],[0.077,2.648],[1.573,1.909],[48.155,1.326],[2.644,-0.059],[1.856,-1.789],[1.258,-32.589],[-0.033,-1.073],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[15.61,31.635],[18.561,39.152],[25.158,43.227],[169.694,43.314],[176.57,39.854],[180.087,33.295],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":21},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[{"c":true,"i":[[0.355,-0.604],[9.063,-18.116],[-0.993,-3.498],[-2.692,-0.088],[-49.222,0.786],[-1.832,1.666],[-1.275,2.313],[-9.417,19.905],[1.229,0.008],[53.092,-0.118]],"o":[[-10.346,17.584],[-1.652,3.302],[0.648,2.283],[49.196,1.615],[2.645,-0.042],[2.036,-1.851],[10.697,-19.406],[0.469,-0.992],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-14.038,-11.592],[-16.469,-0.991],[-9.872,3.084],[137.815,4.075],[144.691,0.615],[149.006,-6.101],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":26},{"s":[{"c":true,"i":[[0.761,0.139],[18.699,4.066],[1.768,2.165],[-1.916,-0.085],[-46.459,-2.274],[-2.914,0.176],[-3.445,-0.368],[-21.965,-2.982],[1.229,0.008],[53.092,-0.118]],"o":[[-18.859,-3.457],[-2.954,-0.642],[-1.114,-1.364],[46.471,2.069],[2.917,0.143],[3.463,-0.21],[22.064,2.356],[1.215,0.165],[-53.09,-0.359],[-0.777,0.002]],"v":[[15.543,-64.979],[-40.778,-76.356],[-49.358,-79.092],[-43.68,-79.91],[95.666,-72.634],[104.429,-72.66],[114.762,-73.791],[180.598,-64.526],[177.029,-65.337],[17.754,-65.628]]}],"t":29}],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7333,0.9412,0.2745],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[99.101,-65.381],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[99.101,-65.381],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":5},{"ty":4,"nm":"shadow","sr":1,"st":0,"op":123,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[119.5,119.5,0],"ix":1},"s":{"a":0,"k":[397.854,250.518,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[287,509,0],"t":0,"ti":[0,4.66666650772095,0],"to":[0,-10,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[287,449,0],"t":15,"ti":[0,-5.33333349227905,0],"to":[0,-4.66666650772095,0]},{"s":[287,481,0],"t":21}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":15},{"s":[63],"t":21}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 1","ix":1,"cix":2,"np":3,"it":[{"ty":"rc","bm":0,"hd":false,"mn":"ADBE Vector Shape - Rect","nm":"Rectangle Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"s":{"a":0,"k":[81.29,81.29],"ix":2}},{"ty":"gf","bm":0,"hd":false,"mn":"ADBE Vector Graphic - G-Fill","nm":"Gradient Fill 1","e":{"a":0,"k":[-25.662,26.134],"ix":6},"g":{"p":3,"k":{"a":0,"k":[0,0,0,0,0.95,0.12549019607843137,0.15294117647058825,0.17254901960784313,1,0,0,0,0,0.39,0.95,0.195,1,0],"ix":9}},"t":2,"a":{"a":0,"k":0,"ix":8},"h":{"a":0,"k":0,"ix":7},"s":{"a":0,"k":[0.074,0.267],"ix":5},"r":1,"o":{"a":0,"k":100,"ix":10}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[124.899,112.74],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[125.672,140.06],"ix":2},"r":{"a":0,"k":-47.351,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":6}],"v":"5.4.2","fr":60,"op":90,"ip":0,"assets":[]} \ No newline at end of file diff --git a/gsf/assets/lottie/spotifyMusic.json b/gsf/assets/lottie/spotifyMusic.json new file mode 100644 index 0000000..de0802e --- /dev/null +++ b/gsf/assets/lottie/spotifyMusic.json @@ -0,0 +1 @@ +{"v":"5.7.6","fr":30,"ip":0,"op":150,"w":1920,"h":1080,"nm":"Music Bar","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1356,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-302,24],[-302,560]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-8,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":89,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":97,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":101,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":105,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":111,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":113,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":122,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":126,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":136,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":142,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":146,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":156,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":164,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":173,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":177,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":181,"s":[0]},{"t":187.000007616666,"s":[40]}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.3764705882352941,0.8549019607843137,0.5294117647058824,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":125,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-10.0000004073083,"op":160.000006516934,"st":10.0000004073083,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1156,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-302,24],[-302,560]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":88,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":94,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":105,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":109,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":113,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":119,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":121,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":132,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":136,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":140,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":146,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":152,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":163,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":167,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":171,"s":[0]},{"t":177.000007209358,"s":[40]}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.3764705882352941,0.8549019607843137,0.5294117647058824,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":125,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-20.0000008146167,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1560,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-302,24],[-302,560]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-15,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-4,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":41,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":48,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":79,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":90,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":94,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":98,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":104,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":106,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":117,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":121,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":125,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":131,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":137,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":148,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":152,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":156,"s":[0]},{"t":162.000006598395,"s":[40]}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.3764705882352941,0.8549019607843137,0.5294117647058824,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":125,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-15.0000006109625,"op":152.000006191087,"st":-15.0000006109625,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-302,24],[-302,560]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-10,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":53,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":95,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":99,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":103,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":109,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":111,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":122,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":126,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":136,"s":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":142,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":153,"s":[91]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":157,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":161,"s":[0]},{"t":167.000006802049,"s":[40]}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.3764705882352941,0.8549019607843137,0.5294117647058824,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":125,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-10.0000004073083,"op":150.000006109625,"st":-10.0000004073083,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/gsf/assets/lottie/timer.json b/gsf/assets/lottie/timer.json new file mode 100644 index 0000000..afdd434 --- /dev/null +++ b/gsf/assets/lottie/timer.json @@ -0,0 +1 @@ +{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.21","a":"","k":"","d":"","tc":""},"fr":24,"ip":0,"op":48,"w":120,"h":120,"nm":"sand timer","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 3","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.742],"y":[0]},"t":16,"s":[0]},{"t":43,"s":[-180]}],"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[73,73,100],"ix":6}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"top sand","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,35.334,0],"ix":2},"a":{"a":0,"k":[-388.008,75.466,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":-4,"s":[{"i":[[0,0],[8.5,-3],[0,0],[0,0],[0,0]],"o":[[0,0],[-8.896,3.14],[0,0],[0,0],[0,0]],"v":[[-371.449,64.5],[-389.008,58.5],[-404,64.5],[-404,87.25],[-371.449,87.25]],"c":true}]},{"i":{"x":0.557,"y":1},"o":{"x":0.167,"y":0.167},"t":19,"s":[{"i":[[0,0],[3.516,5.35],[0,0],[0,0],[0,0]],"o":[[0,0],[-4.234,-6.15],[0,0],[0,0],[0,0]],"v":[[-379.199,83.761],[-392.024,74.823],[-404,75.511],[-404,87.601],[-371.449,87.601]],"c":true}]},{"t":39.2138671875,"s":[{"i":[[0,0],[9.25,0],[0,0],[0,0],[0,0]],"o":[[0,0],[-8.974,0],[0,0],[0,0],[0,0]],"v":[[-371.449,88],[-388.508,88],[-404,88],[-404,88],[-371.449,88]],"c":true}]}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"top mask"}],"shapes":[{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.507,3.571],[0,0],[0,0],[0,2.437],[0,0],[-0.43,0],[0,0],[0,-0.43],[0,0],[1.489,-1.691],[0,0]],"o":[[0,0],[0,0],[-1.707,-1.739],[0,0],[0,-0.43],[0,0],[0.43,0],[0,0],[0,2.251],[0,0],[0,0]],"v":[[-390.332,80.46],[-392.903,77.973],[-397.727,73.057],[-400.374,66.58],[-400.374,65.02],[-399.595,64.241],[-376.422,64.241],[-375.643,65.02],[-375.643,67.039],[-377.952,73.151],[-382.162,77.929]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"bottom sand 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,64.443,0],"ix":2},"a":{"a":0,"k":[-388.008,75.466,0],"ix":1},"s":{"a":0,"k":[136.986,-136.986,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-8.5,0.021],[0,0],[0,0],[0,0]],"o":[[0,0],[8.896,-0.022],[0,0],[0,0],[0,0]],"v":[[-404,62.26],[-386.382,62.199],[-371.449,62.26],[-371.39,62],[-403.941,62]],"c":true}]},{"t":39,"s":[{"i":[[0,0],[-8.5,3],[0,0],[0,0],[0,0]],"o":[[0,0],[8.896,-3.14],[0,0],[0,0],[0,0]],"v":[[-404,95.75],[-386.382,87],[-371.449,95.75],[-371.39,58.25],[-403.941,58.25]],"c":true}]}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"top mask"}],"shapes":[{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,2.437],[0,0],[-0.43,0],[0,0],[0,-0.43],[0,0],[1.489,-1.691],[0,0],[0,0]],"o":[[0,0],[-1.707,-1.739],[0,0],[0,-0.43],[0,0],[0.43,0],[0,0],[0,2.251],[0,0],[0,0],[-3.071,3.486]],"v":[[-392.102,78.79],[-397.727,73.057],[-400.374,66.58],[-400.374,65.02],[-399.595,64.241],[-376.422,64.241],[-375.643,65.02],[-375.643,67.039],[-377.952,73.151],[-383.095,78.988],[-384.631,80.511]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"filler path","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.685,50,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-18.312],[0.041,19]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"bm":0,"d":[{"n":"d","nm":"dash","v":{"a":0,"k":0,"ix":1}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.569],"y":[1]},"o":{"x":[0.37],"y":[0]},"t":1,"s":[0]},{"t":46,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.363],"y":[1]},"o":{"x":[0.613],"y":[-0.021]},"t":-4,"s":[28]},{"t":15.642578125,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"botter","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[-388.008,86.539,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.284],[0,0],[0,0],[0,0],[-2.475,-2.522],[0,0],[1.626,-1.657],[0,0],[0,-3.534],[0,0],[0,0],[0,0],[2.171,2.464],[0,0],[-1.419,1.61],[0,0]],"o":[[0,0],[0,0],[0,0],[0,3.534],[0,0],[1.626,1.657],[0,0],[-2.475,2.522],[0,0],[0,0],[0,0],[0,-3.284],[0,0],[-1.419,-1.61],[0,0],[2.171,-2.464]],"v":[[-371.674,68.761],[-371.674,59.435],[-404.342,59.435],[-404.342,68.343],[-400.481,77.792],[-394.803,83.578],[-394.803,89.547],[-400.481,95.333],[-404.342,104.782],[-404.342,113.642],[-371.674,113.642],[-371.674,104.364],[-375.043,95.445],[-380.388,89.379],[-380.388,83.745],[-375.043,77.68]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9425,0.9575,0.9467,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"top fill","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.985,7.498,0],"ix":2},"a":{"a":0,"k":[-388.008,58.473,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.981,0],[0,0],[0,0.981],[0,0],[-0.981,0],[0,0],[0,-0.981],[0,0]],"o":[[0,0],[-0.981,0],[0,0],[0,-0.981],[0,0],[0.981,0],[0,0],[0,0.981]],"v":[[-369.606,60.249],[-406.411,60.249],[-408.187,58.473],[-408.187,58.473],[-406.411,56.698],[-369.606,56.698],[-367.83,58.473],[-367.83,58.473]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"bottom fill","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.015,92.116,0],"ix":2},"a":{"a":0,"k":[-388.008,114.495,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.981,0],[0,0],[0,0.981],[0,0],[-0.981,0],[0,0],[0,-0.981],[0,0]],"o":[[0,0],[-0.981,0],[0,0],[0,-0.981],[0,0],[0.981,0],[0,0],[0,0.981]],"v":[[-369.606,116.27],[-406.411,116.27],[-408.187,114.495],[-408.187,114.495],[-406.411,112.719],[-369.606,112.719],[-367.83,114.495],[-367.83,114.495]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.1294,0.8118,0.3216,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"cristal","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[-388.008,87.579,0],"ix":1},"s":{"a":0,"k":[136.986,136.986,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0.43],[0,0],[-1.706,1.741],[0,0],[3.507,3.571],[0,0],[0,2.437],[0,0],[-0.43,0],[0,0],[0,-0.43],[0,0],[1.489,-1.691],[0,0],[-3.071,-3.486],[0,0],[0,-2.252],[0,0],[0.43,0]],"o":[[-0.43,0],[0,0],[0,-2.437],[0,0],[3.506,-3.569],[0,0],[-1.707,-1.739],[0,0],[0,-0.43],[0,0],[0.43,0],[0,0],[0,2.251],[0,0],[-3.071,3.486],[0,0],[1.489,1.691],[0,0],[0,0.43],[0,0]],"v":[[-399.595,110.917],[-400.374,110.138],[-400.374,106.544],[-397.728,100.067],[-390.83,93.037],[-390.832,80.085],[-397.727,73.057],[-400.374,66.58],[-400.374,65.02],[-399.595,64.241],[-376.422,64.241],[-375.643,65.02],[-375.643,67.039],[-377.952,73.151],[-384.381,80.448],[-384.381,92.676],[-377.952,99.973],[-375.643,106.087],[-375.643,110.138],[-376.422,110.917]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/gsf/flutter_01.png b/gsf/flutter_01.png new file mode 100644 index 0000000..88567d4 Binary files /dev/null and b/gsf/flutter_01.png differ diff --git a/gsf/ios/.gitignore b/gsf/ios/.gitignore new file mode 100644 index 0000000..ad322bc --- /dev/null +++ b/gsf/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/gsf/ios/Flutter/AppFrameworkInfo.plist b/gsf/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..0d9747f --- /dev/null +++ b/gsf/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 11.0 + + diff --git a/gsf/ios/Flutter/Debug.xcconfig b/gsf/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..553cfac --- /dev/null +++ b/gsf/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/gsf/ios/Flutter/Release.xcconfig b/gsf/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..4b6e1f6 --- /dev/null +++ b/gsf/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist new file mode 100644 index 0000000..4e1d0c5 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + \ No newline at end of file diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-13-35-102.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-13-35-102.plist new file mode 100644 index 0000000..7d7e9e5 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-13-35-102.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-22-50-120.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-22-50-120.plist new file mode 100644 index 0000000..57421eb --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-22-50-120.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-30-16-423.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-30-16-423.plist new file mode 100644 index 0000000..7d7e9e5 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 13-30-16-423.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-03-56-429.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-03-56-429.plist new file mode 100644 index 0000000..7d7e9e5 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-03-56-429.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-08-14-032.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-08-14-032.plist new file mode 100644 index 0000000..57421eb --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-08-14-032.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-11-27-688.plist b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-11-27-688.plist new file mode 100644 index 0000000..7d7e9e5 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/Info.plist 20-11-27-688.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + NotificationService + + + diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-13-35-101.h b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-13-35-101.h new file mode 100644 index 0000000..aa43536 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-13-35-101.h @@ -0,0 +1,12 @@ +// +// NotificationService.h +// OneSignalNotificationServiceExtension +// +// Created by MacBook Pro on 01/09/23. +// + +#import + +@interface NotificationService : UNNotificationServiceExtension + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-30-16-422.h b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-30-16-422.h new file mode 100644 index 0000000..7d3e0cc --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 13-30-16-422.h @@ -0,0 +1,12 @@ +// +// NotificationService.h +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +#import + +@interface NotificationService : UNNotificationServiceExtension + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-03-56-398.h b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-03-56-398.h new file mode 100644 index 0000000..7d3e0cc --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-03-56-398.h @@ -0,0 +1,12 @@ +// +// NotificationService.h +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +#import + +@interface NotificationService : UNNotificationServiceExtension + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-11-27-686.h b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-11-27-686.h new file mode 100644 index 0000000..7d3e0cc --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.h 20-11-27-686.h @@ -0,0 +1,12 @@ +// +// NotificationService.h +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +#import + +@interface NotificationService : UNNotificationServiceExtension + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-13-35-094.m b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-13-35-094.m new file mode 100644 index 0000000..008d908 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-13-35-094.m @@ -0,0 +1,49 @@ +#import + +#import "NotificationService.h" + +@interface NotificationService () + +@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property (nonatomic, strong) UNNotificationRequest *receivedRequest; +@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation NotificationService + +- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { + self.receivedRequest = request; + self.contentHandler = contentHandler; + self.bestAttemptContent = [request.content mutableCopy]; + + //If your SDK version is < 3.5.0 uncomment and use this code: + /* + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent]; + self.contentHandler(self.bestAttemptContent); + */ + + /* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting + Note, this extension only runs when mutable-content is set + Setting an attachment or action buttons automatically adds this */ + // NSLog(@"Running NotificationServiceExtension"); + // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body]; + + // Uncomment this line to set the default log level of NSE to VERBOSE so we get all logs from NSE logic + //[OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_NONE]; + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent + withContentHandler:self.contentHandler]; +} + +- (void)serviceExtensionTimeWillExpire { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + + [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent]; + + self.contentHandler(self.bestAttemptContent); +} + +@end \ No newline at end of file diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-30-16-419.m b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-30-16-419.m new file mode 100644 index 0000000..9cce7ad --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 13-30-16-419.m @@ -0,0 +1,49 @@ +#import + +#import "NotificationService.h" + +@interface NotificationService () + +@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property (nonatomic, strong) UNNotificationRequest *receivedRequest; +@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation NotificationService + +- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { + self.receivedRequest = request; + self.contentHandler = contentHandler; + self.bestAttemptContent = [request.content mutableCopy]; + + //If your SDK version is < 3.5.0 uncomment and use this code: + /* + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent]; + self.contentHandler(self.bestAttemptContent); + */ + + /* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting + Note, this extension only runs when mutable-content is set + Setting an attachment or action buttons automatically adds this */ + // NSLog(@"Running NotificationServiceExtension"); + // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body]; + + // Uncomment this line to set the default log level of NSE to VERBOSE so we get all logs from NSE logic + //[OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_NONE]; + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent + withContentHandler:self.contentHandler]; +} + +- (void)serviceExtensionTimeWillExpire { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + + [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent]; + + self.contentHandler(self.bestAttemptContent); +} + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-03-56-363.m b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-03-56-363.m new file mode 100644 index 0000000..9cce7ad --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-03-56-363.m @@ -0,0 +1,49 @@ +#import + +#import "NotificationService.h" + +@interface NotificationService () + +@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property (nonatomic, strong) UNNotificationRequest *receivedRequest; +@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation NotificationService + +- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { + self.receivedRequest = request; + self.contentHandler = contentHandler; + self.bestAttemptContent = [request.content mutableCopy]; + + //If your SDK version is < 3.5.0 uncomment and use this code: + /* + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent]; + self.contentHandler(self.bestAttemptContent); + */ + + /* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting + Note, this extension only runs when mutable-content is set + Setting an attachment or action buttons automatically adds this */ + // NSLog(@"Running NotificationServiceExtension"); + // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body]; + + // Uncomment this line to set the default log level of NSE to VERBOSE so we get all logs from NSE logic + //[OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_NONE]; + [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest + withMutableNotificationContent:self.bestAttemptContent + withContentHandler:self.contentHandler]; +} + +- (void)serviceExtensionTimeWillExpire { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + + [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent]; + + self.contentHandler(self.bestAttemptContent); +} + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-11-27-681.m b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-11-27-681.m new file mode 100644 index 0000000..7cfefdb --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.m 20-11-27-681.m @@ -0,0 +1,35 @@ +// +// NotificationService.m +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +#import "NotificationService.h" + +@interface NotificationService () + +@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation NotificationService + +- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { + self.contentHandler = contentHandler; + self.bestAttemptContent = [request.content mutableCopy]; + + // Modify the notification content here... + self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title]; + + self.contentHandler(self.bestAttemptContent); +} + +- (void)serviceExtensionTimeWillExpire { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + self.contentHandler(self.bestAttemptContent); +} + +@end diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift new file mode 100644 index 0000000..9334596 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift @@ -0,0 +1,41 @@ +import UserNotifications + +import OneSignal + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var receivedRequest: UNNotificationRequest! + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + self.receivedRequest = request + self.contentHandler = contentHandler + self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + if let bestAttemptContent = bestAttemptContent { + //If your SDK version is < 3.5.0 uncomment and use this code: + /* + OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: self.bestAttemptContent) + contentHandler(bestAttemptContent) + */ + + /* DEBUGGING: Uncomment the 2 lines below to check this extension is excuting + Note, this extension only runs when mutable-content is set + Setting an attachment or action buttons automatically adds this */ + //OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE) + //bestAttemptContent.body = "[Modified] " + bestAttemptContent.body + + OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent) + contentHandler(bestAttemptContent) + } + } +} diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 13-22-50-091.swift b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 13-22-50-091.swift new file mode 100644 index 0000000..d79d403 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 13-22-50-091.swift @@ -0,0 +1,35 @@ +// +// NotificationService.swift +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 06/09/23. +// + +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + if let bestAttemptContent = bestAttemptContent { + // Modify the notification content here... + bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" + + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + +} diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-08-14-023.swift b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-08-14-023.swift new file mode 100644 index 0000000..aa289c9 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-08-14-023.swift @@ -0,0 +1,35 @@ +// +// NotificationService.swift +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + if let bestAttemptContent = bestAttemptContent { + // Modify the notification content here... + bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" + + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + +} diff --git a/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-12-32-444.swift b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-12-32-444.swift new file mode 100644 index 0000000..aa289c9 --- /dev/null +++ b/gsf/ios/OneSignalNotificationServiceExtension/NotificationService.swift 20-12-32-444.swift @@ -0,0 +1,35 @@ +// +// NotificationService.swift +// OneSignalNotificationServiceExtension +// +// Created by MacOs on 05/09/23. +// + +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + if let bestAttemptContent = bestAttemptContent { + // Modify the notification content here... + bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" + + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + +} diff --git a/gsf/ios/Podfile b/gsf/ios/Podfile new file mode 100644 index 0000000..efa5e45 --- /dev/null +++ b/gsf/ios/Podfile @@ -0,0 +1,49 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '13.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + pod 'OneSignalXCFramework', '>= 3.4.3', '< 4.0' + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +target 'OneSignalNotificationServiceExtension' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + pod 'OneSignalXCFramework', '>= 3.0.0', '< 4.0' +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end + + diff --git a/gsf/ios/Podfile.lock b/gsf/ios/Podfile.lock new file mode 100644 index 0000000..2c5e489 --- /dev/null +++ b/gsf/ios/Podfile.lock @@ -0,0 +1,360 @@ +PODS: + - audio_session (0.0.1): + - Flutter + - audioplayers_darwin (0.0.1): + - Flutter + - bluetooth_enable_fork (0.1.4): + - Flutter + - BranchSDK (2.1.2) + - connectivity_plus (0.0.1): + - Flutter + - ReachabilitySwift + - device_info_plus (0.0.1): + - Flutter + - Firebase/CoreOnly (10.17.0): + - FirebaseCore (= 10.17.0) + - Firebase/Crashlytics (10.17.0): + - Firebase/CoreOnly + - FirebaseCrashlytics (~> 10.17.0) + - firebase_core (2.22.0): + - Firebase/CoreOnly (= 10.17.0) + - Flutter + - firebase_crashlytics (3.4.4): + - Firebase/Crashlytics (= 10.17.0) + - firebase_core + - Flutter + - FirebaseCore (10.17.0): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Logger (~> 7.8) + - FirebaseCoreExtension (10.18.0): + - FirebaseCore (~> 10.0) + - FirebaseCoreInternal (10.18.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseCrashlytics (10.17.0): + - FirebaseCore (~> 10.5) + - FirebaseInstallations (~> 10.0) + - FirebaseSessions (~> 10.5) + - GoogleDataTransport (~> 9.2) + - GoogleUtilities/Environment (~> 7.8) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (~> 2.1) + - FirebaseInstallations (10.18.0): + - FirebaseCore (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - PromisesObjC (~> 2.1) + - FirebaseSessions (10.18.0): + - FirebaseCore (~> 10.5) + - FirebaseCoreExtension (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleDataTransport (~> 9.2) + - GoogleUtilities/Environment (~> 7.10) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesSwift (~> 2.1) + - Flutter (1.0.0) + - flutter_blue_plus (0.0.1): + - Flutter + - flutter_branch_sdk (6.4.0): + - BranchSDK (~> 2.1.0) + - Flutter + - flutter_custom_tabs (0.0.1): + - Flutter + - flutter_isolate (0.0.1): + - Flutter + - flutter_native_splash (0.0.1): + - Flutter + - flutter_pdfview (1.0.2): + - Flutter + - fluttertoast (0.0.2): + - Flutter + - Toast + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - geolocator_apple (1.2.0): + - Flutter + - GoogleDataTransport (9.2.5): + - GoogleUtilities/Environment (~> 7.7) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Environment (7.12.0): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.12.0): + - GoogleUtilities/Environment + - "GoogleUtilities/NSData+zlib (7.12.0)" + - GoogleUtilities/UserDefaults (7.12.0): + - GoogleUtilities/Logger + - health (1.0.4): + - Flutter + - icdevicemanager_flutter (1.0.0): + - Flutter + - image_cropper (0.0.4): + - Flutter + - TOCropViewController (~> 2.6.1) + - image_picker_ios (0.0.1): + - Flutter + - just_audio (0.0.1): + - Flutter + - local_auth_ios (0.0.1): + - Flutter + - nanopb (2.30909.1): + - nanopb/decode (= 2.30909.1) + - nanopb/encode (= 2.30909.1) + - nanopb/decode (2.30909.1) + - nanopb/encode (2.30909.1) + - onesignal_flutter (3.5.1): + - Flutter + - OneSignalXCFramework (= 3.12.4) + - OneSignalXCFramework (3.12.4): + - OneSignalXCFramework/OneSignalCore (= 3.12.4) + - OneSignalXCFramework/OneSignalExtension (= 3.12.4) + - OneSignalXCFramework/OneSignalOutcomes (= 3.12.4) + - OneSignalXCFramework/OneSignalCore (3.12.4) + - OneSignalXCFramework/OneSignalExtension (3.12.4): + - OneSignalXCFramework/OneSignalCore + - OneSignalXCFramework/OneSignalOutcomes + - OneSignalXCFramework/OneSignalOutcomes (3.12.4): + - OneSignalXCFramework/OneSignalCore + - package_info_plus (0.4.5): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - pedometer (0.0.1): + - Flutter + - permission_handler_apple (9.0.4): + - Flutter + - PromisesObjC (2.3.1) + - PromisesSwift (2.3.1): + - PromisesObjC (= 2.3.1) + - ReachabilitySwift (5.0.0) + - share_plus (0.0.1): + - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite (0.0.3): + - Flutter + - FMDB (>= 2.7.5) + - syncfusion_flutter_pdfviewer (0.0.1): + - Flutter + - Toast (4.0.0) + - TOCropViewController (2.6.1) + - uni_links (0.0.1): + - Flutter + - url_launcher_ios (0.0.1): + - Flutter + - vibration (1.7.5): + - Flutter + - video_player_avfoundation (0.0.1): + - Flutter + - wakelock (0.0.1): + - Flutter + - webview_flutter_wkwebview (0.0.1): + - Flutter + - workmanager (0.0.1): + - Flutter + +DEPENDENCIES: + - audio_session (from `.symlinks/plugins/audio_session/ios`) + - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) + - bluetooth_enable_fork (from `.symlinks/plugins/bluetooth_enable_fork/ios`) + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`) + - Flutter (from `Flutter`) + - flutter_blue_plus (from `.symlinks/plugins/flutter_blue_plus/ios`) + - flutter_branch_sdk (from `.symlinks/plugins/flutter_branch_sdk/ios`) + - flutter_custom_tabs (from `.symlinks/plugins/flutter_custom_tabs/ios`) + - flutter_isolate (from `.symlinks/plugins/flutter_isolate/ios`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - flutter_pdfview (from `.symlinks/plugins/flutter_pdfview/ios`) + - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`) + - health (from `.symlinks/plugins/health/ios`) + - icdevicemanager_flutter (from `.symlinks/plugins/icdevicemanager_flutter/ios`) + - image_cropper (from `.symlinks/plugins/image_cropper/ios`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - just_audio (from `.symlinks/plugins/just_audio/ios`) + - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) + - onesignal_flutter (from `.symlinks/plugins/onesignal_flutter/ios`) + - OneSignalXCFramework (< 4.0, >= 3.0.0) + - OneSignalXCFramework (< 4.0, >= 3.4.3) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - pedometer (from `.symlinks/plugins/pedometer/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) + - syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`) + - uni_links (from `.symlinks/plugins/uni_links/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - vibration (from `.symlinks/plugins/vibration/ios`) + - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) + - wakelock (from `.symlinks/plugins/wakelock/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) + - workmanager (from `.symlinks/plugins/workmanager/ios`) + +SPEC REPOS: + trunk: + - BranchSDK + - Firebase + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseCrashlytics + - FirebaseInstallations + - FirebaseSessions + - FMDB + - GoogleDataTransport + - GoogleUtilities + - nanopb + - OneSignalXCFramework + - PromisesObjC + - PromisesSwift + - ReachabilitySwift + - Toast + - TOCropViewController + +EXTERNAL SOURCES: + audio_session: + :path: ".symlinks/plugins/audio_session/ios" + audioplayers_darwin: + :path: ".symlinks/plugins/audioplayers_darwin/ios" + bluetooth_enable_fork: + :path: ".symlinks/plugins/bluetooth_enable_fork/ios" + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_crashlytics: + :path: ".symlinks/plugins/firebase_crashlytics/ios" + Flutter: + :path: Flutter + flutter_blue_plus: + :path: ".symlinks/plugins/flutter_blue_plus/ios" + flutter_branch_sdk: + :path: ".symlinks/plugins/flutter_branch_sdk/ios" + flutter_custom_tabs: + :path: ".symlinks/plugins/flutter_custom_tabs/ios" + flutter_isolate: + :path: ".symlinks/plugins/flutter_isolate/ios" + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" + flutter_pdfview: + :path: ".symlinks/plugins/flutter_pdfview/ios" + fluttertoast: + :path: ".symlinks/plugins/fluttertoast/ios" + geolocator_apple: + :path: ".symlinks/plugins/geolocator_apple/ios" + health: + :path: ".symlinks/plugins/health/ios" + icdevicemanager_flutter: + :path: ".symlinks/plugins/icdevicemanager_flutter/ios" + image_cropper: + :path: ".symlinks/plugins/image_cropper/ios" + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" + just_audio: + :path: ".symlinks/plugins/just_audio/ios" + local_auth_ios: + :path: ".symlinks/plugins/local_auth_ios/ios" + onesignal_flutter: + :path: ".symlinks/plugins/onesignal_flutter/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/ios" + pedometer: + :path: ".symlinks/plugins/pedometer/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" + syncfusion_flutter_pdfviewer: + :path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios" + uni_links: + :path: ".symlinks/plugins/uni_links/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + vibration: + :path: ".symlinks/plugins/vibration/ios" + video_player_avfoundation: + :path: ".symlinks/plugins/video_player_avfoundation/ios" + wakelock: + :path: ".symlinks/plugins/wakelock/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" + workmanager: + :path: ".symlinks/plugins/workmanager/ios" + +SPEC CHECKSUMS: + audio_session: 4f3e461722055d21515cf3261b64c973c062f345 + audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 + bluetooth_enable_fork: 73b8ca6e67230a9baa04010cd5c1e824e00d2797 + BranchSDK: 8b25eda1d9e82778d476edc1026e385cf58c56b6 + connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a + device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed + Firebase: f4ac0b02927af9253ae094d23deecf0890da7374 + firebase_core: efc9455611b8769fa90fbdae5da182600bd6901c + firebase_crashlytics: 6a564f58db90be49c49d9ac100bc5cc3fcbf8267 + FirebaseCore: 534544dd98cabcf4bf8598d88ec683b02319a528 + FirebaseCoreExtension: 62b201498aa10535801cdf3448c7f4db5e24ed80 + FirebaseCoreInternal: 8eb002e564b533bdcf1ba011f33f2b5c10e2ed4a + FirebaseCrashlytics: d78651ad7db206ef98269e103ac38d69d569200a + FirebaseInstallations: e842042ec6ac1fd2e37d7706363ebe7f662afea4 + FirebaseSessions: f90fe9212ee2818641eda051c0835c9c4e30d9ae + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_blue_plus: 5cb46a0d66c6cacebf7551e0e5a6bfa345ccc224 + flutter_branch_sdk: cc0393df011973fe6ab0380bc54bce1a3726e8a3 + flutter_custom_tabs: 7a10a08686955cb748e5d26e0ae586d30689bf89 + flutter_isolate: 0edf5081826d071adf21759d1eb10ff5c24503b5 + flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef + flutter_pdfview: 25f53dd6097661e6395b17de506e6060585946bd + fluttertoast: 48c57db1b71b0ce9e6bba9f31c940ff4b001293c + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401 + GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2 + GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34 + health: 5a380c0f6c4f619535845992993964293962e99e + icdevicemanager_flutter: 88e2e000e6de2590bfe51a0af7f8c789d35edc44 + image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98 + image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 + just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa + local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605 + nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 + onesignal_flutter: b8ac01bc3ebe47e798d7d775455c3a9b5b84f1c5 + OneSignalXCFramework: 087934ab0d4d7445fcf1c015c7c782359e26c020 + package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e + path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 + pedometer: 381969883680ade42559782cc41a3bbd453d8234 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 + PromisesSwift: 28dca69a9c40779916ac2d6985a0192a5cb4a265 + ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 + shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 + sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + syncfusion_flutter_pdfviewer: bb9998884b864cfedf72628df3503bdf57e397c0 + Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 + TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 + uni_links: d97da20c7701486ba192624d99bffaaffcfc298a + url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 + vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241 + video_player_avfoundation: 81e49bb3d9fb63dccf9fa0f6d877dc3ddbeac126 + wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f + webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a + workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 + +PODFILE CHECKSUM: a4ad73d8b0c939a70a630a3969a613f644c04b40 + +COCOAPODS: 1.13.0 diff --git a/gsf/ios/Runner.xcodeproj/project.pbxproj b/gsf/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..312d42b --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,894 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 1AF7D2922B8C725000853315 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1AF7D2912B8C725000853315 /* GoogleService-Info.plist */; }; + 227E28212AA8694400B81730 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 227E28202AA8694400B81730 /* NotificationService.swift */; }; + 227E28252AA8694400B81730 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 227E281E2AA8694400B81730 /* OneSignalNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 2CDFEB5386549600F95A3C4B /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 635852FDE7F8B5A361609B82 /* Pods_OneSignalNotificationServiceExtension.framework */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 529068A52A8E5706004ABCB1 /* BranchSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 529068A42A8E5706004ABCB1 /* BranchSDK */; }; + 529068A72A8E5864004ABCB1 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068A62A8E5864004ABCB1 /* CoreServices.framework */; }; + 529068A92A8E5873004ABCB1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068A82A8E5873004ABCB1 /* SystemConfiguration.framework */; }; + 529068AB2A8E5882004ABCB1 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068AA2A8E5882004ABCB1 /* CoreTelephony.framework */; }; + 529068AF2A8E5895004ABCB1 /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068AE2A8E5895004ABCB1 /* CoreSpotlight.framework */; }; + 529068B12A8E589E004ABCB1 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068B02A8E589D004ABCB1 /* AdServices.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 529068B32A8E58A4004ABCB1 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068B22A8E58A4004ABCB1 /* AdSupport.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 529068B52A8E58AF004ABCB1 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068B42A8E58AF004ABCB1 /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 529068B72A8E58B7004ABCB1 /* LinkPresentation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068B62A8E58B7004ABCB1 /* LinkPresentation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 529068B82A8F4849004ABCB1 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529068AC2A8E588C004ABCB1 /* WebKit.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + EAC2B08A5EF3DB337047B851 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + F28142B6420A67828003E26E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 559CD4C37425C2E8E38C2D7D /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 227E28232AA8694400B81730 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 227E281D2AA8694400B81730; + remoteInfo = OneSignalNotificationServiceExtension; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 226DE2242AA76AB30069AF32 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 227E28252AA8694400B81730 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 1AF7D2912B8C725000853315 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../../../../../../Documents/WDI IMP/gsf/GoogleService-Info.plist"; sourceTree = ""; }; + 220B64C42A7253A2006E498E /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + 227E281E2AA8694400B81730 /* OneSignalNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OneSignalNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 227E28202AA8694400B81730 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; + 227E28222AA8694400B81730 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 34CF38A11769EB9BFC905652 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 40D73505D43048226496D7A7 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; sourceTree = ""; }; + 50E3EF1F27202EA85837D946 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.release.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.release.xcconfig"; sourceTree = ""; }; + 5209C85A2A8E3F4800868C46 /* OneSignal.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = OneSignal.xcframework; path = Pods/OneSignalXCFramework/iOS_SDK/OneSignalSDK/OneSignal_XCFramework/OneSignal.xcframework; sourceTree = ""; }; + 529068A62A8E5864004ABCB1 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + 529068A82A8E5873004ABCB1 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 529068AA2A8E5882004ABCB1 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 529068AC2A8E588C004ABCB1 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 529068AE2A8E5895004ABCB1 /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; }; + 529068B02A8E589D004ABCB1 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; }; + 529068B22A8E58A4004ABCB1 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; + 529068B42A8E58AF004ABCB1 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + 529068B62A8E58B7004ABCB1 /* LinkPresentation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LinkPresentation.framework; path = System/Library/Frameworks/LinkPresentation.framework; sourceTree = SDKROOT; }; + 559CD4C37425C2E8E38C2D7D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 635852FDE7F8B5A361609B82 /* Pods_OneSignalNotificationServiceExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OneSignalNotificationServiceExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 73E7677E7BC1C1EB29CDF77C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8FCDD55BD2CD81F1D21914D2 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.profile.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.profile.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C3E19A11A483AD6983EC6356 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 227E281B2AA8694400B81730 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CDFEB5386549600F95A3C4B /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 529068B72A8E58B7004ABCB1 /* LinkPresentation.framework in Frameworks */, + 529068B52A8E58AF004ABCB1 /* StoreKit.framework in Frameworks */, + 529068B32A8E58A4004ABCB1 /* AdSupport.framework in Frameworks */, + 529068B12A8E589E004ABCB1 /* AdServices.framework in Frameworks */, + 529068AF2A8E5895004ABCB1 /* CoreSpotlight.framework in Frameworks */, + 529068AB2A8E5882004ABCB1 /* CoreTelephony.framework in Frameworks */, + 529068A92A8E5873004ABCB1 /* SystemConfiguration.framework in Frameworks */, + 529068A72A8E5864004ABCB1 /* CoreServices.framework in Frameworks */, + 529068A52A8E5706004ABCB1 /* BranchSDK in Frameworks */, + 529068B82A8F4849004ABCB1 /* WebKit.framework in Frameworks */, + EAC2B08A5EF3DB337047B851 /* BuildFile in Frameworks */, + F28142B6420A67828003E26E /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 17AC36FD4407D91AC2261E86 /* Pods */ = { + isa = PBXGroup; + children = ( + 40D73505D43048226496D7A7 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */, + 50E3EF1F27202EA85837D946 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */, + 8FCDD55BD2CD81F1D21914D2 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */, + C3E19A11A483AD6983EC6356 /* Pods-Runner.debug.xcconfig */, + 34CF38A11769EB9BFC905652 /* Pods-Runner.release.xcconfig */, + 73E7677E7BC1C1EB29CDF77C /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 227E281F2AA8694400B81730 /* OneSignalNotificationServiceExtension */ = { + isa = PBXGroup; + children = ( + 227E28202AA8694400B81730 /* NotificationService.swift */, + 227E28222AA8694400B81730 /* Info.plist */, + ); + path = OneSignalNotificationServiceExtension; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 227E281F2AA8694400B81730 /* OneSignalNotificationServiceExtension */, + 97C146EF1CF9000F007C117D /* Products */, + 17AC36FD4407D91AC2261E86 /* Pods */, + 9AD36002AE69EB67FA0E045C /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 227E281E2AA8694400B81730 /* OneSignalNotificationServiceExtension.appex */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 1AF7D2912B8C725000853315 /* GoogleService-Info.plist */, + 220B64C42A7253A2006E498E /* Runner.entitlements */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 9AD36002AE69EB67FA0E045C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 529068B62A8E58B7004ABCB1 /* LinkPresentation.framework */, + 529068B42A8E58AF004ABCB1 /* StoreKit.framework */, + 529068B22A8E58A4004ABCB1 /* AdSupport.framework */, + 529068B02A8E589D004ABCB1 /* AdServices.framework */, + 529068AE2A8E5895004ABCB1 /* CoreSpotlight.framework */, + 529068AC2A8E588C004ABCB1 /* WebKit.framework */, + 529068AA2A8E5882004ABCB1 /* CoreTelephony.framework */, + 529068A82A8E5873004ABCB1 /* SystemConfiguration.framework */, + 529068A62A8E5864004ABCB1 /* CoreServices.framework */, + 5209C85A2A8E3F4800868C46 /* OneSignal.xcframework */, + 635852FDE7F8B5A361609B82 /* Pods_OneSignalNotificationServiceExtension.framework */, + 559CD4C37425C2E8E38C2D7D /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 227E281D2AA8694400B81730 /* OneSignalNotificationServiceExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 227E28262AA8694400B81730 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */; + buildPhases = ( + 13EB04CF12534CDD59BBA288 /* [CP] Check Pods Manifest.lock */, + 227E281A2AA8694400B81730 /* Sources */, + 227E281B2AA8694400B81730 /* Frameworks */, + 227E281C2AA8694400B81730 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OneSignalNotificationServiceExtension; + productName = OneSignalNotificationServiceExtension; + productReference = 227E281E2AA8694400B81730 /* OneSignalNotificationServiceExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + AD0A238C35E5294F8BAB6312 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 226DE2242AA76AB30069AF32 /* Embed Foundation Extensions */, + C9D58640702688400651DCCA /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 227E28242AA8694400B81730 /* PBXTargetDependency */, + ); + name = Runner; + packageProductDependencies = ( + 529068A42A8E5706004ABCB1 /* BranchSDK */, + ); + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 227E281D2AA8694400B81730 = { + CreatedOnToolsVersion = 14.3.1; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 529068A32A8E5706004ABCB1 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */, + ); + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 227E281D2AA8694400B81730 /* OneSignalNotificationServiceExtension */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 227E281C2AA8694400B81730 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 1AF7D2922B8C725000853315 /* GoogleService-Info.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 13EB04CF12534CDD59BBA288 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-OneSignalNotificationServiceExtension-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 12; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + AD0A238C35E5294F8BAB6312 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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"; + showEnvVarsInLog = 0; + }; + C9D58640702688400651DCCA /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 227E281A2AA8694400B81730 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 227E28212AA8694400B81730 /* NotificationService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 227E28242AA8694400B81730 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 227E281D2AA8694400B81730 /* OneSignalNotificationServiceExtension */; + targetProxy = 227E28232AA8694400B81730 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 227E28272AA8694400B81730 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D73505D43048226496D7A7 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.3.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit.OneSignalNotificationServiceExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + 227E28282AA8694400B81730 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 50E3EF1F27202EA85837D946 /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.3.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit.OneSignalNotificationServiceExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + 227E28292AA8694400B81730 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8FCDD55BD2CD81F1D21914D2 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.3.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit.OneSignalNotificationServiceExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Profile; + }; + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "GSF BETA"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.3.27; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + ENABLE_BITCODE = NO; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 i386"; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "GSF BETA"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.3.27; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78P6PBS6GZ; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "GSF BETA"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.3.27; + PRODUCT_BUNDLE_IDENTIFIER = com.getsetfit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 227E28262AA8694400B81730 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 227E28272AA8694400B81730 /* Debug */, + 227E28282AA8694400B81730 /* Release */, + 227E28292AA8694400B81730 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 529068A32A8E5706004ABCB1 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/BranchMetrics/ios-branch-sdk-spm"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 529068A42A8E5706004ABCB1 /* BranchSDK */ = { + isa = XCSwiftPackageProductDependency; + package = 529068A32A8E5706004ABCB1 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */; + productName = BranchSDK; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/gsf/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/gsf/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c4b79bd --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..fc6bf80 --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..af0309c --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3966d58 --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "ios-branch-sdk-spm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/BranchMetrics/ios-branch-sdk-spm", + "state" : { + "revision" : "7fbe3085821c8e60241a2037098c6eed76fd2798", + "version" : "2.2.0" + } + } + ], + "version" : 2 +} diff --git a/gsf/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/gsf/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c87d15a --- /dev/null +++ b/gsf/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/ios/Runner.xcworkspace/contents.xcworkspacedata b/gsf/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/gsf/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/gsf/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/gsf/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..fc6bf80 --- /dev/null +++ b/gsf/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/gsf/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/gsf/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..af0309c --- /dev/null +++ b/gsf/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/gsf/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/gsf/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3966d58 --- /dev/null +++ b/gsf/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "ios-branch-sdk-spm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/BranchMetrics/ios-branch-sdk-spm", + "state" : { + "revision" : "7fbe3085821c8e60241a2037098c6eed76fd2798", + "version" : "2.2.0" + } + } + ], + "version" : 2 +} diff --git a/gsf/ios/Runner/AppDelegate.swift b/gsf/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..89a79c6 --- /dev/null +++ b/gsf/ios/Runner/AppDelegate.swift @@ -0,0 +1,26 @@ +import UIKit +import Flutter +//import OneSignal + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) +// OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE) + + // OneSignal initialization +// OneSignal.initWithLaunchOptions(launchOptions) +// OneSignal.setAppId("f5869a6b-cf12-422d-91e3-286f9c0e1a62") + + // promptForPushNotifications will show the native iOS notification permission prompt. + // We recommend removing the following code and instead using an In-App Message to prompt for notification permission (See step 8) +// OneSignal.promptForPushNotifications(userResponse: { accepted in +// print("User accepted notifications: \(accepted)") +// }) + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..745e1de --- /dev/null +++ b/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "ios_logo.jpg", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/ios_logo.jpg b/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/ios_logo.jpg new file mode 100644 index 0000000..d9bb146 Binary files /dev/null and b/gsf/ios/Runner/Assets.xcassets/AppIcon.appiconset/ios_logo.jpg differ diff --git a/gsf/ios/Runner/Assets.xcassets/Contents.json b/gsf/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/gsf/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json new file mode 100644 index 0000000..0611fd4 --- /dev/null +++ b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "ios_logo_transparents.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ios_logo_transparents@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ios_logo_transparents@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents.png b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents.png new file mode 100644 index 0000000..263d23f Binary files /dev/null and b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents.png differ diff --git a/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@2x.png b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@2x.png new file mode 100644 index 0000000..8ab3c64 Binary files /dev/null and b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@2x.png differ diff --git a/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@3x.png b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@3x.png new file mode 100644 index 0000000..0925076 Binary files /dev/null and b/gsf/ios/Runner/Assets.xcassets/SplashIcon.imageset/ios_logo_transparents@3x.png differ diff --git a/gsf/ios/Runner/Base.lproj/LaunchScreen.storyboard b/gsf/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..a5b6d3d --- /dev/null +++ b/gsf/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/ios/Runner/Base.lproj/Main.storyboard b/gsf/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8afb256 --- /dev/null +++ b/gsf/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gsf/ios/Runner/GoogleService-Info.plist b/gsf/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..ce9584e --- /dev/null +++ b/gsf/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 751933368781-0cgjotkpv6o238qrm9g9u1cgcq5pkf91.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.751933368781-0cgjotkpv6o238qrm9g9u1cgcq5pkf91 + API_KEY + AIzaSyAEz8aya-EsS6ebSSVgDxc4X6vlU3Lh5EY + GCM_SENDER_ID + 751933368781 + PLIST_VERSION + 1 + BUNDLE_ID + com.getsetfit + PROJECT_ID + gsf-live + STORAGE_BUCKET + gsf-live.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:751933368781:ios:1b07754b53887f3d0dfc84 + + \ No newline at end of file diff --git a/gsf/ios/Runner/Info.plist b/gsf/ios/Runner/Info.plist new file mode 100644 index 0000000..40091c5 --- /dev/null +++ b/gsf/ios/Runner/Info.plist @@ -0,0 +1,113 @@ + + + + + BGTaskSchedulerPermittedIdentifiers + + $(PRODUCT_BUNDLE_IDENTIFIER) + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Getsetfit + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + getsetfit + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.4 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + wdipl.gsf.scaletest2 + CFBundleURLSchemes + + gsf + + + + CFBundleVersion + 1 + ITSAppUsesNonExemptEncryption + + LSRequiresIPhoneOS + + NSAppleMusicUsageDescription + Getsetfit user mobile libarary for update profile + NSBluetoothAlwaysUsageDescription + Allow Getsetfit to aceess bluetooth to connect with sacle for biomatric + NSBluetoothPeripheralUsageDescription + Getsetfit Bluetooth requires this permission to connect the scale + NSCalendarsUsageDescription + Getsetfit use calendar to get current datetime + NSCameraUsageDescription + To capture profile photo please grant camera access + NSHealthShareUsageDescription + We will sync your data with the Apple Health app to give you better insights + NSHealthUpdateUsageDescription + We will sync your data with the Apple Health app to give you better insights + NSLocationAlwaysAndWhenInUseUsageDescription + Allow Getsetfit to find, connect to and determine the realtive position of nearby device + NSLocationUsageDescription + Getsetfit use Location to determine the near by devices + NSLocationWhenInUseUsageDescription + Getsetfit needs to access location to find nearbe devices + NSMicrophoneUsageDescription + Getsetfit access to Microphone access + NSMotionUsageDescription + This application tracks your steps + NSPhotoLibraryAddUsageDescription + Getsetfit get write-only access to the user photo library + NSPhotoLibraryUsageDescription + Allow access to photo library + NSSpeechRecognitionUsageDescription + sprecg + NSFaceIDUsageDescription + For user authentication + UIApplicationSupportsIndirectInputEvents + + UIBackgroundModes + + processing + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiresFullScreen + + UIStatusBarStyle + UIStatusBarStyleDarkContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + + UIViewControllerBasedStatusBarAppearance + + branch_key + + live + key_live_oEih3MwUt9Gn9S0LKaoG6jfovAedOTUv + + branch_universal_link_domains + + gsf019y3.app.link + gsf019y3-alternate.app.link + + + diff --git a/gsf/ios/Runner/Runner-Bridging-Header.h b/gsf/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..fae207f --- /dev/null +++ b/gsf/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/gsf/ios/Runner/Runner.entitlements b/gsf/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..02185fe --- /dev/null +++ b/gsf/ios/Runner/Runner.entitlements @@ -0,0 +1,17 @@ + + + + + aps-environment + development + com.apple.developer.associated-domains + + gsf019y3.app.link + gsf019y3-alternate.app.link + + com.apple.developer.healthkit + + com.apple.developer.healthkit.access + + + diff --git a/gsf/lib/api/ResponseManager.dart b/gsf/lib/api/ResponseManager.dart new file mode 100644 index 0000000..a8bae41 --- /dev/null +++ b/gsf/lib/api/ResponseManager.dart @@ -0,0 +1,18 @@ +class ResponseData { + ResponseData(this.message, this.status, {this.data}); + + final T? data; + final String message; + final ResponseStatus status; + + @override + String toString() => message; +} + +enum ResponseStatus { + SUCCESS, + + FAILED, + + PRIVATE, +} diff --git a/gsf/lib/api/StreamEnum.dart b/gsf/lib/api/StreamEnum.dart new file mode 100644 index 0000000..45d4b87 --- /dev/null +++ b/gsf/lib/api/StreamEnum.dart @@ -0,0 +1 @@ +enum requestResponseState { Error, DataReceived, Loading, SessionExpired } diff --git a/gsf/lib/api/base_manager.dart b/gsf/lib/api/base_manager.dart new file mode 100644 index 0000000..a8bae41 --- /dev/null +++ b/gsf/lib/api/base_manager.dart @@ -0,0 +1,18 @@ +class ResponseData { + ResponseData(this.message, this.status, {this.data}); + + final T? data; + final String message; + final ResponseStatus status; + + @override + String toString() => message; +} + +enum ResponseStatus { + SUCCESS, + + FAILED, + + PRIVATE, +} diff --git a/gsf/lib/api/network_api.dart b/gsf/lib/api/network_api.dart new file mode 100644 index 0000000..d87d739 --- /dev/null +++ b/gsf/lib/api/network_api.dart @@ -0,0 +1,123 @@ +import 'dart:convert'; +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import 'base_manager.dart'; +import 'package:http/http.dart' as http; + +class NetworkApi { + Dio dio = Dio(); + + // Future> postApiHttp( + // String token, String url, Map body) async { + // var headers = { + // "access-token": token + // // 'Authorization': 'Bearer $token', + // // 'Cookie': 'laravel_session=eyJpdiI6ImcwS2NYNlJYam4wcU1YUXJsYWZsb2c9PSIsInZhbHVlIjoiK0hvT3c5NmZFQ0NDajYxTUFaaVluWkpYbUkwYk1JbldyTVJwZitMN05zWnliaVdBNWZjTXpyVG5UODM1MTBaMzQwUCtNc3lGak5MQWRZamh2dWIvdzIxQnNVVWQrQi9NUi9YTS9PQWgxMlZHTENUNU0zY0VVazluNEplTFFvbGgiLCJtYWMiOiJkNjA0NjA4YWJhZDkxODA0YmQ2MTViNzc1MTg4OWRiODMzMjI5OGE0ZDI3MDRhMTAzM2E1MGY4ODQyMjI1NGIxIiwidGFnIjoiIn0%3D' + // }; + // var request = http.MultipartRequest('POST', Uri.parse(url)); + + // request.fields.addAll(body); + + // request.headers.addAll(headers); + + // http.StreamedResponse response = await request.send(); + // if (response.statusCode == 200) { + // var resp = await response.stream.bytesToString(); + // print(resp); + // return ResponseData( + // "success", + // ResponseStatusValue.SUCCESS, + // ); + // // return await response.stream.bytesToString(); + // } + // // if (response.statusCode == 400) { + // // var resp = await response.stream.bytesToString(); + // // var jsonResp = jsonDecode(resp); + // // print(jsonResp); + // // return ResponseData( + // // jsonResp["message"], + // // ResponseStatusValue.FAILED, + // // ); + // // // return await response.stream.bytesToString(); + // // } + // else { + // return ResponseData( + // response.reasonPhrase!, + // ResponseStatusValue.FAILED, + // ); + // // return response.reasonPhrase!; + // } + // } + + Future getApi(String url) async { + if (kDebugMode) { + print("api url is >>> $url"); + } + Response response; + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + try { + response = await dio.get(url, + options: + Options(headers: {"access-token": GetStorage().read('token')})); + } on Exception catch (_) { + return ResponseData( + 'Oops something Went Wrong', ResponseStatus.FAILED); + } + if (response.statusCode == 200) { + return ResponseData("success", ResponseStatus.SUCCESS, + data: response.data); + } else { + try { + return ResponseData( + response.data['message'].toString(), ResponseStatus.FAILED); + } catch (_) { + return ResponseData( + response.statusMessage!, ResponseStatus.FAILED); + } + } + } + + Future postApi({data, required String url}) async { + if (kDebugMode) { + print("data >>> $data"); + print("api url is >>> $url"); + } + var token = GetStorage().read('token'); + Response response; + // print("calling from token $token"); + try { + response = await dio.post(url, + data: data, + options: + Options(headers: {"access-token": GetStorage().read('token')})); + } on Exception catch (_) { + return ResponseData( + 'Opps something went wrong', ResponseStatus.FAILED); + } + + // if (kDebugMode) { + // print(response); + // } + + // print("response in post $response"); + + if (response.statusCode == 200) { + // print(response.data); + + return ResponseData("success", ResponseStatus.SUCCESS, + data: response.data); + } else { + try { + return ResponseData( + response.data['message'].toString(), ResponseStatus.FAILED); + } catch (_) { + return ResponseData( + response.statusMessage!, ResponseStatus.FAILED); + } + } + } +} diff --git a/gsf/lib/main.dart b/gsf/lib/main.dart new file mode 100644 index 0000000..4ff0a8f --- /dev/null +++ b/gsf/lib/main.dart @@ -0,0 +1,308 @@ +import 'dart:async'; +import 'dart:io'; + +// import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/scale/utils/local_storage.dart'; +import 'package:gsp_app/view_model/StepcountController.dart'; +import 'package:gsp_app/view_model/Stepcounts.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/views/pages/StepCount/HealthApp.dart'; +import 'package:gsp_app/views/pages/splash.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/other/ICDeviceManagerConfig.dart'; +import 'package:injectable/injectable.dart'; +import 'package:onesignal_flutter/onesignal_flutter.dart'; +import 'package:pedometer/pedometer.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'views/pages/intro/get_started.dart'; +import 'views/pages/test/age_defined.dart'; +import 'views/short_video_player/svp_lib/injection.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + configureInjection(Environment.prod); + await SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + await Firebase.initializeApp(); + const fatalError = true; + // Non-async exceptions + FlutterError.onError = (errorDetails) { + if (fatalError) { + // If you want to record a "fatal" exception + FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails); + // ignore: dead_code + } else { + // If you want to record a "non-fatal" exception + FirebaseCrashlytics.instance.recordFlutterError(errorDetails); + } + }; + // Async exceptions + PlatformDispatcher.instance.onError = (error, stack) { + if (fatalError) { + // If you want to record a "fatal" exception + FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + // ignore: dead_code + } else { + // If you want to record a "non-fatal" exception + FirebaseCrashlytics.instance.recordError(error, stack); + } + return true; + }; + await GetStorage.init(); + OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none); + OneSignal.shared.setAppId( + "41397809-455f-4d3a-bfa7-f190a4d078e4"); //f5869a6b-cf12-422d-91e3-286f9c0e1a62 + OneSignal.shared.setExternalUserId("8879"); + OneSignal.shared.promptUserForPushNotificationPermission().then( + (accepted) => print("Accepted Permission $accepted"), + ); + final status = await OneSignal.shared.getDeviceState(); + final String? playerId = status!.userId; + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString("playerId", playerId.toString()); + print("playerId $playerId"); + Get.put(AppDataController()); //init controller + + if (Platform.isAndroid) { + WidgetsFlutterBinding.ensureInitialized(); + [ + Permission.location, + Permission.storage, + Permission.bluetooth, + Permission.bluetoothConnect, + Permission.bluetoothScan, + Permission.activityRecognition, + ].request().then((value) { + runApp(const MyApp()); + }); + } else { + runApp(const MyApp()); + } +} + +class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + //pedometer module variables + late Stream _stepCountStream; + String _steps = '?'; + // Initialize a step count variable and a date variable + int? _appStepCount; + DateTime _currentDate = DateTime.now(); + + StepCountController stepController = Get.put(StepCountController()); + + @override + void initState() { + super.initState(); + // initShortClipLinks(); + LocalStorage.init(); + IcBluetoothSdk.instance.initSDK(ICDeviceManagerConfig()); + checkLocationStatus(); + // initPlatformState(); + //For step count Module + if (Platform.isAndroid) { + permissionDialog(); + getStepCountFromStorage(); + // checkAndUpdateDate(); + storeSteps(); + } + } + + storeSteps() { + Timer.periodic(const Duration(minutes: 1), (timer) { + Map updata = {"step_count": _appStepCount}; + StepCounts().storeSteps(updata); + }); + } + + permissionDialog() async { + // Map statuses = await [ + // Permission.activityRecognition, + // ].request(); + if (await Permission.activityRecognition.isGranted) { + initPlatformState(); + } + } + + int _storedStepCount = 0; + void initPlatformState() { + _stepCountStream = Pedometer.stepCountStream; + _stepCountStream.listen(onStepCount).onError(onStepCountError); + + if (!mounted) return; + } + + int finalSteps = 0; + void onStepCount(StepCount event) async { + if (_appStepCount == null) { + // Set the initial step count when the stream first emits a value + _storedStepCount = event.steps; + await storeFirstEmittedValueOfDay(_storedStepCount); + int stepsSinceLastStoredCount = event.steps - _storedStepCount; + stepController.appStepCountGlobal.value = stepsSinceLastStoredCount; + updateAndPersistStepCount(stepsSinceLastStoredCount); + _appStepCount = stepsSinceLastStoredCount; + } else { + _storedStepCount = await getFirstEmittedValueOfDay(); + finalSteps = event.steps - _storedStepCount; + _appStepCount = finalSteps; + stepController.appStepCountGlobal.value = finalSteps; + } + + // // Check if the step count is a multiple of 1000 + // if (_appStepCount! % 1000 == 0) { + // // Call the API to store steps + // Map updata = {"step_count": _appStepCount}; + // StepCounts().storeSteps(updata); + // } + } + + storeFirstEmittedValueOfDay(_storedStepCount) async { + final prefs = await SharedPreferences.getInstance(); + final currentDateKey = "emitted" + + _currentDate + .toLocal() + .toString() + .split(' ')[0]; // Use the date as the key + prefs.setInt(currentDateKey, _storedStepCount); + } + + getFirstEmittedValueOfDay() async { + final currentDateKey = + "emitted" + _currentDate.toLocal().toString().split(' ')[0]; + final prefs = await SharedPreferences.getInstance(); + final emittedValueCount = prefs.getInt(currentDateKey); + return emittedValueCount!; + } + +// Function to reset the daily step count + void resetDailyStepCount() { + _storedStepCount = 0; + } + +//-----+++++++++++----- old logic + // void initPlatformState() { + // _stepCountStream = Pedometer.stepCountStream; + // _stepCountStream.listen(onStepCount).onError(onStepCountError); + + // if (!mounted) return; + // } + + // // When you receive step count updates from the pedometer package: + // void onStepCount(StepCount event) { + // _steps = event.steps.toString(); + // _appStepCount = _appStepCount + 1; + // stepController.appStepCountGlobal.value = _appStepCount; + // updateAndPersistStepCount(null); + + // // Check if the step count is a multiple of 1000 + // if (_appStepCount % 1000 == 0) { + // // Call the API to store steps + // Map updata = {"step_count": _appStepCount}; + // StepCounts().storeSteps(updata); + // } + // } +//-----+++++++++++----- old logic end + void onStepCountError(error) { + print('onStepCountError: $error'); + setState(() { + _steps = 'Step Count not available'; + }); + } + +// //Function to check and update the current date +// void checkAndUpdateDate() { +// final today = DateTime.now(); +// if (today.day != _currentDate.day) { +// // The date has changed, reset the step count and update the current date +// updateAndPersistStepCount(0); +// _currentDate = today; +// } +// } + +// Function to retrieve the step count from storage during app initialization + void getStepCountFromStorage() async { + final currentDateKey = _currentDate.toLocal().toString().split(' ')[0]; + final prefs = await SharedPreferences.getInstance(); + final storedCount = prefs.getInt(currentDateKey); + setState(() { + _appStepCount = storedCount; + stepController.appStepCountGlobal.value = _appStepCount ?? 0; + }); + } + + // Function to update and persist the step count + void updateAndPersistStepCount(int? manualCount) async { + final prefs = await SharedPreferences.getInstance(); + final currentDateKey = _currentDate + .toLocal() + .toString() + .split(' ')[0]; // Use the date as the key + prefs.setInt(currentDateKey, manualCount!); + } + + checkLocationStatus() async { + Map statuses = await [ + Permission.location, + Permission.storage, + Permission.bluetooth, + ].request(); + // print(statuses[Permission.location]); + } + + @override + Widget build(BuildContext context) { + // initUniLinks(); + + //initOnesignal(); + final isloggedins = GetStorage().read("isLoggedIn") ?? false; + print('isloggedins $isloggedins'); + // var moodResult = await MoodOMeterService().getMoodOMeter(); + // // if() + // if(moodResult.responseStatus != ResponseStatus.success ){ + // return const HomePageSkeleton(); + // } + return GetMaterialApp( + // theme, + builder: (context, child) { + return MediaQuery( + data: MediaQuery.of(context).copyWith(textScaleFactor: 1), + child: child!, + ); + }, + theme: AppTheme.light(), + darkTheme: AppTheme.dark(), + themeMode: ThemseServices().theme, + // theme: ThemeData( + // fontFamily: 'Poppins', + // textTheme: Theme.of(context).textTheme.apply( + // bodyColor: Colors.white, + // displayColor: Colors.white, + // ), + // ), + debugShowCheckedModeBanner: false, + home: + //PeriodCalendar(), // + isloggedins ? const SplashScreen() : const Getstarted(), + // home: AgeInputForm(), + // home: StoryViewr(), + ); + } +} diff --git a/gsf/lib/modals/BioscalOverviewForallDates.dart b/gsf/lib/modals/BioscalOverviewForallDates.dart new file mode 100644 index 0000000..37c49f3 --- /dev/null +++ b/gsf/lib/modals/BioscalOverviewForallDates.dart @@ -0,0 +1,113 @@ +class BioscaleOverviewForallDates { + bool? success; + String? message; + Authorisation? authorisation; + + BioscaleOverviewForallDates({this.success, this.message, this.authorisation}); + + BioscaleOverviewForallDates.fromJson(Map json) { + success = json['success']; + message = json['message']; + authorisation = json['authorisation'] != null + ? Authorisation.fromJson(json['authorisation']) + : null; + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + data['message'] = message; + if (authorisation != null) { + data['authorisation'] = authorisation!.toJson(); + } + return data; + } +} + +class Authorisation { + List? userData; + + Authorisation({this.userData}); + + Authorisation.fromJson(Map json) { + if (json['user_data'] != null) { + userData = []; + json['user_data'].forEach((v) { + userData!.add(UserData1.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + if (userData != null) { + data['user_data'] = userData!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class UserData1 { + int? id; + int? userId; + String? muscleRate; + String? bodyFat; + String? skeletalMuscle; + String? protein; + String? bmr; + String? water; + String? age; + String? weight; + String? deletedAt; + String? createdAt; + String? updatedAt; + + UserData1( + {this.id, + this.userId, + this.muscleRate, + this.bodyFat, + this.skeletalMuscle, + this.protein, + this.bmr, + this.water, + this.age, + this.weight, + this.deletedAt, + this.createdAt, + this.updatedAt}); + + UserData1.fromJson(Map json) { + id = json['id']; + userId = json['user_id']; + muscleRate = json['muscle_rate']; + bodyFat = json['body_fat']; + skeletalMuscle = json['skeletal_muscle']; + protein = json['protein']; + bmr = json['bmr']; + water = json['water']; + age = json['age']; + weight = json['weight']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['user_id'] = userId; + data['muscle_rate'] = muscleRate; + data['body_fat'] = bodyFat; + data['skeletal_muscle'] = skeletalMuscle; + data['protein'] = protein; + data['bmr'] = bmr; + data['water'] = water; + data['age'] = age; + data['weight'] = weight; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/PastSessionModel.dart b/gsf/lib/modals/PastSessionModel.dart new file mode 100644 index 0000000..993c287 --- /dev/null +++ b/gsf/lib/modals/PastSessionModel.dart @@ -0,0 +1,253 @@ +class PastSessionModel { + bool? success; + String? message; + Result? result; + + PastSessionModel({this.success, this.message, this.result}); + + PastSessionModel.fromJson(Map json) { + success = json['success']; + message = json['message']; + result = + json['result'] != null ? Result.fromJson(json['result']) : null; + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + data['message'] = message; + if (result != null) { + data['result'] = result!.toJson(); + } + return data; + } +} + +class Result { + int? id; + String? activityName; + String? title; + String? mainActivityBanner; + String? description; + String? startDate; + String? endDate; + int? teacherId; + String? faqsId; + String? teaserUrl; + String? benefits; + String? preRequisites; + int? subscriptionId; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + List? schedule; + + Result( + {this.id, + this.activityName, + this.title, + this.mainActivityBanner, + this.description, + this.startDate, + this.endDate, + this.teacherId, + this.faqsId, + this.teaserUrl, + this.benefits, + this.preRequisites, + this.subscriptionId, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt, + this.schedule}); + + Result.fromJson(Map json) { + id = json['id']; + activityName = json['activity_name']; + title = json['title']; + mainActivityBanner = json['main_activity_banner']; + description = json['description']; + startDate = json['start_date']; + endDate = json['end_date']; + teacherId = json['teacher_id']; + faqsId = json['faqs_id']; + teaserUrl = json['teaser_url']; + benefits = json['benefits']; + preRequisites = json['pre_requisites']; + subscriptionId = json['subscription_id']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + if (json['schedule'] != null) { + schedule = []; + json['schedule'].forEach((v) { + schedule!.add(Schedule.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['activity_name'] = activityName; + data['title'] = title; + data['main_activity_banner'] = mainActivityBanner; + data['description'] = description; + data['start_date'] = startDate; + data['end_date'] = endDate; + data['teacher_id'] = teacherId; + data['faqs_id'] = faqsId; + data['teaser_url'] = teaserUrl; + data['benefits'] = benefits; + data['pre_requisites'] = preRequisites; + data['subscription_id'] = subscriptionId; + data['is_active'] = isActive; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + if (schedule != null) { + data['schedule'] = schedule!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Schedule { + int? id; + int? activityMasterId; + String? activityName; + String? activityTeaser; + String? activityLevel; + String? description; + String? startDate; + String? endDate; + int? subscriptionId; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + List? pastData; + + Schedule( + {this.id, + this.activityMasterId, + this.activityName, + this.activityTeaser, + this.activityLevel, + this.description, + this.startDate, + this.endDate, + this.subscriptionId, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt, + this.pastData}); + + Schedule.fromJson(Map json) { + id = json['id']; + activityMasterId = json['activity_master_id']; + activityName = json['activity_name']; + activityTeaser = json['activity_teaser']; + activityLevel = json['activity_level']; + description = json['description']; + startDate = json['start_date']; + endDate = json['end_date']; + subscriptionId = json['subscription_id']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + if (json['past_data'] != null) { + pastData = []; + json['past_data'].forEach((v) { + pastData!.add(PastData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['activity_master_id'] = activityMasterId; + data['activity_name'] = activityName; + data['activity_teaser'] = activityTeaser; + data['activity_level'] = activityLevel; + data['description'] = description; + data['start_date'] = startDate; + data['end_date'] = endDate; + data['subscription_id'] = subscriptionId; + data['is_active'] = isActive; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + if (pastData != null) { + data['past_data'] = pastData!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class PastData { + int? id; + int? activityMasterId; + int? activityScheduleId; + String? activityName; + String? image; + String? url; + int? duration; + String? date; + String? day; + String? deletedAt; + String? createdAt; + String? updatedAt; + + PastData( + {this.id, + this.activityMasterId, + this.activityScheduleId, + this.activityName, + this.image, + this.url, + this.duration, + this.date, + this.day, + this.deletedAt, + this.createdAt, + this.updatedAt}); + + PastData.fromJson(Map json) { + id = json['id']; + activityMasterId = json['activity_master_id']; + activityScheduleId = json['activity_schedule_id']; + activityName = json['activity_name']; + image = json['image']; + url = json['url']; + duration = json['duration']; + date = json['date']; + day = json['day']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['activity_master_id'] = activityMasterId; + data['activity_schedule_id'] = activityScheduleId; + data['activity_name'] = activityName; + data['image'] = image; + data['url'] = url; + data['duration'] = duration; + data['date'] = date; + data['day'] = day; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/PodcastsModel.dart b/gsf/lib/modals/PodcastsModel.dart new file mode 100644 index 0000000..f114ed2 --- /dev/null +++ b/gsf/lib/modals/PodcastsModel.dart @@ -0,0 +1,95 @@ +class PodcastsModel { + bool? success; + String? message; + Result? result; + + PodcastsModel({this.success, this.message, this.result}); + + PodcastsModel.fromJson(Map json) { + success = json['success']; + message = json['message']; + result = json['result'] != null ? Result.fromJson(json['result']) : null; + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + data['message'] = message; + if (result != null) { + data['result'] = result!.toJson(); + } + return data; + } +} + +class Result { + List? latestPodcast; + + Result({this.latestPodcast}); + + Result.fromJson(Map json) { + if (json['latestPodcast'] != null) { + latestPodcast = []; + json['latestPodcast'].forEach((v) { + latestPodcast!.add(LatestPodcast.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + if (latestPodcast != null) { + data['latestPodcast'] = latestPodcast!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class LatestPodcast { + int? id; + String? title; + String? description; + String? podcastUrl; + String? bannerImage; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + + LatestPodcast( + {this.id, + this.title, + this.description, + this.podcastUrl, + this.bannerImage, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt}); + + LatestPodcast.fromJson(Map json) { + id = json['id']; + title = json['title']; + description = json['description']; + podcastUrl = json['podcast_url']; + bannerImage = json['banner_image']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['title'] = title; + data['description'] = description; + data['podcast_url'] = podcastUrl; + data['banner_image'] = bannerImage; + data['is_active'] = isActive; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/QuizModel.dart b/gsf/lib/modals/QuizModel.dart new file mode 100644 index 0000000..3f9d404 --- /dev/null +++ b/gsf/lib/modals/QuizModel.dart @@ -0,0 +1,121 @@ +class QuizeModel { + bool? success; + String? message; + List? result; + + QuizeModel({this.success, this.message, this.result}); + + QuizeModel.fromJson(Map json) { + success = json['success']; + message = json['message']; + if (json['result'] != null) { + result = []; + json['result'].forEach((v) { + result!.add(Result.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + data['message'] = message; + if (result != null) { + data['result'] = result!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Result { + int? id; + String? questions; + String? scheduleTiming; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + List? answer; + + Result( + {this.id, + this.questions, + this.scheduleTiming, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt, + this.answer}); + + Result.fromJson(Map json) { + id = json['id']; + questions = json['questions']; + scheduleTiming = json['schedule_timing']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + if (json['answer'] != null) { + answer = []; + json['answer'].forEach((v) { + answer!.add(Answer.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['questions'] = questions; + data['schedule_timing'] = scheduleTiming; + data['is_active'] = isActive; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + if (answer != null) { + data['answer'] = answer!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Answer { + int? id; + int? questionId; + String? answers; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + + Answer( + {this.id, + this.questionId, + this.answers, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt}); + + Answer.fromJson(Map json) { + id = json['id']; + questionId = json['question_id']; + answers = json['answers']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['question_id'] = questionId; + data['answers'] = answers; + data['is_active'] = isActive; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/VersionControlModels.dart b/gsf/lib/modals/VersionControlModels.dart new file mode 100644 index 0000000..4ee54fa --- /dev/null +++ b/gsf/lib/modals/VersionControlModels.dart @@ -0,0 +1,72 @@ +class VersionControlModel { + Result? result; + String? status; + String? message; + + VersionControlModel({this.result, this.status, this.message}); + + VersionControlModel.fromJson(Map json) { + result = json['result'] != null ? Result.fromJson(json['result']) : null; + status = json['status']; + message = json['message']; + } + + Map toJson() { + final Map data = {}; + if (result != null) { + data['result'] = result!.toJson(); + } + data['status'] = status; + data['message'] = message; + return data; + } +} + +class Result { + int? id; + int? userId; + String? oldVersionAndroid; + String? newVersionAndroid; + String? oldVersionIos; + String? newVersionIos; + int? isActive; + String? createdAt; + String? updatedAt; + + Result( + {this.id, + this.userId, + this.oldVersionAndroid, + this.newVersionAndroid, + this.oldVersionIos, + this.newVersionIos, + this.isActive, + this.createdAt, + this.updatedAt}); + + Result.fromJson(Map json) { + id = json['id']; + userId = json['user_id']; + oldVersionAndroid = json['old_version_android']; + newVersionAndroid = json['new_version_android']; + oldVersionIos = json['old_version_ios']; + newVersionIos = json['new_version_ios']; + isActive = json['is_active']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['user_id'] = userId; + data['old_version_android'] = oldVersionAndroid; + data['new_version_android'] = newVersionAndroid; + data['old_version_ios'] = oldVersionIos; + data['new_version_ios'] = newVersionIos; + data['is_active'] = isActive; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/about_model.dart b/gsf/lib/modals/about_model.dart new file mode 100644 index 0000000..196102e --- /dev/null +++ b/gsf/lib/modals/about_model.dart @@ -0,0 +1,35 @@ +class AboutModel { + final String firstImgUrl; + final String title; + final String videoUrl; + final String description; + final String secondImgUrl; + final String leftImgLabel; + final String leftImgUrl; + final String rightImgLabel; + final String rightImgUrl; + + const AboutModel({ + required this.firstImgUrl, + required this.title, + required this.videoUrl, + required this.description, + required this.secondImgUrl, + required this.leftImgLabel, + required this.leftImgUrl, + required this.rightImgLabel, + required this.rightImgUrl, + }); + + factory AboutModel.fromJson(Map json) => AboutModel( + firstImgUrl: json['main_image'], + title: json['about_us_title'], + videoUrl: json['video_url'], + description: json['description'], + secondImgUrl: json['middel_image'], + leftImgLabel: json['about_us_first_image_title'], + leftImgUrl: json['aboutus_first_image'], + rightImgLabel: json['about_us_last_image_title'], + rightImgUrl: json['aboutus_last_image'], + ); +} diff --git a/gsf/lib/modals/diet_chart_model.dart b/gsf/lib/modals/diet_chart_model.dart new file mode 100644 index 0000000..945bee3 --- /dev/null +++ b/gsf/lib/modals/diet_chart_model.dart @@ -0,0 +1,12 @@ +class DietChartModel { + final String image; + + DietChartModel({ + required this.image, + }); + factory DietChartModel.fromJson(Map json) { + return DietChartModel( + image: json["image"], + ); + } +} diff --git a/gsf/lib/modals/edit_profile_model.dart b/gsf/lib/modals/edit_profile_model.dart new file mode 100644 index 0000000..194836f --- /dev/null +++ b/gsf/lib/modals/edit_profile_model.dart @@ -0,0 +1,51 @@ +class EditProfileModel { + final bool isSuccess; + final String message; + final String fullName; + final String contactNumber; + final String emailId; + final String? profilePicture; + final String description; + final String userBio; + final String gender; + final String age; + final String city; + final String fullAddress; + final String height; + final String weight; + + const EditProfileModel({ + required this.isSuccess, + required this.message, + required this.fullName, + required this.contactNumber, + required this.emailId, + required this.profilePicture, + required this.description, + required this.userBio, + required this.gender, + required this.age, + required this.city, + required this.fullAddress, + required this.height, + required this.weight, + }); + + factory EditProfileModel.fromJson(Map json) => + EditProfileModel( + isSuccess: json['success'], + message: json['message'], + fullName: json['result']['full_name'], + contactNumber: json['result']['contact_number'], + emailId: json['result']['email_id'], + profilePicture: json['result']['user_detail']['profile_picture'], + userBio: json['result']['user_detail']['user_bio'], + description: json['result']['user_detail']['description'], + gender: json['result']['user_detail']['gender'], + age: json['result']['user_detail']['age'], + city: json['result']['user_detail']['city'], + fullAddress: json['result']['user_detail']['full_address'], + height: json['result']['user_detail']['height'], + weight: json['result']['user_detail']['weight'], + ); +} diff --git a/gsf/lib/modals/faq_model.dart b/gsf/lib/modals/faq_model.dart new file mode 100644 index 0000000..784cfd4 --- /dev/null +++ b/gsf/lib/modals/faq_model.dart @@ -0,0 +1,22 @@ +class FaqModel { + final int categoryId; + final String categoryName; + final String question; + final String answer; + + const FaqModel({ + required this.categoryId, + required this.categoryName, + required this.question, + required this.answer, + }); + + factory FaqModel.fromJson(Map json) { + return FaqModel( + categoryId: json['category_id'] as int, + categoryName: json['category']['category_name'] as String, + question: json['question'] as String, + answer: json['answer'] as String, + ); + } +} diff --git a/gsf/lib/modals/home_modal.dart b/gsf/lib/modals/home_modal.dart new file mode 100644 index 0000000..7572049 --- /dev/null +++ b/gsf/lib/modals/home_modal.dart @@ -0,0 +1,4 @@ +class EmployeeModel { + final String? name, address; + EmployeeModel({required this.name, required this.address}); +} diff --git a/gsf/lib/modals/leaderboard_ranking_model.dart b/gsf/lib/modals/leaderboard_ranking_model.dart new file mode 100644 index 0000000..990cfd0 --- /dev/null +++ b/gsf/lib/modals/leaderboard_ranking_model.dart @@ -0,0 +1,170 @@ +class RnakingModel { + String gender; + String groupLevel; + List? userData; + + RnakingModel({ + required this.gender, + required this.groupLevel, + required this.userData, + }); + + factory RnakingModel.fromJson(Map json) { + var userDataList = json['user_data'] as List; + List userData = userDataList + .map((userDataJson) => RankingLeaderBoard.fromJson(userDataJson)) + .toList(); + return RnakingModel( + gender: json["gender"], + groupLevel: json["group_level"], + userData: userData, + ); + } +} + +class RankingLeaderBoard { + dynamic totalScore; + int userId; + UserRanking? user; + UserData? userData; + String progressBar; + String updatatedTime; + + RankingLeaderBoard( + {required this.userId, + required this.totalScore, + required this.user, + this.userData, + required this.progressBar, + required this.updatatedTime}); + + factory RankingLeaderBoard.fromJson(Map json) { + return RankingLeaderBoard( + userId: json["user_id"], + totalScore: json["total_score"], + // user: UserRanking.fromJson(json['user']), + user: json['user'] != null ? UserRanking.fromJson(json['user']) : null, + userData: json['user_data'] != null + ? UserData.fromJson(json['user_data']) + : null, + progressBar: json["progress_bar"], + updatatedTime: json["updated_at"], + ); + } +} + +class UserRanking { + String fullName; + String contactNumber; + String emailId; + String address; + // String fitnessGoal; + // String hearAbout; + List stepCountList; + UserRanking({ + required this.fullName, + required this.contactNumber, + required this.emailId, + required this.address, + required this.stepCountList, + // required this.fitnessGoal, + // required this.hearAbout, + }); + factory UserRanking.fromJson(Map json) { + var userDataList = json['step_count'] as List; + List userData = userDataList + .map((userDataJson) => StepCount1.fromJson(userDataJson)) + .toList(); + return UserRanking( + fullName: json['full_name'], + contactNumber: json['contact_number'], + emailId: json['email_id'], + address: json['address'], stepCountList: userData, + // stepCountList: json['step_count'], + // fitnessGoal: json['fitness_goal'], + // hearAbout: json['hear_about'], + ); + } +} + +class UserData { + String? profilePicture; + String? userBio; + String? description; + String? gender; + String? birthDate; + int? age; + String? city; + String? fullAddress; + dynamic height; + + UserData({ + this.profilePicture, + this.userBio, + this.description, + this.gender, + this.birthDate, + this.age, + this.city, + this.fullAddress, + required this.height, + }); + factory UserData.fromJson(Map json) { + return UserData( + profilePicture: json['profile_picture'], + userBio: json['user_bio'], + description: json['description'], + gender: json['gender'], + birthDate: json['birth_date'], + age: json['age'], + city: json['city'], + fullAddress: json['full_address'], + height: json['height'], + ); + } +} + +class StepCount1 { + int? id; + int? userId; + String? date; + int? stepCount; + int? points; + String? deletedAt; + String? createdAt; + String? updatedAt; + + StepCount1( + {this.id, + this.userId, + this.date, + this.stepCount, + this.points, + this.deletedAt, + this.createdAt, + this.updatedAt}); + + StepCount1.fromJson(Map json) { + id = json['id']; + userId = json['user_id']; + date = json['date']; + stepCount = json['step_count']; + points = json['points']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['user_id'] = userId; + data['date'] = date; + data['step_count'] = stepCount; + data['points'] = points; + data['deleted_at'] = deletedAt; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/live_session_model.dart b/gsf/lib/modals/live_session_model.dart new file mode 100644 index 0000000..091e4ab --- /dev/null +++ b/gsf/lib/modals/live_session_model.dart @@ -0,0 +1,144 @@ +import 'dart:convert'; + +class LiveActivityModel { + String activityName; + String activityDayBanner; + dynamic dayDuration; + String description; + String date; + String day; + String time; + Subscription subscription; + String zoomLink; + List scheduleData; + List activityData; + bool isActive; + + LiveActivityModel({ + required this.activityName, + required this.activityDayBanner, + required this.description, + required this.isActive, + required this.subscription, + required this.scheduleData, + required this.activityData, + required this.dayDuration, + required this.time, + required this.date, + required this.day, + required this.zoomLink, + }); + + factory LiveActivityModel.fromJson(Map json) { + return LiveActivityModel( + activityName: json['activity_name'], + activityDayBanner: json['activity_teaser'], + description: json['description'], + isActive: json['is_active'] == "1", + subscription: Subscription.fromJson(json['subscription']), + date: json["date"], + day: json["day"], + time: json["time"], + dayDuration: json["activity_duration"], + zoomLink: json["zoom_link"], + scheduleData: List.from( + json['schedule_data'].map( + (schedule) => Schedule.fromJson(schedule), + ), + ), + activityData: List.from( + json["activity_data"].map( + (activityData) => ActivityData.fromJson(activityData), + ), + ), + ); + } +} + +class Subscription { + String planName; + bool isActive; + + Subscription({required this.planName, required this.isActive}); + + factory Subscription.fromJson(Map json) { + return Subscription( + planName: json['plan_name'], + isActive: json['is_active'] == "1", + ); + } +} + +class Schedule { + int activityMasterId; + String? description; + String? zoomLink; + Schedule({ + required this.activityMasterId, + this.description, + this.zoomLink, + }); + + factory Schedule.fromJson(Map json) { + return Schedule( + activityMasterId: json['activity_master_id'], + description: json['description'], + zoomLink: json['zoom_link'], + ); + } +} + +class ActivityData { + String? activityName; + String? title; + String? mainActivityBanner; + String? description; + String? startDate; + String? endDate; + String? teaserUrl; + String? benefits; + String? preRequisites; + TearcherData techerData; + ActivityData({ + required this.activityName, + required this.title, + required this.mainActivityBanner, + required this.description, + required this.startDate, + required this.endDate, + required this.teaserUrl, + required this.benefits, + required this.preRequisites, + required this.techerData, + }); + factory ActivityData.fromJson(Map json) { + return ActivityData( + activityName: json["activity_name"], + title: json["title"], + mainActivityBanner: json["main_activity_banner"], + description: json["description"], + startDate: json["start_date"], + endDate: json["end_date"], + teaserUrl: json["teaser_url"], + benefits: json["benefits"], + preRequisites: json["pre_requisites"], + techerData: TearcherData.fromJson(json['teacher_data']), + ); + } +} + + +class TearcherData { + String teacherName; + String teacherImage; + TearcherData({ + required this.teacherName, + required this.teacherImage, + }); + factory TearcherData.fromJson(Map json) { + return TearcherData( + teacherName: json["teacher_title"], + teacherImage: json["teacher_image"], + ); + } +} diff --git a/gsf/lib/modals/manage_banner_model.dart b/gsf/lib/modals/manage_banner_model.dart new file mode 100644 index 0000000..aa52e59 --- /dev/null +++ b/gsf/lib/modals/manage_banner_model.dart @@ -0,0 +1,42 @@ +class ManageBannerModel { + final String bannerPath; + final int bannerPosition; + const ManageBannerModel({ + required this.bannerPath, + required this.bannerPosition, + }); + factory ManageBannerModel.fromJson(Map json) { + int bannerIndex = 0; + switch (json['block_position']) { + case "Position 1": + bannerIndex = 0; + break; + case "Position 2": + bannerIndex = 1; + break; + case "Position 3": + bannerIndex = 2; + break; + case "Position 4": + bannerIndex = 3; + break; + case "Position 5": + bannerIndex = 4; + break; + case "Position 6": + bannerIndex = 5; + break; + case "Position 7": + bannerIndex = 6; + break; + case "Position 8": + bannerIndex = 7; + break; + default: + } + return ManageBannerModel( + bannerPath: json['banner_path'] as String, + bannerPosition: bannerIndex, + ); + } +} diff --git a/gsf/lib/modals/member_modal.dart b/gsf/lib/modals/member_modal.dart new file mode 100644 index 0000000..c75f313 --- /dev/null +++ b/gsf/lib/modals/member_modal.dart @@ -0,0 +1,194 @@ +List memberDetails = [ + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare' + }, + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare1' + }, + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare2' + }, + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare3' + }, + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare4' + }, + { + 'img': 'assets/image/communityImg/member.png', + 'headTitle': 'The most personalized fitness app!', + 'desc': + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text since the 1500s, when an', + 'memberName': 'Chetan Tatkare5' + }, +]; + +// class MeetTheCommunityModel { +// final String? img, title, desc, memberName; +// final int? rating; +// bool isExpanded; + +// MeetTheCommunityModel({ +// this.img, +// this.title, +// this.desc, +// this.memberName, +// this.rating, +// this.isExpanded = false, +// }); +// factory MeetTheCommunityModel.fromJson(Map json) { +// return MeetTheCommunityModel( +// img: json['image'], +// title: json['title'], +// desc: json['description'], +// memberName: json['user_name'], +// rating: json['rating'], +// isExpanded: false, +// ); +// } +// } + +class MeetTheCommunityModel { + List? user; + + MeetTheCommunityModel({this.user}); + + MeetTheCommunityModel.fromJson(Map json) { + if (json['user'] != null) { + user = []; + json['user'].forEach((v) { + user!.add(new User.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.user != null) { + data['user'] = this.user!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class User { + int? id; + String? userName; + String? image; + String? title; + String? description; + String? rating; + String? isActive; + String? deletedAt; + String? createdAt; + String? updatedAt; + List? testimonialData; + + User( + {this.id, + this.userName, + this.image, + this.title, + this.description, + this.rating, + this.isActive, + this.deletedAt, + this.createdAt, + this.updatedAt, + this.testimonialData}); + + User.fromJson(Map json) { + id = json['id']; + userName = json['user_name']; + image = json['image']; + title = json['title']; + description = json['description']; + rating = json['rating']; + isActive = json['is_active']; + deletedAt = json['deleted_at']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + if (json['testimonial_data'] != null) { + testimonialData = []; + json['testimonial_data'].forEach((v) { + testimonialData!.add(new TestimonialData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['user_name'] = this.userName; + data['image'] = this.image; + data['title'] = this.title; + data['description'] = this.description; + data['rating'] = this.rating; + data['is_active'] = this.isActive; + data['deleted_at'] = this.deletedAt; + data['created_at'] = this.createdAt; + data['updated_at'] = this.updatedAt; + if (this.testimonialData != null) { + data['testimonial_data'] = + this.testimonialData!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class TestimonialData { + int? id; + int? testimonialId; + String? images; + int? isActive; + String? createdAt; + String? updatedAt; + + TestimonialData( + {this.id, + this.testimonialId, + this.images, + this.isActive, + this.createdAt, + this.updatedAt}); + + TestimonialData.fromJson(Map json) { + id = json['id']; + testimonialId = json['testimonial_id']; + images = json['images']; + isActive = json['is_active']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['testimonial_id'] = this.testimonialId; + data['images'] = this.images; + data['is_active'] = this.isActive; + data['created_at'] = this.createdAt; + data['updated_at'] = this.updatedAt; + return data; + } +} diff --git a/gsf/lib/modals/mood_o_meter_model.dart b/gsf/lib/modals/mood_o_meter_model.dart new file mode 100644 index 0000000..2a1f91a --- /dev/null +++ b/gsf/lib/modals/mood_o_meter_model.dart @@ -0,0 +1,6 @@ +class MoodOMeterModel { + final String moodOMeter; + const MoodOMeterModel({required this.moodOMeter}); + factory MoodOMeterModel.fromJson(Map json) => + MoodOMeterModel(moodOMeter: json['mood_o_meter']); +} diff --git a/gsf/lib/modals/notification_model.dart b/gsf/lib/modals/notification_model.dart new file mode 100644 index 0000000..1b0fd8c --- /dev/null +++ b/gsf/lib/modals/notification_model.dart @@ -0,0 +1,67 @@ +class NotificationModel { + bool success; + String message; + dynamic notificationCount; + List notificationList; + + NotificationModel({ + required this.success, + required this.message, + required this.notificationCount, + required this.notificationList, + }); + factory NotificationModel.fromJson(Map json) { + return NotificationModel( + success: json['success'], + message: json['message'], + notificationCount: json['notification_count'], + notificationList: (json['notification_list'] as List) + .map((item) => NotificationReadData.fromJson(item)) + .toList(), + ); + } +} + +class NotificationReadData { + String isRead; + dynamic notificationId; + NotificationData notificationMasterData; + String timesAgo; + + NotificationReadData({ + required this.isRead, + required this.notificationId, + required this.notificationMasterData, + required this.timesAgo, + }); + + factory NotificationReadData.fromJson(Map json) { + return NotificationReadData( + isRead: json["is_read"], + notificationId: json["notification_id"], + notificationMasterData: NotificationData.fromJson( + json['notification_master_data'], + ), + timesAgo: json["created_at"], + ); + } +} + +class NotificationData { + String title; + String message; + String isActive; + + NotificationData({ + required this.message, + required this.title, + required this.isActive, + }); + factory NotificationData.fromJson(Map json) { + return NotificationData( + message: json["messages"], + title: json["title"], + isActive: json["is_active"], + ); + } +} diff --git a/gsf/lib/modals/overview_scaledata_model.dart b/gsf/lib/modals/overview_scaledata_model.dart new file mode 100644 index 0000000..d8632a7 --- /dev/null +++ b/gsf/lib/modals/overview_scaledata_model.dart @@ -0,0 +1,42 @@ +class UserOverviewModelData { + final int id; + final int userId; + final String muscleRate; + final String bodyFat; + final String skeletalMuscle; + final String protein; + final String bmr; + final String water; + final String age; + final String weight; + final String updatedTime; + + UserOverviewModelData({ + required this.id, + required this.userId, + required this.muscleRate, + required this.bodyFat, + required this.skeletalMuscle, + required this.protein, + required this.bmr, + required this.water, + required this.age, + required this.weight, + required this.updatedTime, + }); + factory UserOverviewModelData.fromJson(Map json) { + return UserOverviewModelData( + id: json["id"], + userId: json["user_id"], + muscleRate: json["muscle_rate"], + bodyFat: json["body_fat"], + skeletalMuscle: json["skeletal_muscle"], + protein: json["protein"], + bmr: json["bmr"], + water: json["water"], + age: json["age"], + weight: json["weight"], + updatedTime: json["updated_at"], + ); + } +} diff --git a/gsf/lib/modals/past_activity_modal.dart b/gsf/lib/modals/past_activity_modal.dart new file mode 100644 index 0000000..f319f18 --- /dev/null +++ b/gsf/lib/modals/past_activity_modal.dart @@ -0,0 +1,104 @@ +class PastActivityModel { + + String? activityName; + String? title; + String? mainActivityBanner; + String? description; + String? teaserUrl; + String? benefits; + String? preRequisites; + List? schedule; + + PastActivityModel({ + + this.activityName, + this.title, + this.mainActivityBanner, + this.description, + this.teaserUrl, + this.benefits, + this.preRequisites, + this.schedule, + }); + + factory PastActivityModel.fromJson(Map json) { + int count = -1; + return PastActivityModel( + + activityName: json['activity_name'], + title: json['title'], + mainActivityBanner: json['main_activity_banner'], + description: json['description'], + teaserUrl: json['teaser_url'], + benefits: json['benefits'], + preRequisites: json['pre_requisites'], + schedule: List.from( + json['schedule'].map((scheduleJson) { + count++; + return Schedule.fromJson(scheduleJson,count); + }), + ), + ); + } +} + +class Schedule { + int index; + String? activityName; + String? activityTeaser; + String? activityDuration; + String? zoomLink; + List? pastData; + int? id; + + Schedule({ + required this.index, + this.activityName, + this.activityTeaser, + this.activityDuration, + this.zoomLink, + this.pastData, + this.id, + }); + + factory Schedule.fromJson(Map json, int ind) { + return Schedule( + index: ind, + id: json['id'], + activityName: json["activity_name"], + activityDuration: json["activity_duration"], + activityTeaser: json["activity_teaser"], + zoomLink: json["zoom_link"], + pastData: List.from( + json['past_data'].map((e) => PastData.fromJson(e)), + ), + ); + } +} + +class PastData { + String? activityName; + String? image; + String? url; + String? date; + String? day; + dynamic duration; + + PastData( + {this.activityName, + this.image, + this.url, + this.date, + this.day, + this.duration}); + factory PastData.fromJson(Map json) { + return PastData( + activityName: json["activity_name"], + image: json["image"], + url: json["url"], + date: json["date"], + day: json["day"], + duration: json["duration"], + ); + } +} diff --git a/gsf/lib/modals/past_session_model.dart b/gsf/lib/modals/past_session_model.dart new file mode 100644 index 0000000..f582e7f --- /dev/null +++ b/gsf/lib/modals/past_session_model.dart @@ -0,0 +1,137 @@ +import 'dart:convert'; +class Activity { + final bool success; + final String message; + final ActivityResult result; + + Activity({ + required this.success, + required this.message, + required this.result, + }); + + factory Activity.fromJson(Map json) { + return Activity( + success: json['success'], + message: json['message'], + result: ActivityResult.fromJson(json['result']), + ); + } +} + +class ActivityResult { + final String activityName; + final String title; + final String mainActivityBanner; + final String description; + final String startDate; + final String endDate; + final int teacherId; + final List benefits; + final List preRequisites; + final int subscriptionId; + final List schedule; + + ActivityResult({ + required this.activityName, + required this.title, + required this.mainActivityBanner, + required this.description, + required this.startDate, + required this.endDate, + required this.teacherId, + required this.benefits, + required this.preRequisites, + required this.subscriptionId, + required this.schedule, + }); + + factory ActivityResult.fromJson(Map json) { + final scheduleList = json['schedule'] as List; + List schedules = scheduleList.map((scheduleJson) { + return ActivitySchedule.fromJson(scheduleJson); + }).toList(); + + return ActivityResult( + activityName: json['activity_name'], + title: json['title'], + mainActivityBanner: json['main_activity_banner'], + description: json['description'], + startDate: json['start_date'], + endDate: json['end_date'], + teacherId: json['teacher_id'], + benefits: List.from(jsonDecode(json['benefits'])), + preRequisites: List.from(jsonDecode(json['pre_requisites'])), + subscriptionId: json['subscription_id'], + schedule: schedules, + ); + } +} + +class ActivitySchedule { + final String activityName; + final String activityTeaser; + final String description; + final String startDate; + final String endDate; + final int subscriptionId; + final List pastData; + bool isExpanded; // Add the isExpanded property + + ActivitySchedule({ + required this.activityName, + required this.activityTeaser, + required this.description, + required this.startDate, + required this.endDate, + required this.subscriptionId, + required this.pastData, + this.isExpanded = false, // Initialize isExpanded to false + }); + + factory ActivitySchedule.fromJson(Map json) { + final pastDataList = json['past_data'] as List; + List pastData = pastDataList.map((pastDataJson) { + return PastData.fromJson(pastDataJson); + }).toList(); + + return ActivitySchedule( + activityName: json['activity_name'], + activityTeaser: json['activity_teaser'], + description: json['description'], + startDate: json['start_date'], + endDate: json['end_date'], + subscriptionId: json['subscription_id'], + pastData: pastData, + ); + } +} + +class PastData { + final String activityName; + final String image; + final String url; + final int duration; + final String date; + final String day; + + PastData({ + required this.activityName, + required this.image, + required this.url, + required this.duration, + required this.date, + required this.day, + }); + + factory PastData.fromJson(Map json) { + return PastData( + activityName: json['activity_name'], + image: json['image'], + url: json['url'], + duration: json['duration'], + date: json['date'], + day: json['day'], + ); + } +} \ No newline at end of file diff --git a/gsf/lib/modals/rank_position.dart b/gsf/lib/modals/rank_position.dart new file mode 100644 index 0000000..ed24e1b --- /dev/null +++ b/gsf/lib/modals/rank_position.dart @@ -0,0 +1,19 @@ +class SelfRankPositions { + // bool success; + // String message; + dynamic dailyPosition; + + SelfRankPositions({ + // required this.success, + // required this.message, + required this.dailyPosition, + }); + + factory SelfRankPositions.fromJson(Map json) { + return SelfRankPositions( + // success: json["success"], + // message: json['message'], + dailyPosition: json["daily_position"], + ); + } +} diff --git a/gsf/lib/modals/set_mood_res_modal.dart b/gsf/lib/modals/set_mood_res_modal.dart new file mode 100644 index 0000000..520be81 --- /dev/null +++ b/gsf/lib/modals/set_mood_res_modal.dart @@ -0,0 +1,18 @@ +class SetMoodResponse { + bool? success; + String? progressBar; + + SetMoodResponse({this.success, this.progressBar}); + + SetMoodResponse.fromJson(Map json) { + success = json['success']; + progressBar = json['progress_bar']; + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + data['progress_bar'] = progressBar; + return data; + } +} diff --git a/gsf/lib/modals/share_thoughts.dart b/gsf/lib/modals/share_thoughts.dart new file mode 100644 index 0000000..cea6478 --- /dev/null +++ b/gsf/lib/modals/share_thoughts.dart @@ -0,0 +1,16 @@ +class ShareOurthoutghs { + final String userThoughts; + final String isActive; + + ShareOurthoutghs({ + required this.userThoughts, + required this.isActive, + }); + + factory ShareOurthoutghs.fromJson(Map json) { + return ShareOurthoutghs( + isActive: json['is_active'], + userThoughts: json['user_thought'], + ); + } +} diff --git a/gsf/lib/modals/short_clip_likes_model.dart b/gsf/lib/modals/short_clip_likes_model.dart new file mode 100644 index 0000000..0cedb73 --- /dev/null +++ b/gsf/lib/modals/short_clip_likes_model.dart @@ -0,0 +1,22 @@ +class ShortClipLikesModel { + // final int id; + // final int userId; + final int shortClipId; + bool isLiked; + + ShortClipLikesModel({ + // required this.id, + // required this.userId, + required this.shortClipId, + required this.isLiked, + }); + + factory ShortClipLikesModel.fromJson(Map json) { + return ShortClipLikesModel( + // id: json['id'], + // userId: json['user_id'], + shortClipId: json['short_clips_id'], + isLiked: json['is_like'].toString() == "0" ? true : false, + ); + } +} diff --git a/gsf/lib/modals/short_clip_model.dart b/gsf/lib/modals/short_clip_model.dart new file mode 100644 index 0000000..4feedaa --- /dev/null +++ b/gsf/lib/modals/short_clip_model.dart @@ -0,0 +1,26 @@ +class ShortClipModel { + final int id; + final String title; + final String description; + final String videoUrl; + final String thumbnailUrl; + int likes; + + ShortClipModel({ + required this.id, + required this.title, + required this.description, + required this.videoUrl, + required this.thumbnailUrl, + required this.likes, + }); + + factory ShortClipModel.fromJson(Map json) => ShortClipModel( + id: json['id'] as int, + title: json['video_title'] as String, + description: json['video_description'] as String, + videoUrl: json['video_url'] as String, + thumbnailUrl: json['thumbnail'] as String, + likes: json['likes'], + ); +} diff --git a/gsf/lib/modals/upcoming_session_model.dart b/gsf/lib/modals/upcoming_session_model.dart new file mode 100644 index 0000000..3c3747f --- /dev/null +++ b/gsf/lib/modals/upcoming_session_model.dart @@ -0,0 +1,208 @@ +import 'dart:convert'; + +class UpcomingSessionModel { + String activityName; + String activityDayBanner; + dynamic dayDuration; + String description; + // List benefits; + String date; + String day; + String time; + // List preRequisites; + Subscription subscription; + List scheduleData; + List activityData; + bool isActive; + // String zoomLink; + + UpcomingSessionModel({ + required this.activityName, + required this.activityDayBanner, + required this.description, + // required this.benefits, + // required this.preRequisites, + required this.isActive, + required this.subscription, + required this.scheduleData, + required this.activityData, + required this.dayDuration, + required this.time, + required this.date, + required this.day, + // required this.zoomLink, + }); + + factory UpcomingSessionModel.fromJson(Map json) { + return UpcomingSessionModel( + activityName: json['activity_name'], + activityDayBanner: json['activity_teaser'], + description: json['description'], + // // benefits: List.from(json['benefits'].map((x) => x.toString())), + // benefits: json['benefits'] is List + // ? (json['benefits'] as List) + // .map((x) => x.toString()) + // .toList() + // : jsonDecode(json['benefits']).map((x) => x.toString()).toList(), + // preRequisites: json['pre_requisites'] is List + // ? (json['pre_requisites'] as List) + // .map((x) => x.toString()) + // .toList() + // : jsonDecode(json['pre_requisites']) + // .map((x) => x.toString()) + // .toList(), + isActive: json['is_active'] == "1", + subscription: Subscription.fromJson(json['subscription']), + date: json["date"], + day: json["day"], + time: json["time"], + dayDuration: json["activity_duration"], + // zoomLink: json["zoom_link"], + + // // schedule: Schedule.fromJson(json['schedule']), + scheduleData: List.from( + json['schedule_data'].map( + (schedule) => Schedule.fromJson(schedule), + ), + ), + activityData: List.from( + json["activity_data"].map( + (activityData) => ActivityData.fromJson(activityData), + ), + ), + ); + } +} + +class Subscription { + String planName; + bool isActive; + + Subscription({required this.planName, required this.isActive}); + + factory Subscription.fromJson(Map json) { + return Subscription( + planName: json['plan_name'], + isActive: json['is_active'] == "1", + ); + } +} + +class Schedule { + int activityMasterId; + // String? activityName; + // String? activityTeaser; + // String? activityDuration; + // dynamic activityLevel; + String? description; + // String? benefits; + // String? preRequisites; + String? startDate; + // String? day; + // String? time; + String? zoomLink; + // dynamic subscriptionId; + // dynamic isActive; + + Schedule({ + required this.activityMasterId, + // this.activityName, + // this.activityTeaser, + // this.activityDuration, + // this.activityLevel, + this.description, + this.startDate, + // this.day, + // this.time, + // this.benefits, + // this.preRequisites, + this.zoomLink, + // this.subscriptionId, + // this.isActive, + }); + + factory Schedule.fromJson(Map json) { + return Schedule( + activityMasterId: json['activity_master_id'], + // activityName: json['activity_name'], + // activityTeaser: json['activity_teaser'], + // activityDuration: json['activity_duration'], + // activityLevel: json['activity_level'], + description: json['description'], + // benefits: json['benefits'], + // // // benefits: json['benefits'] is List + // // // ? (json['benefits'] as List) + // // // .map((x) => x.toString()) + // // // .toList() + // // // : jsonDecode(json['benefits']).map((x) => x.toString()).toList(), + // preRequisites: json['pre_requisites'], + // // // preRequisites: json['pre_requisites'] is List + // // // ? (json['pre_requisites'] as List) + // // // .map((x) => x.toString()) + // // // .toList() + // // // : jsonDecode(json['pre_requisites']) + // // // .map((x) => x.toString()) + // // // .toList(), + startDate: json['start_date'], + // day: json['day'], + // time: json['time'], + zoomLink: json['zoom_link'], + // subscriptionId: json['subscription_id'], + // isActive: json['is_active'] == "1", + ); + } +} + +class ActivityData { + String? activityName; + String? title; + String? mainActivityBanner; + String? description; + String? startDate; + String? endDate; + String? teaserUrl; + String? benefits; + String? preRequisites; + TearcherData techerData; + ActivityData({ + required this.activityName, + required this.title, + required this.mainActivityBanner, + required this.description, + required this.startDate, + required this.endDate, + required this.teaserUrl, + required this.benefits, + required this.preRequisites, + required this.techerData, + }); + factory ActivityData.fromJson(Map json) { + return ActivityData( + activityName: json["activity_name"], + title: json["title"], + mainActivityBanner: json["main_activity_banner"], + description: json["description"], + startDate: json["start_date"], + endDate: json["end_date"], + teaserUrl: json["teaser_url"], + benefits: json["benefits"], + preRequisites: json["pre_requisites"], + techerData: TearcherData.fromJson(json['teacher_data']), + ); + } +} + +class TearcherData { + String teacherName; + String teacherImage; + TearcherData({ + required this.teacherName, + required this.teacherImage, + }); + factory TearcherData.fromJson(Map json) { + return TearcherData( + teacherImage: json["teacher_image"], + teacherName: json["teacher_title"], + ); + } +} diff --git a/gsf/lib/modals/user_dashboard_chart_model.dart b/gsf/lib/modals/user_dashboard_chart_model.dart new file mode 100644 index 0000000..3edc02d --- /dev/null +++ b/gsf/lib/modals/user_dashboard_chart_model.dart @@ -0,0 +1,35 @@ +class UserDashboardChartModel { + bool success; + String message; + List monthlyData; + UserDashboardChartModel({ + required this.message, + required this.success, + required this.monthlyData, + }); + factory UserDashboardChartModel.fromJson(Mapjson) { + var monthlyPositionsData = json['monthly_positions'] as List; + List monthlyPositionsList = + monthlyPositionsData.map((data) => MonthLyPosition.fromJson(data)).toList(); + return UserDashboardChartModel( + message: json["message"], + success: json["success"], + monthlyData: monthlyPositionsList, + ); + } +} + +class MonthLyPosition { + dynamic position; + String month; + MonthLyPosition({ + required this.month, + this.position, + }); + factory MonthLyPosition.fromJson(Map json) { + return MonthLyPosition( + month: json["month"], + position: json["position"] == null?null:json['position'].toDouble(), + ); + } +} diff --git a/gsf/lib/modals/user_model.dart b/gsf/lib/modals/user_model.dart new file mode 100644 index 0000000..e3f9c81 --- /dev/null +++ b/gsf/lib/modals/user_model.dart @@ -0,0 +1,67 @@ +class UserModel { + final int id; + final String? token; + final String name; + final String phoneNo; + final String email; + + final String? profilePicUrl; + final String? bio; + final String? gender; + final int? age; + final String? address; + final String? city; + final double? height; + // final double? weight; + + const UserModel({ + required this.id, + required this.token, + required this.name, + required this.phoneNo, + required this.email, + this.profilePicUrl, + this.bio, + this.gender, + this.age, + this.address, + this.city, + this.height, + // this.weight, + }); + + factory UserModel.fromJson(Map json) { + Map? userDetails = + json["authorisation"]["user_data"]["user_detail"]; + return UserModel( + id: json["authorisation"]["user_data"]["id"], + token: json["authorisation"]["token"], + name: json["authorisation"]["user_data"]["full_name"], + phoneNo: json["authorisation"]["user_data"]["contact_number"], + email: json["authorisation"]["user_data"]["email_id"], + profilePicUrl: + userDetails == null ? null : userDetails["profile_picture"], + address: userDetails == null || userDetails["full_address"] == null + ? null + : userDetails["full_address"], + age: userDetails == null || userDetails["age"] == null + ? null + : userDetails["age"], + bio: userDetails == null || userDetails["user_bio"] == null + ? null + : userDetails["user_bio"], + city: userDetails == null || userDetails["city"] == null + ? null + : userDetails["city"], + gender: userDetails == null || userDetails["gender"] == null + ? null + : userDetails["gender"], + height: userDetails == null || userDetails["height"] == null + ? null + : double.parse(userDetails["height"].toString()), + // weight: userDetails == null + // ? null + // : double.parse(userDetails["weight"].toString()), + ); + } +} diff --git a/gsf/lib/modals/view_frnd_profile_model.dart b/gsf/lib/modals/view_frnd_profile_model.dart new file mode 100644 index 0000000..5c10ba4 --- /dev/null +++ b/gsf/lib/modals/view_frnd_profile_model.dart @@ -0,0 +1,62 @@ +class ViewfrndsProfileModel { + final int id; + final String name; + final String contactNumber; + final String emailId; + final UserDetailModel? userDetailModel; + + ViewfrndsProfileModel({ + required this.id, + required this.name, + required this.contactNumber, + required this.emailId, + this.userDetailModel, + }); + + factory ViewfrndsProfileModel.fromJson(Map json) { + return ViewfrndsProfileModel( + id: json['id'] as int, + name: json['full_name'] as String, + contactNumber: json['contact_number'] as String, + emailId: json['email_id'] as String, + userDetailModel: UserDetailModel.fromJson(json['user_detail']), + ); + } +} + +class UserDetailModel { + final String? profilePicture; + final String? userBio; + final String? description; + final String? gender; + final String? age; + final String? city; + final String? fullAddress; + final String? height; + final String? weight; + + const UserDetailModel({ + this.profilePicture, + this.userBio, + this.description, + this.gender, + this.age, + this.city, + this.fullAddress, + this.height, + this.weight, + }); + + factory UserDetailModel.fromJson(Map? json) => + UserDetailModel( + profilePicture: json != null ? json['profile_picture'] : null, + userBio: json != null ? json['user_bio'] : null, + description: json != null ? json['description'] : null, + gender: json != null ? json['gender'] : null, + age: json != null ? json['age'].toString() : null, + city: json != null ? json['city'] : null, + fullAddress: json != null ? json['full_address'] : null, + height: json != null ? json['height'].toString() : null, + weight: json != null ? json['weight'].toString() : null, + ); +} diff --git a/gsf/lib/modals/view_profile_model.dart b/gsf/lib/modals/view_profile_model.dart new file mode 100644 index 0000000..01a17b3 --- /dev/null +++ b/gsf/lib/modals/view_profile_model.dart @@ -0,0 +1,46 @@ +class ViewProfileModel { + final String name; + final String contactNumber; + final String emailId; + final String profilePicture; + final String userBio; + final String description; + final String gender; + final String age; + final String city; + final String fullAddress; + final String height; + final String weight; + + ViewProfileModel({ + required this.name, + required this.contactNumber, + required this.emailId, + required this.profilePicture, + required this.userBio, + required this.description, + required this.gender, + required this.age, + required this.city, + required this.fullAddress, + required this.height, + required this.weight, + }); + + factory ViewProfileModel.fromJson(Map json) => + ViewProfileModel( + name: json['result']['full_name'] as String, + contactNumber: json['result']['contact_number'] as String, + emailId: json['result']['email_id'] as String, + profilePicture: + json['result']['user_detail']['profile_picture'] as String, + userBio: json['result']['user_detail']['user_bio'] as String, + description: json['result']['user_detail']['description'] as String, + gender: json['result']['user_detail']['gender'] as String, + age: json['result']['user_detail']['age'] as String, + city: json['result']['user_detail']['city'] as String, + fullAddress: json['result']['user_detail']['full_address'] as String, + height: json['result']['user_detail']['height'] as String, + weight: json['result']['user_detail']['weight'] as String, + ); +} diff --git a/gsf/lib/repository/endpoints.dart b/gsf/lib/repository/endpoints.dart new file mode 100644 index 0000000..2bb3cd8 --- /dev/null +++ b/gsf/lib/repository/endpoints.dart @@ -0,0 +1,61 @@ +//chaitanya +class Endpoints { + static const _staging = "https://gsf.betadelivery.com/api/"; + static const _base = "https://thegsf.co/api/"; + + static const login = _base + "login"; + static const generateOtp = _base + "otp/generate"; + static const verifyOtp = _base + "otp/create_new_pass_with_otp"; + static const updateProfile = _base + "update_profile"; + static const fetchUserData = _base + "get_user_data"; + static const updatePassword = _base + "otp/update_password"; + static const manageBanner = _base + "manageBanner"; + static const viewFriendsProfile = _base + "view_profile_frds"; + static const addUserOverView = _base + "addUserOverview"; + static const userScaleData = _base + "getUserOverview"; + static const userScaleDataWithDate = _base + "showUserOverview"; + static const userScaleDataFilter = _base + "showUserOverview_new"; + + static const getThoughtData = _base + "GetThoughts"; + static const getPastSessionVideo = _base + "getManagePastSession"; + static const dietChartPlan = _base + "getDietCategories"; + static const moodOmeterGet = _base + "getMoodOMeter"; + // static const dietChartPplan = _base + "https://gsf.betadelivery.com/api/getDietCategories?diet_categories=veg" + static const setMoodOMeter = _base + "storeMoodOMeter"; + static const getMoodOMeterValue = _base + "getMoodOMeterValue"; + + static const getTestimonial = _base + "getTestimonial"; + static const getFaq = _base + "getFaq"; + static const getUserData = _base + "get_user_data"; + + static const getLiveActivity = _base + "getManageActivity"; + static const getUpcomingActivity = _base + "getManageActivitySchedule"; + static const getUpcomingActivityUtc = _base + "getManageActivityScheduleUTC"; + static const getPastActivity = _base + "getManagePastSession"; + static const getLeaderboraderRankingOld = _base + "getUserRanking"; + static const getLeaderboraderRanking = _base + "get_user_data_filterUsers"; + static const getLeaderboraderRankingHome = + _base + "get_user_data_filterUsers_home"; + static const getNotificationCountList = _base + "get_notification_count"; + static const readNotification = _base + "update_read_status"; + static const deleteNotification = _base + "delete_notification"; + static const getDashboardChart = _base + "get_user_position"; + static const getLeaderBoardRankPosition = _base + "get_user_position_daily"; + static const setLeaderBoardRankYealyPosition = _base + "get_position"; + static const getShortCLips = _base + "getShortClips"; + static const postLikeShortCLips = _base + "likeShortClips"; + static const getLikeShortCLips = _base + "getShortClipsLikes"; + static const postContactUs = _base + "storeContactUs"; + static const storeSteps = _base + "step_count"; + static const resetPassword = _base + "reset_pass"; + static const generateOTPV2 = _base + "otp/generate"; + static const verifyOTPV2 = _base + "otp/validate_otp"; + static const storeVersion = _base + "getOlderVersion"; + static const getNewVersion = _base + "getNewVersion"; + static const getquiz = _base + "getQuiz"; + static const storePoints = _base + "storeQuizPoints"; + static const showQuiz = _base + "getUerQuizpoints"; + static const storeDates = _base + "storeDates"; + static const getPeriodDates = _base + "getPeriodDates"; + static const getPodcast = _base + "getPodcast"; +} diff --git a/gsf/lib/repository/response_data.dart b/gsf/lib/repository/response_data.dart new file mode 100644 index 0000000..4eed820 --- /dev/null +++ b/gsf/lib/repository/response_data.dart @@ -0,0 +1,11 @@ +enum ResponseStatus { success, failed, expired, error } + +class ResponseModel { + final ResponseStatus responseStatus; + final dynamic data; + + const ResponseModel({ + required this.responseStatus, + required this.data, + }); +} diff --git a/gsf/lib/repository/services/StoreLauncher.dart b/gsf/lib/repository/services/StoreLauncher.dart new file mode 100644 index 0000000..aaf80db --- /dev/null +++ b/gsf/lib/repository/services/StoreLauncher.dart @@ -0,0 +1,30 @@ +import 'dart:io'; + +import 'package:get/get.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class StoreLauncher extends GetxController { + Future launchStore() async { + const String playStoreUrl = + 'https://play.google.com/store/apps/details?id=com.getsetfit.gsf'; + const String appStoreUrl = + 'https://apps.apple.com/in/app/getsetfit/id6455990055'; + + String storeUrl; + + if (Platform.isAndroid) { + storeUrl = playStoreUrl; + } else if (Platform.isIOS) { + storeUrl = appStoreUrl; + } else { + throw 'Unsupported platform'; + } + + if (await canLaunchUrl(Uri.parse(storeUrl))) { + await launchUrl(Uri.parse(storeUrl), + mode: LaunchMode.externalApplication); + } else { + throw 'Could not launch $storeUrl'; + } + } +} diff --git a/gsf/lib/repository/services/about_service.dart b/gsf/lib/repository/services/about_service.dart new file mode 100644 index 0000000..6df42d1 --- /dev/null +++ b/gsf/lib/repository/services/about_service.dart @@ -0,0 +1,17 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/about_model.dart'; +import 'package:http/http.dart' as http; + +class AboutService { + Future> fetchAbout() async { + http.Response response = await http.get( + Uri.parse("https://gsf.wdipl.com/api/getAboutUs"), + headers: {"access-token": GetStorage().read('token')}, + ); + var parsed = jsonDecode(response.body)['user'] as List; + return parsed.map((e) => AboutModel.fromJson(e)).toList(); + } +} diff --git a/gsf/lib/repository/services/cj/diet_chart_service.dart b/gsf/lib/repository/services/cj/diet_chart_service.dart new file mode 100644 index 0000000..ca401d3 --- /dev/null +++ b/gsf/lib/repository/services/cj/diet_chart_service.dart @@ -0,0 +1,43 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +import '../../../modals/diet_chart_model.dart'; +import '../../../view_model/diet_chart_controller.dart'; + +class DietChartServices extends GetConnect { + DietChartController dietChartController = Get.put(DietChartController()); + + Future getDietChartPlan() async { + final String vegNnoveg = dietChartController.vegNveg.value; + Response response = await post(Endpoints.dietChartPlan, { + "diet_categories": vegNnoveg + }, headers: { + "access-token": GetStorage().read("token"), + }); + + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + // debugPrint('DATA REPOSNSE ${data["result"][0]["image"]}'); + bool isAiuthenticated = data["success"] ?? false; + + if (isAiuthenticated) { + var authData = data['result'] as List; + return ResponseModel( + responseStatus: ResponseStatus.success, + data: authData.map((e) => DietChartModel.fromJson(e)).toList(), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/generate_otp_service.dart b/gsf/lib/repository/services/cj/generate_otp_service.dart new file mode 100644 index 0000000..6055e8b --- /dev/null +++ b/gsf/lib/repository/services/cj/generate_otp_service.dart @@ -0,0 +1,34 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; + +import '../../endpoints.dart'; +import '../../response_data.dart'; + +class GenerateOtpService extends GetConnect { + Future generateOtp({required String email}) async { + Response response = await post( + Endpoints.generateOtp, + {"email_id": email}, + ); + if (response.body == null || response.body.contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = jsonDecode(response.body); + if (data['status'] == 200) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: data['user_id'], + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/get_notification_count_service.dart b/gsf/lib/repository/services/cj/get_notification_count_service.dart new file mode 100644 index 0000000..d02e999 --- /dev/null +++ b/gsf/lib/repository/services/cj/get_notification_count_service.dart @@ -0,0 +1,68 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../../../modals/notification_model.dart'; +import '../../response_data.dart'; + +class GetNotificationCount extends GetConnect { + Future getNotificationCout() async { + var response = await get( + // Endpoints.getNotificationCountList, + Endpoints.getNotificationCountList, + headers: { + "access-token": GetStorage().read('token'), + }, + ); + // print('Notification data ${response.body}'); + + if (response.body == null && response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + var data = response.body; + bool isAuthenticated = data["success"] ?? false; + // debugPrint('Notifiction success ${data["success"]}'); + + if (isAuthenticated) { + // var authData = data; + // print('AUTHDATA NOTIFICATION ${authData}'); + return ResponseModel( + responseStatus: ResponseStatus.success, + data: NotificationModel.fromJson(data as Map), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } + } + } + + // read notification functionality + readNotification(notificationId) async { + var response = await post(Endpoints.readNotification, { + "notification_id": notificationId + }, headers: { + "access-token": GetStorage().read("token"), + }); + + // print('Response of read API ${response}'); + } + + // delete notification functionality + deleteNnotification(notificationId) async { + var response = await post(Endpoints.deleteNotification, { + "notification_id": notificationId + }, headers: { + "access-token": GetStorage().read("token"), + }); + print('API Response of delete API $response '); + } +} diff --git a/gsf/lib/repository/services/cj/leader_board_ranking.dart b/gsf/lib/repository/services/cj/leader_board_ranking.dart new file mode 100644 index 0000000..9a68ce2 --- /dev/null +++ b/gsf/lib/repository/services/cj/leader_board_ranking.dart @@ -0,0 +1,174 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/leaderboard_ranking_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +import '../../../modals/rank_position.dart'; +import '../../../view_model/my_ranking_controller.dart'; + +class RankingLeaderboard extends GetConnect { + MyRankingController myRankingController = Get.put(MyRankingController()); + + String generateGroupLevel(String groupLevel) { + if (groupLevel == "Swole") { + // myRankingController.groupLevel.value = "Swole"; + return "elites"; + } else if (groupLevel == "Up Steppers") { + // myRankingController.groupLevel.value = "Up Steppers"; + return "gameChangers"; + } else if (groupLevel == "Rookie") { + // myRankingController.groupLevel.value = "Underdogs"; + return "underdogs"; + } + return "elites"; + } + + String generateGender(String gender) { + if (gender == "Male") { + // myRankingController.gender.value = "Male"; + return "male"; + } else if (gender == "Female") { + // myRankingController.gender.value = "Female"; + return "female"; + } else if (gender == "All") { + // myRankingController.gender.value = "All"; + return "all"; + } + return "all"; + } + + Future getLeaderboardRanking( + {required String gender, required String groupLevel}) async { + var response = await post(Endpoints.getLeaderboraderRanking, { + "group_level": generateGroupLevel(groupLevel), + "gender": generateGender(gender) + }, headers: { + "access-token": GetStorage().read("token"), + }); + // debugPrint('LeaderBoard ranking ${response.body}'); + + if (response.body == null && + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + // var allData = data["user_ranking"]; + // var allData = data["user_data"]; + // print("All data of ranking users $data"); + // ["user_data"]; + return ResponseModel( + responseStatus: ResponseStatus.success, + data: RnakingModel.fromJson(data as Map)); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } + + Future getLeaderBoardDataWithoutFilter() async { + var response = await post(Endpoints.getLeaderboraderRanking, {}, headers: { + "access-token": GetStorage().read("token"), + }); + + // print('Ranking without filter ${response.body}'); + + if (response.body == null && + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + // var allData = data["user_data"]; + // var allData = data["user_data"]; + // print("All data of ranking users $allData"); + // ["user_data"]; + return ResponseModel( + responseStatus: ResponseStatus.success, + data: RnakingModel.fromJson(data as Map)); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } + + Future getLeaderBoardDataWithoutFilterHome() async { + var response = await post(Endpoints.getLeaderboraderRanking, { "group_level": "elites",}, headers: { + "access-token": GetStorage().read("token"), + }); + + // print('Ranking without filter ${response.body}'); + + if (response.body == null && + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + // var allData = data["user_data"]; + // var allData = data["user_data"]; + // print("All data of ranking users $allData"); + // ["user_data"]; + return ResponseModel( + responseStatus: ResponseStatus.success, + data: RnakingModel.fromJson(data as Map)); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } + + + + + Future getLeaderBoardRankPositions() async { + var response = await get(Endpoints.getLeaderBoardRankPosition, headers: { + "access-token": GetStorage().read("token"), + }); + + if (response.body == null && + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: SelfRankPositions.fromJson(data as Map), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } + } + } + + setLeaderBoardRankYearlyPositions() async { + var response = + await get(Endpoints.setLeaderBoardRankYealyPosition, headers: { + "access-token": GetStorage().read("token"), + }); + } +} diff --git a/gsf/lib/repository/services/cj/live_activity_service.dart b/gsf/lib/repository/services/cj/live_activity_service.dart new file mode 100644 index 0000000..de961c8 --- /dev/null +++ b/gsf/lib/repository/services/cj/live_activity_service.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/live_session_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +class LiveActivityServices extends GetConnect { + Future getLiveActivitydata() async { + var response = await get(Endpoints.getLiveActivity, headers: { + "access-token": GetStorage().read("token"), + }); + + // debugPrint('check reponse of getActivity data ${response.body}'); + + if (response.body == null && response.body.contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + //debugPrint('result of data ${data["result"]}'); + bool isAuthenticated = data["success"] ?? false; + //print('DATA ALL ${data['result']}'); + + if (isAuthenticated) { + var authData = data["result"] as List; + // print('AUTHDATA NEWS of Live Data ${authData}'); + + // var filteredArray = authData.where((data) { + // return data.containsKey("schedule") && + // data["schedule"] != null && + // data["schedule"].isNotEmpty; + // }).toList(); + + // print('filteredArray ${filteredArray}'); + + return ResponseModel( + responseStatus: ResponseStatus.success, + data: authData + .map( + (e) => LiveActivityModel.fromJson(e), + ) + .toList(), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/login_service.dart b/gsf/lib/repository/services/cj/login_service.dart new file mode 100644 index 0000000..024b6a6 --- /dev/null +++ b/gsf/lib/repository/services/cj/login_service.dart @@ -0,0 +1,47 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../../../modals/user_model.dart'; +import '../../response_data.dart'; + +class LoginService extends GetConnect { + Future loginUser({ + required String email, + required String password, + }) async { + Response response = await post( + Endpoints.login, + {"email_id": email, "password": password}, + ); + // print('RESPONSEBODY ${response.body}'); + if (response.body == null || + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else if (response.statusCode == 201) { + return const ResponseModel( + responseStatus: ResponseStatus.expired, + data: null, + ); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + if (isAuthenticated) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: UserModel.fromJson(data), + ); + } else { + print('check response'); + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/manage_banner_service.dart b/gsf/lib/repository/services/cj/manage_banner_service.dart new file mode 100644 index 0000000..623d01e --- /dev/null +++ b/gsf/lib/repository/services/cj/manage_banner_service.dart @@ -0,0 +1,78 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; + +import '../../../modals/manage_banner_model.dart'; +import '../../endpoints.dart'; +import '../../response_data.dart'; + +ManageBannerModel? bannerManager; +AppDataController appDataController = Get.find(); + +class ManageBannerService extends GetConnect { +/* + Future manageBanner() async { + try { + var response = await http.get( + Uri.parse('https://gsf.wdipl.com/api/manageBanner'), + headers: {'access-token': GetStorage().read('token')}, + ); + var parsed = jsonDecode(response.body) as Map; + + if (parsed['status'] == 'Token is Invalid') { + Get.offAll(const SignIn()); + Get.snackbar( + 'Please login again', + 'Something went wrong', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor, + duration: const Duration(milliseconds: 1500), + ); + } + // print("manage banner api response ${parsed['result']['banner_path']}"); + return ManageBannerModel.fromJson(parsed['result']); + } catch (e) { + debugPrint(e.toString()); + } + return manageBanner(); + } +*/ + Future fetchManageBanner() async { + Response response = await get( + Endpoints.manageBanner, + headers: {"access-token": GetStorage().read("token")}, + ); + //print('fetchManageBanner ${response.body}'); + if (response.body == null || + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + //print('fetchManageBanner all data ${response.body}'); + Map data = response.body; + bool success = data["success"] ?? false; + if (success) { + bannerManager = ManageBannerModel.fromJson(data['result']); + handleBannerDatareceivedFrom(); + return ResponseModel( + responseStatus: ResponseStatus.success, + data: ManageBannerModel.fromJson(data['result']), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} + +handleBannerDatareceivedFrom() { + appDataController.bannerPath.value = bannerManager!.bannerPath; + appDataController.bannerPosition.value = bannerManager!.bannerPosition; +} diff --git a/gsf/lib/repository/services/cj/moodOmeter_services.dart b/gsf/lib/repository/services/cj/moodOmeter_services.dart new file mode 100644 index 0000000..d4ea249 --- /dev/null +++ b/gsf/lib/repository/services/cj/moodOmeter_services.dart @@ -0,0 +1,122 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/home_controller.dart'; +import 'package:http/http.dart' as http; + +class MoodOMeterService extends GetConnect { + HomeApiController homeApiController = Get.put(HomeApiController()); + + Future getMoodOMeter() async { + + Response response = await get( + Endpoints.moodOmeterGet, + headers: { + "access-token": GetStorage().read("token"), + }, + ); + + if (response.body == null || + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + var moodOmeterResult = data["result"]; + + // print('moodOmeterResult new $moodOmeterResult'); + homeApiController.setMoodOMeterResult(moodOmeterResult); + // print("moodOmeterResult data $moodOmeterResult"); + + + if (moodOmeterResult != null) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: moodOmeterResult, + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } + + Future uploadMood(String mood) async { + http.Response response = await http.post( + //Uri.parse("https://gsf.wdipl.com/api/storeMoodOMeter"), + Uri.parse(Endpoints.setMoodOMeter), + + headers: {"access-token": GetStorage().read('token')}, + body: {"mood_o_meter": mood}, + ); + // print("uploadMood $response"); + return response; + } + // Future setMoodOMeter2() async{ + // Response response = await post( + // Endpoints.moodOmeterGet, + // {"mood_o_meter": "Happppppyyyyy"}, + // headers: {"access-token": GetStorage().read("token")}, + + // ); + // if (response.body == null || response.body.toString().contains("")) { + // return const ResponseModel( + // responseStatus: ResponseStatus.error, + // data: null, + // ); + // } else { + // Map data = response.body; + // // var moodOmeterResult = data["result"]; + // // homeApiController.setMoodOMeterResult(moodOmeterResult); + // // print("moodOmeterResult $moodOmeterResult"); + + // if (data != null) { + // return ResponseModel( + // responseStatus: ResponseStatus.success, + // data: null, + // ); + // } else { + // return const ResponseModel( + // responseStatus: ResponseStatus.failed, + // data: null, + // ); + // } + // } + // } + + // Future> setMoodOMeter(Map body)async{ + // final response = await NetworkApi().postApiHttp( + // GetStorage().read("token"), + // Endpoints.setMoodOMeter, + // body + // ); + // return response; + // } + + // postMethod(){ + // var headers = { + // 'access-token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2dzZi5iZXRhZGVsaXZlcnkuY29tL2FwaS9sb2dpbiIsImlhdCI6MTY4NTk3NjEyMSwibmJmIjoxNjg1OTc2MTIxLCJqdGkiOiJiTlBhS0RrQlA2QzRaNjBWIiwic3ViIjoiMiIsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.oSiBU7fGki0bNHZ6xy5YfvzowlY8UuBlKRu8r-vjIBU', + // 'Content-Type': 'application/json' + // }; + // var request = http.Request('POST', Uri.parse('https://gsf.betadelivery.com/api/storeMoodOMeter')); + // request.body = json.encode({ + // "mood_o_meter": "Happppppyyyyy" + // }); + // request.headers.addAll(headers); + + // http.StreamedResponse response = await request.send(); + + // if (response.statusCode == 200) { + // print(await response.stream.bytesToString()); + // } + // else { + // print(response.reasonPhrase); + // } + + // } +} diff --git a/gsf/lib/repository/services/cj/overview_service.dart b/gsf/lib/repository/services/cj/overview_service.dart new file mode 100644 index 0000000..8850734 --- /dev/null +++ b/gsf/lib/repository/services/cj/overview_service.dart @@ -0,0 +1,105 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/overview_scaledata_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../../../views/pages/bioMaker/controller.dart'; +import '../../response_data.dart'; + +class OverViewServices extends GetConnect { + final AController aController = Get.put(AController()); + Future addUserOverviewData({ + required String muscleRate, + required String bodyFat, + required String skeletalMuscle, + required String protein, + required String bmr, + required String water, + required String age, + required String weight, + }) async { + FormData scaleData = FormData({ + "muscle_rate": muscleRate, + "body_fat": bodyFat, + "skeletal_muscle": skeletalMuscle, + "protein": protein, + "bmr": bmr, + "water": water, + "age": age, + "weight": weight + }); + Response response = await post( + Endpoints.addUserOverView, + scaleData, + headers: {"access-token": GetStorage().read("token")}, + ); + print('RESPONSEBODY ${response.body}'); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + // print('Item data ${data}'); + bool isAuthenticated = data["success"] ?? false; + if (isAuthenticated) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: data["message"], + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } + + Future getSuerOverviewData(String currentDate) async { + // final String params = currentDate; + final String params1 = aController.getDAte.value; + // final aController + print('tapped date $params1'); + Response response = await get( + Endpoints.userScaleDataWithDate + '?created_at=$params1', + headers: {"access-token": GetStorage().read("token")}, + ); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + + if (data["authorisation"]["user_data"] == null) { + aController.dataNull.value = true; + // print('aController.dataNull.value ${aController.dataNull.value}'); + } + print('Oveiview data as per datas ${data}'); + + if (data["authorisation"]["user_data"] != null) { + aController.dataNull.value = false; + // print('aController.dataNull.value false ${aController.dataNull.value}'); + } + if (isAuthenticated) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: UserOverviewModelData.fromJson( + data["authorisation"]["user_data"], + ), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/past_session_service.dart b/gsf/lib/repository/services/cj/past_session_service.dart new file mode 100644 index 0000000..154d36e --- /dev/null +++ b/gsf/lib/repository/services/cj/past_session_service.dart @@ -0,0 +1,41 @@ +// import 'dart:convert'; + +// import 'package:get/get.dart'; +// import 'package:get_storage/get_storage.dart'; +// import 'package:gsp_app/modals/past_session_model.dart'; +// import 'package:gsp_app/repository/endpoints.dart'; +// import 'package:gsp_app/repository/response_data.dart'; + +// class PastSessionservice extends GetConnect { +// Future getpastSessionData() async { +// Response response = await get( +// Endpoints.getPastSessionVideo, +// headers: {"access-token": GetStorage().read("token")}, +// ); +// if (response.body == null || response.body.contains("")) { +// return const ResponseModel( +// responseStatus: ResponseStatus.error, +// data: null, +// ); +// } else { +// Map data = jsonDecode(response.body); +// bool isAuthenticated = data["success"] ?? false; +// // var dataAsList = data["result"] as List; +// print("all data $data"); +// // print("list data $dataAsList"); + +// if (isAuthenticated) { +// List parsed = data['result'] as List; +// return ResponseModel( +// responseStatus: ResponseStatus.success, +// data: parsed.map((e) => PastSessionModel.fromJson(e)).toList(), +// ); +// } else { +// return const ResponseModel( +// responseStatus: ResponseStatus.error, +// data: null, +// ); +// } +// } +// } +// } diff --git a/gsf/lib/repository/services/cj/past_session_services.dart b/gsf/lib/repository/services/cj/past_session_services.dart new file mode 100644 index 0000000..2372243 --- /dev/null +++ b/gsf/lib/repository/services/cj/past_session_services.dart @@ -0,0 +1,88 @@ +import 'dart:convert'; +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +// import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/PastSessionModel.dart'; +// import 'package:gsp_app/modals/past_activity_modal.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +PastSessionModel? pastData; + +class PastActivity { + Dio dio = Dio(); + + // Future getPastActivityData() async { + // print("past session api calling"); + // var response = await get(Endpoints.getPastActivity, headers: { + // "access-token": GetStorage().read("token"), + // }); + + // if (response.body == null && + // response.body.toString().contains("")) { + // return const ResponseModel( + // responseStatus: ResponseStatus.error, data: null); + // } else { + // Map data = response.body; + // print('data of past activity data ${data}'); + + // bool isAuthenticated = data["success"] ?? false; + // // print('New data and filter ${data["result"]}'); + // if (isAuthenticated) { + // var pastData = data["result"] as List; + + // var filteredData = pastData.where((e) { + // if (e.containsKey('schedule')) { + // var schedules = e['schedule']; + // print('Schedules Data New ${schedules.length}'); + // for (var schedule in schedules) { + // if (schedule.containsKey('past_data') && + // schedule['past_data'].isEmpty) { + // print('Schedule Data of past data ${schedule}'); + // return true; + // } + // } + // } + // return false; + // }).toList(); + + // int index = -1; + + // return ResponseModel( + // responseStatus: ResponseStatus.success, + // data: filteredData.map((e) { + // index++; + // return PastActivityModel.fromJson(e); + // }).toList(), + // ); + // } else { + // return const ResponseModel( + // responseStatus: ResponseStatus.error, data: null); + // } + // } + // } + + Future getPastActivityData() async { + Response response; + String? token = GetStorage().read("token").toString(); + try { + response = await dio.get(Endpoints.getPastActivity, + options: Options(headers: { + "access-token": token, + })); + } on Exception catch (_) { + return const ResponseModel( + responseStatus: ResponseStatus.failed, data: null); + } + if (response.statusCode == 200) { + pastData = PastSessionModel.fromJson(response.data); + + return ResponseModel( + responseStatus: ResponseStatus.success, data: pastData); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } +} diff --git a/gsf/lib/repository/services/cj/upcoming_activity_service.dart b/gsf/lib/repository/services/cj/upcoming_activity_service.dart new file mode 100644 index 0000000..0c2ff95 --- /dev/null +++ b/gsf/lib/repository/services/cj/upcoming_activity_service.dart @@ -0,0 +1,81 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/upcoming_session_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +class UpcomingActivityServices extends GetConnect { + Future getUpcomingActivitydata() async { + var response = await get(Endpoints.getUpcomingActivity, headers: { + "access-token": GetStorage().read("token"), + }); + + // debugPrint('check reponse of getUpcomingActivity data ${response.body}'); + + if (response.body == null && response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + // debugPrint('result of data ${data["result"]}'); + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + var authData = data["result"] as List; + //print('AUTHDATA of upcoming $authData'); + + // var filteredArray = authData + // .where((data) => + // data.containsKey("schedule") && data["schedule"] != null) + // .toList(); + // print('ONLY SCHEDULE CONTAINS DATA upcoming Activity ${authData}'); + return ResponseModel( + responseStatus: ResponseStatus.success, + data: authData.map((e) => UpcomingSessionModel.fromJson(e)).toList(), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } + + + Future getUpcomingActivitydataUtc() async { + var response = await get(Endpoints.getUpcomingActivityUtc, headers: { + "access-token": GetStorage().read("token"), + }); + + // debugPrint('check reponse of getUpcomingActivity data ${response.body}'); + + if (response.body == null && response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } else { + Map data = response.body; + // debugPrint('result of data ${data["result"]}'); + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + var authData = data["result"] as List; + //print('AUTHDATA of upcoming $authData'); + + // var filteredArray = authData + // .where((data) => + // data.containsKey("schedule") && data["schedule"] != null) + // .toList(); + // print('ONLY SCHEDULE CONTAINS DATA upcoming Activity ${authData}'); + return ResponseModel( + responseStatus: ResponseStatus.success, + data: authData.map((e) => UpcomingSessionModel.fromJson(e)).toList(), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.error, data: null); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/update_password_service.dart b/gsf/lib/repository/services/cj/update_password_service.dart new file mode 100644 index 0000000..7c69532 --- /dev/null +++ b/gsf/lib/repository/services/cj/update_password_service.dart @@ -0,0 +1,43 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +import '../../endpoints.dart'; + +class UpdatePasswordService extends GetConnect { + Future updatePassword({ + required String userId, + required String password, + required String confirmPassword, + }) async { + Response response = await put( + Endpoints.updatePassword, + { + "user_id": userId, + "password": password, + "password_confirmation": confirmPassword, + }, + ); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + bool success = data["success"] ?? false; + if (success) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: data['message'], + ); + } else { + return ResponseModel( + responseStatus: ResponseStatus.failed, + data: data['message'], + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/update_profile_service.dart b/gsf/lib/repository/services/cj/update_profile_service.dart new file mode 100644 index 0000000..82625dc --- /dev/null +++ b/gsf/lib/repository/services/cj/update_profile_service.dart @@ -0,0 +1,64 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/user_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../../response_data.dart'; + +class UpdateProfileService extends GetConnect { + Future updateProfile({ + required String name, + required String bio, + required String description, + required String gender, + required int age, + required String address, + required String city, + required double height, + // required double weight, + String? profilePicPath, + }) async { + Response response = await post( + Endpoints.updateProfile, + FormData({ + "full_name": name, + "bio": bio, + "description": description, + "gender": gender, + "age": age, + "full_address": address, + "city": city, + "height": height, + // "weight": weight, + "profile_picture": profilePicPath == null + ? null + : MultipartFile(File(profilePicPath).readAsBytesSync(), + filename: profilePicPath.split("/").last), + }), + headers: {"access-token": GetStorage().read('token')}, + ); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + bool success = data["success"] ?? false; + if (success) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: UserModel.fromJson(data), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/user_dashboard_chart_service.dart b/gsf/lib/repository/services/cj/user_dashboard_chart_service.dart new file mode 100644 index 0000000..e0eb884 --- /dev/null +++ b/gsf/lib/repository/services/cj/user_dashboard_chart_service.dart @@ -0,0 +1,40 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../../../modals/user_dashboard_chart_model.dart'; +import '../../response_data.dart'; + +class UserDashboardChartService extends GetConnect{ + FutureuserDashboardChart()async { + Response response = await get(Endpoints.getDashboardChart,headers: { + "access-token":GetStorage().read("token"), + }); + print('New Data of dahsboard ${response.body}'); + + if (response.body == null && response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else{ + var data = response.body; + bool isAuthenticated = data["success"] ?? false; + + if (isAuthenticated) { + // var authData = data; + // print('AUTHDATA NOTIFICATION ${authData}'); + return ResponseModel( + responseStatus: ResponseStatus.success, + data: UserDashboardChartModel.fromJson(data as Map), + ); + }else { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } + + } + } +} \ No newline at end of file diff --git a/gsf/lib/repository/services/cj/user_data_service.dart b/gsf/lib/repository/services/cj/user_data_service.dart new file mode 100644 index 0000000..b4d104a --- /dev/null +++ b/gsf/lib/repository/services/cj/user_data_service.dart @@ -0,0 +1,44 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +import '../../../modals/user_model.dart'; +import '../../endpoints.dart'; + +class UserDataService extends GetConnect { + Future fetchUserData() async { + Response response = await get( + Endpoints.fetchUserData, + headers: {"access-token": GetStorage().read('token')}, + ); + + if (response.body == null || + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else if (response.body["status_code"] == 201) { + return const ResponseModel( + responseStatus: ResponseStatus.expired, + data: null, + ); + } else { + Map data = response.body; + bool canParse = data["success"] ?? false; + if (canParse) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: UserModel.fromJson(data), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/cj/verify_otp_service.dart b/gsf/lib/repository/services/cj/verify_otp_service.dart new file mode 100644 index 0000000..e184d06 --- /dev/null +++ b/gsf/lib/repository/services/cj/verify_otp_service.dart @@ -0,0 +1,58 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; + +import '../../endpoints.dart'; +import '../../response_data.dart'; + +class VerifyOtpService extends GetConnect { + Future verifyOtp({ + required String emailId, + required String otp, + }) async { + Response response = await post( + Endpoints.verifyOTPV2, + {"email_id": emailId, "otp": otp}, + ); + if (response.body == null || + response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + late ResponseModel responseModel; + switch (data['status']) { + case 200: + //CORRECT OTP + responseModel = const ResponseModel( + responseStatus: ResponseStatus.success, + data: null, + ); + break; + case 401: + //INCORRECT OTP + responseModel = const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + break; + case 500: + //EXPIRED + responseModel = const ResponseModel( + responseStatus: ResponseStatus.expired, + data: null, + ); + break; + default: + responseModel = const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + break; + } + return responseModel; + } + } +} diff --git a/gsf/lib/repository/services/cj/view_frnds_profile_service.dart b/gsf/lib/repository/services/cj/view_frnds_profile_service.dart new file mode 100644 index 0000000..25f1d65 --- /dev/null +++ b/gsf/lib/repository/services/cj/view_frnds_profile_service.dart @@ -0,0 +1,56 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +import '../../../modals/view_frnd_profile_model.dart'; +import '../../endpoints.dart'; +import '../../response_data.dart'; + +class ViewFriendsProfileService extends GetConnect { + /* + Future> fetchFrndDetails() async { + var response = await http.get( + Uri.parse("https://gsf.wdipl.com/api/view_profile_frds"), + headers: {"access-token": GetStorage().read('token')}, + ); + var parsed = jsonDecode(response.body)['result'] as List; + print('parsed data shows $parsed'); + // if (parsed['status'] == "Token is Expired") { + // Get.offAll(() => const SignIn()); + // Get.showSnackbar(const GetSnackBar( + // title: "Session Expired", + // message: "Please login again", + // )); + // } + return parsed.map((e) => ViewfrndsProfileModel.fromJson(e)).toList(); + } +*/ + Future fetchFriendsProfile() async { + Response response = await get( + Endpoints.viewFriendsProfile, + headers: {"access-token": GetStorage().read('token')}, + ); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + bool canParse = data["success"] ?? false; + if (canParse) { + var parsed = data['result'] as List; + return ResponseModel( + responseStatus: ResponseStatus.success, + data: parsed.map((e) => ViewfrndsProfileModel.fromJson(e)).toList(), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} diff --git a/gsf/lib/repository/services/complete_profile_service.dart b/gsf/lib/repository/services/complete_profile_service.dart new file mode 100644 index 0000000..c77f6dc --- /dev/null +++ b/gsf/lib/repository/services/complete_profile_service.dart @@ -0,0 +1,231 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:http/http.dart' as http; +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; +import '../../views/components/const.dart'; + +// import 'sign_in_controller.dart'; + +class CompleteProfileController extends GetxController { + // complete profile textEditController================= + final nameController = TextEditingController().obs; //complete profile name + final bioController = TextEditingController().obs; //complete profile bio + final genderController = + TextEditingController().obs; //complete profile gender + final ageController = TextEditingController().obs; //complete profile age + final phoneNumberController = + TextEditingController().obs; //complete profile phoneNumber + final emailProfileController = + TextEditingController().obs; //complete profile emailProfile + final fullAdrsessController = + TextEditingController().obs; //complete profile fullAdrsessController + final cityController = + TextEditingController().obs; //complete profile cityController + final heightController = + TextEditingController().obs; //complete profile heightController + final weightController = + TextEditingController().obs; //complete profile weightController + final RxBool loading = false.obs; + var selectedImagePath = ''.obs; + var cropImagePath = ''.obs; + var box = GetStorage(); + RxBool isFileNetwork = true.obs; + + // image upload functions start=======================\ + void getImage(ImageSource imageSource) async { + // pick image + final pickedFile = await ImagePicker().pickImage(source: imageSource); + // File file = File(pickedFile!.path); + // debugPrint('file picked view ${file.path}'); + + print('images path in controller 1 ${selectedImagePath.value}'); + if (pickedFile != null) { + // crop image + print('images path in controller picked file ${pickedFile}'); + final cropImageFile = await ImageCropper().cropImage( + sourcePath: pickedFile.path, + maxWidth: 512, + maxHeight: 512, + compressFormat: ImageCompressFormat.jpg, + compressQuality: 100, + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'Cropper', + toolbarColor: ColorConstants.kPrimaryColor, + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: false, + activeControlsWidgetColor: ColorConstants.kPrimaryColor, + ), + IOSUiSettings( + title: 'Cropper', + ), + ], + ); + print('images path in controller crop image file ${cropImageFile!.path}'); + cropImagePath.value = cropImageFile.path; + // File file = File(image!.path); + print('crop image file selcted news ${cropImagePath.value}'); + Get.back(); + // selectedImagePath.value = ''; + selectedImagePath.value = cropImagePath.value; + isFileNetwork.value = false; + // var imageName = selectedImagePath.value.split('/').last; + debugPrint( + 'image name split value before the upload ${selectedImagePath.value}'); + debugPrint(' image path value ${selectedImagePath.value}'); + } else { + Get.snackbar( + 'Error', + 'No Image Selected', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + } + } + + void clearFormAndSubmit() { + nameController.value.clear(); + bioController.value.clear(); + genderController.value.clear(); + ageController.value.clear(); + phoneNumberController.value.clear(); + emailProfileController.value.clear(); + fullAdrsessController.value.clear(); + cityController.value.clear(); + heightController.value.clear(); + weightController.value.clear(); + Get.snackbar('Congratulation!', 'You have completed you\'re profile.', + backgroundColor: ColorConstants.kPrimaryColor); + // Get.offAll(() => const HomePage()); + box.write('isLoggedIn', true); + } + + // complete profile api controller start==================================== + Future completeProfile() async { + try { + // if (selectedImagePath.value == null) { + // final request = await http.post( + // Uri.parse('https://gsf.wdipl.com/api/update_profile'), + // headers: {'Access-token': box.read('token')}, + // body: { + // "bio": bioController.value.text, + // "description": "Pankaj descriptions", + // "gender": SignInData.selectedGender!.toLowerCase(), + // "full_address": fullAdrsessController.value.text, + // "age": ageController.value.text, + // "city": cityController.value.text, + // "height": heightController.value.text, + // "weight": weightController.value.text, + // }, + // ); + // var data = jsonDecode(request.body) as Map; + // print(data["success"]); + // if (data["success"] == true) { + // clearFormAndSubmit(); + // } + // if (data["success"] == false) { + // Get.snackbar('Failed', data["message"], + // snackPosition: SnackPosition.BOTTOM, + // backgroundColor: ColorConstants.kErroColor); + // } + // } + + // with image api called======================= + // if (selectedImagePath.value != null) { + // debugPrint('with image api runn'); + // debugPrint('with image api runn $selectedImagePath'); + // http.MultipartRequest request = http.MultipartRequest( + // 'POST', Uri.parse('https://gsf.wdipl.com/api/update_profile')); + // request.headers['access-token'] = box.read('token'); + // request.fields["bio"] = bioController.value.text; + // request.fields["description"] = "Pankaj descriptions"; + // request.fields["gender"] = genderValue; + // request.fields["full_address"] = fullAdrsessController.value.text; + // request.fields["age"] = ageController.value.text; + // request.fields["city"] = cityController.value.text; + // request.fields["height"] = heightController.value.text; + // request.fields["weight"] = weightController.value.text; + // var pic = http.MultipartFile.fromBytes( + // 'profile_picture', + // File(selectedImagePath.value).readAsBytesSync(), + // filename: selectedImagePath.value.split('/').last, + // ); + // request.files.add(pic); + // var response = await request.send(); + // var responseData = await response.stream.toBytes(); + // var responseString = String.fromCharCodes(responseData); + // var data = jsonDecode(responseString); + // debugPrint("api with image $data"); + // print(data["success"]); + // if (data["success"] == true) { + // Get.snackbar( + // 'Congratulations!', + // '${data["message"]}', + // snackPosition: SnackPosition.BOTTOM, + // backgroundColor: const Color.fromARGB(255, 170, 228, 46), + // ); + // isFileNetwork.toggle(); + // } + // if (data["success"] == false) { + // Get.snackbar( + // 'Failed', + // '${data["message"]}', + // snackPosition: SnackPosition.BOTTOM, + // backgroundColor: ColorConstants.kErroColor, + // ); + // } + if (selectedImagePath.value == '') { + Get.snackbar('Failed', 'Please select an image', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor); + } + http.MultipartRequest request = http.MultipartRequest( + 'POST', Uri.parse(Endpoints.updateProfile)); + request.headers['access-token'] = SignInData.token; + request.fields["bio"] = bioController.value.text; + request.fields["full_name"] = nameController.value.text; + request.fields["description"] = "Pankaj descriptions"; + request.fields["gender"] = SignInData.selectedGender!.toLowerCase(); + request.fields["full_address"] = fullAdrsessController.value.text; + request.fields["age"] = ageController.value.text; + request.fields["city"] = cityController.value.text; + request.fields["height"] = heightController.value.text; + request.fields["weight"] = weightController.value.text; + var pic = http.MultipartFile.fromBytes( + 'profile_picture', + File(selectedImagePath.value).readAsBytesSync(), + filename: selectedImagePath.value.split('/').last, + ); + request.files.add(pic); + var response = await request.send(); + var responseData = await response.stream.toBytes(); + var responseString = String.fromCharCodes(responseData); + var data = jsonDecode(responseString); + print('status of api on complete profile $data'); + print(data["success"]); + if (data["success"] == true) { + clearFormAndSubmit(); + } + if (data["success"] == false) { + Get.snackbar( + 'Failed', + '${data["message"]}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor, + ); + } + // } + } catch (e) { + debugPrint(e.toString()); + } + } +} diff --git a/gsf/lib/repository/services/contact_us_service.dart b/gsf/lib/repository/services/contact_us_service.dart new file mode 100644 index 0000000..1b3a88c --- /dev/null +++ b/gsf/lib/repository/services/contact_us_service.dart @@ -0,0 +1,27 @@ +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:http/http.dart' as http; + +class ContactUsService { + Future uploadDetails( + String name, + String email, + String number, + String subject, + String message, + ) async { + http.Response response = await http.post( + Uri.parse(Endpoints.postContactUs), + headers: {"access-token": GetStorage().read('token')}, + body: { + "name": name, + "email_id": email, + "contact_number": number, + "subject": subject, + "message": message, + "type": "complaint", + }, + ); + return response; + } +} diff --git a/gsf/lib/repository/services/edit_profile_service.dart b/gsf/lib/repository/services/edit_profile_service.dart new file mode 100644 index 0000000..588c25d --- /dev/null +++ b/gsf/lib/repository/services/edit_profile_service.dart @@ -0,0 +1,154 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:http/http.dart' as http; + +import '../../modals/edit_profile_model.dart'; +import 'complete_profile_service.dart'; + +class EditProfileController extends GetxController { + // complete profile textEditController================= + final nameController = TextEditingController().obs; //complete profile name + final bioController = TextEditingController().obs; //complete profile bio + final genderController = + TextEditingController().obs; //complete profile gender + final ageController = TextEditingController().obs; //complete profile age + final phoneNumberController = + TextEditingController().obs; //complete profile phoneNumber + final emailProfileController = + TextEditingController().obs; //complete profile emailProfile + final fullAdrsessController = + TextEditingController().obs; //complete profile fullAdrsessController + final cityController = + TextEditingController().obs; //complete profile cityController + final heightController = + TextEditingController().obs; //complete profile heightController + final weightController = + TextEditingController().obs; //complete profile weightController + final RxBool loading = false.obs; + // String selectedImagePaths = + // Get.find().selectedImagePath.value; + final CompleteProfileController profileImagePath = + Get.put(CompleteProfileController()); + + final box = GetStorage(); + // RxBool imageChange = false.obs; + + // get user data ================ + + Future fetchUserData() async { + try { + http.Response response = await http.get( + Uri.parse(Endpoints.fetchUserData), + headers: {'access-token': GetStorage().read('token')}, + ); + var parsed = jsonDecode(response.body) as Map; + return EditProfileModel.fromJson(parsed); + } catch (e) { + print('edit profile api error ${e.toString()}'); + } + return fetchUserData(); + } + + // update user profile data start============== + + Future postEditProfileData( + {genderValue, required String imgPath}) async { + // print( + // 'without image api runn before api run in try and catch ${profileImagePath.selectedImagePath.value}'); + + try { + // if (profileImagePath == null) { + // final request = await http.post( + // Uri.parse('https://gsf.wdipl.com/api/update_profile'), + // headers: {'access-token': box.read('token')}, + // body: { + // "bio": bioController.value.text, + // "description": "Pankaj descriptions", + // "gender": genderValue, + // "full_address": fullAdrsessController.value.text, + // "age": ageController.value.text, + // "city": cityController.value.text, + // "height": heightController.value.text, + // "weight": weightController.value.text, + // }, + // ); + // var data = jsonDecode(request.body) as Map; + // print("api without image $data"); + // if (data["success"] == true) { + // Get.snackbar( + // 'Congratulations!', + // data['message'], + // backgroundColor: ColorConstants.kPrimaryColor, + // snackPosition: SnackPosition.BOTTOM, + // ); + // profileImagePath.isFileNetwork.toggle(); + // } + // if (data["success"] == false) { + // Get.snackbar( + // 'Failed', + // data["message"], + // snackPosition: SnackPosition.BOTTOM, + // backgroundColor: ColorConstants.kErroColor, + // ); + // } + // } + // with image api called======================= + // if (profileImagePath != null) { + // print('with image api runn'); + // print('with image api runn $profileImagePath'); + http.MultipartRequest request = http.MultipartRequest( + 'POST', Uri.parse('https://gsf.wdipl.com/api/update_profile')); + request.headers['access-token'] = box.read('token'); + request.fields["bio"] = bioController.value.text; + request.fields["full_name"] = nameController.value.text; + request.fields["description"] = "Pankaj descriptions"; + request.fields["gender"] = genderValue; + request.fields["full_address"] = fullAdrsessController.value.text; + request.fields["age"] = ageController.value.text; + request.fields["city"] = cityController.value.text; + request.fields["height"] = heightController.value.text; + request.fields["weight"] = weightController.value.text; + + var pic = http.MultipartFile.fromBytes( + 'profile_picture', + // File(profileImagePath.selectedImagePath.value).readAsBytesSync(), + File(imgPath).readAsBytesSync(), + filename: profileImagePath.selectedImagePath.value.split('/').last, + ); + // print('image name with split $pic'); + request.files.add(pic); + var response = await request.send(); + var responseData = await response.stream.toBytes(); + var responseString = String.fromCharCodes(responseData); + var data = jsonDecode(responseString); + print("api with image $data"); + print(data["success"]); + if (data["success"] == true) { + Get.snackbar( + 'Congratulations!', + '${data["message"]}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: const Color.fromARGB(255, 170, 228, 46), + ); + profileImagePath.isFileNetwork.toggle(); + } + if (data["success"] == false) { + Get.snackbar( + 'Failed', + '${data["message"]}', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor, + ); + } + return postEditProfileData(imgPath: imgPath); + // } + } catch (e) { + debugPrint(e.toString()); + } + } +} diff --git a/gsf/lib/repository/services/faq_service.dart b/gsf/lib/repository/services/faq_service.dart new file mode 100644 index 0000000..112d340 --- /dev/null +++ b/gsf/lib/repository/services/faq_service.dart @@ -0,0 +1,21 @@ +import 'dart:convert'; + +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/faq_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:http/http.dart' as http; + +class FaqService { + // final String baseUrl = "https://gsf.wdipl.com/api"; + + Future> fetchFaq() async { + final response = await http.get( + Uri.parse(Endpoints.getFaq), + headers: {"access-token": GetStorage().read('token')}, + ); + print('response of faq ${response.body}'); + final parsed = jsonDecode(response.body)['user'] as List; + print('response of faq ${parsed}'); + return parsed.map((json) => FaqModel.fromJson(json)).toList(); + } +} diff --git a/gsf/lib/repository/services/home_controller.dart b/gsf/lib/repository/services/home_controller.dart new file mode 100644 index 0000000..01bd9ca --- /dev/null +++ b/gsf/lib/repository/services/home_controller.dart @@ -0,0 +1,37 @@ +import 'package:get/get.dart'; +import 'package:async/async.dart'; +import '../../modals/set_mood_res_modal.dart'; +import 'edit_profile_service.dart'; + +class HomeApiController extends GetxController { + String? _moodCheckResult; + String? get moodCheckResult => _moodCheckResult; + + SetMoodResponse _setMoodResponse = SetMoodResponse(); + SetMoodResponse get setMoodResponse => _setMoodResponse; + + var homePageApi = FutureGroup(); + final EditProfileController getProfileDatas = + Get.put(EditProfileController()); + // final ManageBanner manageBanners = Get.put(ManageBanner()); + + void fetchGroupAPi() async { + homePageApi.add( + getProfileDatas.fetchUserData(), + ); + // homePageApi.add(manageBanners.manageBanner()); + homePageApi.close(); + } + + setMoodOMeterResult(String result) { + _moodCheckResult = result; + update(); + } + + setMoodOMeterResp(dynamic data) { + _setMoodResponse = SetMoodResponse.fromJson(data); + update(); + } + +// OverViewServices +} diff --git a/gsf/lib/repository/services/meet_community_service.dart b/gsf/lib/repository/services/meet_community_service.dart new file mode 100644 index 0000000..1bd8cbe --- /dev/null +++ b/gsf/lib/repository/services/meet_community_service.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; +import 'package:dio/dio.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:http/http.dart' as http; + +import '../../modals/member_modal.dart'; + +MeetTheCommunityModel? communityData; + +class MeetTheCommunityService { + Dio dio = Dio(); + + // Future fetchCommunityData() async { + // var response = await http.get( + // Uri.parse(Endpoints.getTestimonial), + // headers: {'access-token': GetStorage().read('token')}, + // ); + + // // var parsed = jsonDecode(response.body) ['user'] as List; + // // print(parsed); + // // // return MeetTheCommunityModel.fromJson(parsed); + + // // return parsed + // // .map((e) => MeetTheCommunityModel.fromJson(e)) + // // .toList(); + + // Map responseData = response.body as Map; + // communityData = MeetTheCommunityModel.fromJson(responseData); + // print("meetCommunity data ${responseData}"); + // return communityData!; + // } + + Future fetchCommunityData() async { + Response response; + String? token = GetStorage().read("token").toString(); + + response = await dio.get(Endpoints.getTestimonial, + options: Options(headers: { + "access-token": token, + })); + + if (response.statusCode == 200) { + //print("fetch community result ${response.data}"); + communityData = MeetTheCommunityModel.fromJson(response.data); + + // return ResponseModel( + // responseStatus: ResponseStatus.success, data: communityData); + } + return communityData!; + } +} diff --git a/gsf/lib/repository/services/mood_o_meter_service.dart b/gsf/lib/repository/services/mood_o_meter_service.dart new file mode 100644 index 0000000..88ddfe2 --- /dev/null +++ b/gsf/lib/repository/services/mood_o_meter_service.dart @@ -0,0 +1,13 @@ +// import 'package:get_storage/get_storage.dart'; +// import 'package:http/http.dart' as http; + +// class MoodOMeterService { +// Future uploadMood(String mood) async { +// http.Response response = await http.post( +// Uri.parse("https://gsf.wdipl.com/api/storeMoodOMeter"), +// headers: {"access-token": GetStorage().read('token')}, +// body: {"mood_o_meter": mood}, +// ); +// return response; +// } +// } diff --git a/gsf/lib/repository/services/share_thoughts_service.dart b/gsf/lib/repository/services/share_thoughts_service.dart new file mode 100644 index 0000000..9531ea9 --- /dev/null +++ b/gsf/lib/repository/services/share_thoughts_service.dart @@ -0,0 +1,43 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import '../../modals/share_thoughts.dart'; +import '../endpoints.dart'; +import '../response_data.dart'; + +class GetOurThoughts extends GetConnect { + Future getShareThoughtsData() async { + Response response = await get( + Endpoints.getThoughtData, + headers: {"access-token": GetStorage().read("token")}, + ); + print('GET OVERVIEW RESPONSIVE ${response.body}'); + if (response.body == null || response.body.toString().contains("")) { + return const ResponseModel( + responseStatus: ResponseStatus.error, + data: null, + ); + } else { + Map data = response.body; + bool isAuthenticated = data["success"] ?? false; + if (isAuthenticated) { + return ResponseModel( + responseStatus: ResponseStatus.success, + data: ShareOurthoutghs.fromJson(data["result"][0]), + ); + } else { + return const ResponseModel( + responseStatus: ResponseStatus.failed, + data: null, + ); + } + } + } +} + + + + +// var strings = "I DONT, KNOW"; +// var lenthofIndex = strings.split(","); +// let splitedString = lenthofIndex[1]; +// console.log(splitedString); \ No newline at end of file diff --git a/gsf/lib/repository/services/short_clip_service.dart b/gsf/lib/repository/services/short_clip_service.dart new file mode 100644 index 0000000..d96de09 --- /dev/null +++ b/gsf/lib/repository/services/short_clip_service.dart @@ -0,0 +1,71 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/short_clip_likes_model.dart'; +import 'package:gsp_app/modals/short_clip_model.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:http/http.dart' as http; + +class ShortClipService { + Future> fetchShortClips() async { + var response = await http.get( + Uri.parse(Endpoints.getShortCLips), + headers: {"access-token": GetStorage().read('token')}, + ); + var withoutDecoded = response.body; + var decodedNew = jsonDecode(withoutDecoded); + + var decoded = jsonDecode(response.body); + // print('decoded in new ${decoded}'); + + if (decodedNew['status'] == "Token is Expired") { + Get.showSnackbar(const GetSnackBar( + title: "Session Expired", + message: "Please login again", + )); + } + + var parsed = decodedNew['user'] as List; + var parsedNewVAl = parsed.map((e) => ShortClipModel.fromJson(e)).toList(); + return parsed.map((e) => ShortClipModel.fromJson(e)).toList(); + } + + Future likeOrUnlikeClip(int clipId) async { + var response = await http.post( + Uri.parse(Endpoints.postLikeShortCLips), + headers: {"access-token": GetStorage().read('token')}, + body: {"short_clips_id": clipId.toString()}, + ); + String? result = response.body; + + String? finalresult = jsonDecode(result)['message']; + // print('object only $finalresult'); + if (finalresult == "you liked" || finalresult == "You Like a post") { + return true; + } else { + return false; + } + } + + Future> fetchShortClipLikes() async { + var response = await http.get( + Uri.parse(Endpoints.getLikeShortCLips), + headers: {"access-token": GetStorage().read('token')}, + ); + + var decoded = response.body; + var finalDecoded = jsonDecode(decoded); + if (finalDecoded['status'] == "Token is Expired") { + Get.showSnackbar(const GetSnackBar( + title: "Session Expired", + message: "Please login again", + )); + } + var parsed = finalDecoded['result'] as List; + var res = parsed.map((e) => ShortClipLikesModel.fromJson(e)).toList(); + return res; + } +} diff --git a/gsf/lib/repository/services/sign_in_service.dart b/gsf/lib/repository/services/sign_in_service.dart new file mode 100644 index 0000000..2febada --- /dev/null +++ b/gsf/lib/repository/services/sign_in_service.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:http/http.dart'; + +import '../../views/components/const.dart'; + +// import '../test/dropdwon.dart'; + +// import '../home/home_page.dart'; + +class SignInController extends GetxController { + final emailController = TextEditingController().obs; + final passwordController = TextEditingController().obs; + final box = GetStorage(); + final RxBool loading = false.obs; + + @override + void dispose() { + emailController.value.dispose(); + passwordController.value.dispose(); + super.dispose(); + } + + Future loginApi() async { + loading.value = true; + try { + final response = await post( + Uri.parse(Endpoints.login), + // headers: {'token': token, 'content-type': 'application/json'}, + body: { + 'email_id': emailController.value.text, + 'password': passwordController.value.text, + }, + ); + var data = jsonDecode(response.body); + // debugPrint("DATA ${data['authorisation']['user_data']['full_name']}"); + // debugPrint(' data ${data}'); + // print(' $data object5'); + // print(' data name ${data['authorisation']['user_data']['full_name']}'); + // debugPrint(data["status"]); + // debugPrint(' token :- ${data['authorisation']["token"]}'); + SignInData.data = data["status"]; + SignInData.token = data["authorisation"]["token"]; + SignInData.name = data['authorisation']['user_data']['full_name']; + SignInData.status = data['authorisation']['user_data']['status']; + SignInData.mobileNumber = + data['authorisation']['user_data']['contact_number']; + SignInData.emailId = data['authorisation']['user_data']['email_id']; + debugPrint(' token genrated ${SignInData.token}'); + + if (data["status"] == true) { + Get.snackbar( + 'Congratulation!', + data['message'], + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kPrimaryColor, + ); + loading.value = false; + emailController.value.clear(); + passwordController.value.clear(); + box.write('token', + data['authorisation']['token']); // user token store in localStorage + box.write( + 'userName', + data['authorisation']['user_data'] + ['full_name']); //usre name store in + + var userData = box.read('userName'); + + debugPrint('user data $userData'); + } else if (data["status"] == 401) { + Get.snackbar( + 'Log in Failed', + data["message"], + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor, + ); + loading.value = false; + } + } catch (e) { + Get.snackbar( + 'Excepetion', + 'something went wrong, please check you credentails.', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: ColorConstants.kErroColor, + ); + loading.value = false; + } + } +} diff --git a/gsf/lib/repository/services/view_profile_services.dart b/gsf/lib/repository/services/view_profile_services.dart new file mode 100644 index 0000000..5bbcb5b --- /dev/null +++ b/gsf/lib/repository/services/view_profile_services.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:http/http.dart' as http; + +import '../../modals/edit_profile_model.dart'; +import '../../modals/view_profile_model.dart'; + +class ViewProfileController extends GetxController { + // Future> userProfileApi() async { + // try { + // http.Response response = await http.get( + // Uri.parse('https://gsf.wdipl.com/api/view_profile_frds'), + // headers: {'access-token': GetStorage().read('token')}, + // ); + // var parsed = jsonDecode(response.body)["result"] as List; + // print(parsed); + // return parsed.map((e) => ViewProfileModel.fromJson(e)).toList(); + // } on FormatException catch (e) { + // print(e.toString()); + // } + // return userProfileApi(); + // } + + Future fetchUserData() async { + try { + http.Response response = await http.get( + Uri.parse(Endpoints.fetchUserData), + headers: {'Access-token': GetStorage().read('token')}, + ); + var parsed = jsonDecode(response.body) as Map; + // print(parsed); + return EditProfileModel.fromJson(parsed); + } catch (e) { + print('edit profile api error ${e.toString()}'); + } + return fetchUserData(); + } +} diff --git a/gsf/lib/scale/model/device_type.dart b/gsf/lib/scale/model/device_type.dart new file mode 100644 index 0000000..775df16 --- /dev/null +++ b/gsf/lib/scale/model/device_type.dart @@ -0,0 +1,7 @@ +class DeviceType { + static const int scale = 0; + static const int kitchen = 1; + static const int rope = 2; + static const int ruler = 3; + static const int height = 4; +} diff --git a/gsf/lib/scale/page/device_scan_page.dart b/gsf/lib/scale/page/device_scan_page.dart new file mode 100644 index 0000000..1454a16 --- /dev/null +++ b/gsf/lib/scale/page/device_scan_page.dart @@ -0,0 +1,304 @@ +// ignore_for_file: must_be_immutable + +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICScanDeviceDelegate.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICScanDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +import '../../view_model/home_page_controller.dart'; +import '../../views/theme.dart'; + +class DeviceScanPage extends StatefulWidget { + DeviceScanPage({required this.devType, Key? key}) : super(key: key); + + int devType; + + @override + State createState() => _DeviceScanPageState(); +} + +class _DeviceScanPageState extends State + implements ICScanDeviceDelegate { + var ReScan = "ReScan"; + var StopScan = "StopScan"; + var count = 1; + List listArray = []; + + void onScanResult(ICScanDeviceInfo dev) { + // log("onScanResult-->222222222222:$dev"); + if (!isDeviceTypeMatch(dev, widget.devType)) { + return; + } + if (GetStorage().read('bluetoothMac') == + DeviceItem( + dev.name, + dev.macAddr, + dev.rssi, + listArray.length + 1, + dev.communicationType == + ICDeviceCommunicationType.ICDeviceCommunicationTypeConnect + ? 0 + : 1, + )) { + IcBluetoothSdk.instance.addDevice( + ICDevice((dev.macAddr)), + ICAddDeviceCallBack( + callBack: (ICDevice icDevice, ICAddDeviceCallBackCode code) { + log("InkWell-->ICAddDeviceCallBack:$code"); + }, + ), + ); + } + // log("onScanResult-->3333:$dev"); + if (!isContainMac(dev)) { + setState( + () { + listArray.add( + DeviceItem( + dev.name, + dev.macAddr, + dev.rssi, + listArray.length + 1, + dev.communicationType == + ICDeviceCommunicationType.ICDeviceCommunicationTypeConnect + ? 0 + : 1, + ), + ); + }, + ); + } + } + + bool isDeviceTypeMatch(ICScanDeviceInfo response, int deviceType) { + if (deviceType == DeviceType.ruler && + response.type != ICDeviceType.ICDeviceTypeRuler) { + return false; + } + if (deviceType == DeviceType.kitchen && + response.type != ICDeviceType.ICDeviceTypeKitchenScale) { + return false; + } + if (deviceType == DeviceType.rope && + response.type != ICDeviceType.ICDeviceTypeSkip) { + return false; + } + + if (deviceType == DeviceType.height && + response.subType != ICDeviceSubType.ICDeviceSubTypeHeight) { + return false; + } + if (response.subType == ICDeviceSubType.ICDeviceSubTypeHeight || + response.type == ICDeviceType.ICDeviceTypeKitchenScale || + response.type == ICDeviceType.ICDeviceTypeRuler || + response.type == ICDeviceType.ICDeviceTypeSkip) { + if (deviceType == DeviceType.scale) { + return false; + } + } + + return true; + } + + isContainMac(ICScanDeviceInfo dev) { + for (var element in listArray) { + if (element.mac == dev.macAddr) { + return true; + } + } + return false; + } + + @override + void initState() { + super.initState(); + // IcBluetoothSdk.instance.setDeviceScanDelegate(this); + IcBluetoothSdk.instance.scanDevice(this); + } + + @override + void dispose() { + super.dispose(); + IcBluetoothSdk.instance.stopScan(); + } + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + appBar: AppBar( + backgroundColor: (brightness == Brightness.light) + ? ColorConstants.kWhite + : ColorConstants.kPrimaryColor, + automaticallyImplyLeading: false, + centerTitle: true, + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: StopScan, child: Text(StopScan)), + PopupMenuItem(value: ReScan, child: Text(ReScan)), + ], + onSelected: _menuSelectValue, + // icon: Icon( + // Icons.adaptive.more, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + ) + ], + title: const Text( + "Device Scan", + style: TextStyle(color: ColorConstants.kBlack), + ), + ), + body: ListView.builder( + itemCount: listArray.length, + itemBuilder: (context, index) { + return GestureDetector( + onTap: () { + print('scale datas'); + // GetStorage().write('addScale', true); + // homePageController.updateBottomNavIndex(1); + // homePageController.updateBottomNavIndex(2); + }, + child: DeviceItem( + listArray[index].name, + listArray[index].mac, + listArray[index].rssi, + index, + listArray[index].communicationType, + ), + ); + }, + //separatorBuilder: (BuildContext context, int index) { + //return const Divider( ); + //}, + //children: listArray, + ), + ); + } + + void _menuSelectValue(value) { + if (value == StopScan) { + IcBluetoothSdk.instance.stopScan(); + } else if (value == ReScan) { + IcBluetoothSdk.instance.scanDevice(this); + } + } +} + +class DeviceItem extends StatelessWidget { + final String? name; + final String? mac; + final int rssi; + final int position; + final int communicationType; + + DeviceItem( + this.name, this.mac, this.rssi, this.position, this.communicationType, + {Key? key}) + : super(key: key); + + HomePageController homePageController = Get.put(HomePageController()); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return InkWell( + onTap: () { + LocalStorage.saveData("communicationType:${mac!}", communicationType); + IcBluetoothSdk.instance.addDevice( + ICDevice((mac)), + ICAddDeviceCallBack( + callBack: (ICDevice icDevice, ICAddDeviceCallBackCode code) { + log("InkWell-->ICAddDeviceCallBack:$code"); + }, + ), + ); + GetStorage().write('bluetoothMac', mac); + print( + 'mac address show stoare in local ${GetStorage().read('bluetoothMac')}'); + Navigator.pop(context); + GetStorage().write('addScale', true); + homePageController.updateBottomNavIndex(1); + homePageController.updateBottomNavIndex(2); + }, + child: Container( + padding: + const EdgeInsets.only(left: 15, right: 15, top: 10, bottom: 10), + width: double.infinity, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + boxShadow: [ + BoxShadow( + blurRadius: 10, + spreadRadius: 2, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.2) + : ColorConstants.kWhite.withOpacity(0), + ), + ], + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Colors.grey.withOpacity(0.2), + ), + child: Stack( + alignment: Alignment.centerLeft, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name != null ? name! : "", + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + const SizedBox( + width: 10, + height: 5, + ), + Text( + mac != null ? mac! : "", + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ], + ), + Align( + alignment: Alignment.centerRight, + child: Text( + rssi.toString(), + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/scale/page/height_home_page.dart b/gsf/lib/scale/page/height_home_page.dart new file mode 100644 index 0000000..e51a478 --- /dev/null +++ b/gsf/lib/scale/page/height_home_page.dart @@ -0,0 +1,332 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/NavigatorUtils.dart'; +import '../../scale/utils/debug_logger.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:icdevicemanager_flutter/utils/ICConverUtil.dart'; + +class HeightPage extends StatefulWidget { + @override + State createState() => _HeightPageState(); +} + +class _HeightPageState extends State + implements ICDeviceManagerDelegate { + var result = "Result:"; + var menuScan = "Scan"; + var menuConnect = "Connect"; + var menuDisConnect = "DisConnect"; + var menuLog = "Log"; + var connectState = "Not Connect"; + String? mac; + List unitChecks = [true, false]; + + @override + void initState() { + super.initState(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + } + + @override + void dispose() { + super.dispose(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(null); + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuScan, child: Text(menuScan)), + PopupMenuItem(value: menuConnect, child: Text(menuConnect)), + PopupMenuItem(value: menuDisConnect, child: Text(menuDisConnect)), + PopupMenuItem(value: menuLog, child: Text(menuLog)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("Height"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Unit:"), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[0]) {_UnitChange(0)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: unitChecks[0], + onChanged: (value) { + setState(() => { + if (value!) {_UnitChange(0)} + }); + })), + const SizedBox(width: 10.0), + const Text("cm", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[1]) {_UnitChange(1)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: unitChecks[1], + onChanged: (value) { + setState(() => { + if (value!) {_UnitChange(1)} + }); + })), + const SizedBox(width: 10.0), + const Text("inch", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + const Text( + "state: ", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + width: 10, + height: 10, + ), + Text(connectState), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + )) + ], + ), + ), + ); + } + + void _UnitChange(int unit) { + log("_OnUnitChange"); + unitChecks[0] = unit == 0; + unitChecks[1] = unit == 1; + if (mac != null) { + IcBluetoothSdk.instance.setRulerUnit( + ICDevice(mac), + ICConverUtil.rulerUnitValueOf(unit), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.height); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: + (ICDevice icDevice, ICAddDeviceCallBackCode code) {})); + } + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState(() { + connectState = "Not Connect"; + }); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + DebugLogger.instance + .logText("onDeviceConnectionChanged: ${device.macAddr!} ->$state"); + mac = device.macAddr; + setState(() { + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) {} + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) { + DebugLogger.instance + .logText("onReceiveRulerData: ${device.macAddr!} ->$data"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) { + DebugLogger.instance + .logText("onReceiveRulerHistoryData: ${device.macAddr!} ->$data"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) { + DebugLogger.instance + .logText("onReceiveRulerUnitChanged: ${device.macAddr!} ->$unit"); + unitChecks[0] = ICRulerUnit.ICRulerUnitCM == unit; + unitChecks[1] = ICRulerUnit.ICRulerUnitCM != unit; + setState(() { + unitChecks; + }); + } + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) {} + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) {} + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) {} + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) {} +} diff --git a/gsf/lib/scale/page/kitchen_scale_home_page.dart b/gsf/lib/scale/page/kitchen_scale_home_page.dart new file mode 100644 index 0000000..b1ea23b --- /dev/null +++ b/gsf/lib/scale/page/kitchen_scale_home_page.dart @@ -0,0 +1,550 @@ +import 'dart:developer'; + +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/NavigatorUtils.dart'; +import '../../scale/utils/debug_logger.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:icdevicemanager_flutter/utils/ICConverUtil.dart'; + +class KitchenScalePage extends StatefulWidget { + @override + State createState() => _KitchenScalePageState(); +} + +class _KitchenScalePageState extends State + implements ICDeviceManagerDelegate { + var result = "Result:"; + var menuScan = "Scan"; + var menuConnect = "Connect"; + var powerOff = "powerOff"; + var menuDisConnect = "DisConnect"; + var menuLog = "Log"; + var connectState = "Not Connect"; + String? mac; + List unitChecks = [ + true, + false, + false, + false, + false, + false, + false, + false + ]; + + @override + void initState() { + super.initState(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + } + + @override + void dispose() { + super.dispose(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(null); + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuScan, child: Text(menuScan)), + PopupMenuItem(value: menuConnect, child: Text(menuConnect)), + PopupMenuItem(value: menuDisConnect, child: Text(menuDisConnect)), + PopupMenuItem(value: powerOff, child: Text(menuConnect)), + PopupMenuItem(value: menuLog, child: Text(menuLog)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("Kitchen Scale"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + const Align( + alignment: Alignment.centerLeft, + child: Text( + "Unit:", + style: TextStyle(fontSize: 16), + ), + ), + Row( + children: [ + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[0]) {_OnUnitChange(0)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[0], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(0)} + }); + })), + const SizedBox(width: 5.0), + const Text("g", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[1]) {_OnUnitChange(1)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[1], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(1)} + }); + })), + const SizedBox(width: 5.0), + const Text("ml", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[2]) {_OnUnitChange(2)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[2], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(2)} + }); + })), + const SizedBox(width: 5.0), + const Text("lb", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[3]) {_OnUnitChange(3)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[3], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(3)} + }); + })), + const SizedBox(width: 5.0), + const Text("oz", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + padding: MaterialStateProperty.all( + EdgeInsets.zero), + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[4]) {_OnUnitChange(4)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[4], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(4)} + }); + })), + const SizedBox(width: 5.0), + const Text("mg", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Row( + children: [ + SizedBox( + width: 80, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[5]) {_OnUnitChange(5)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[5], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(5)} + }); + })), + const SizedBox(width: 5.0), + const Text("milk", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 130, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[6]) {_OnUnitChange(6)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[6], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(6)} + }); + })), + const SizedBox(width: 5.0), + const Text("fl_oz_water", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 130, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[7]) {_OnUnitChange(7)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[7], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(7)} + }); + })), + const SizedBox(width: 5.0), + const Text("fl_oz_milk", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + const Text( + "state: ", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + width: 10, + height: 10, + ), + Text( + connectState, + style: const TextStyle(fontSize: 16), + ), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Row( + children: [ + ElevatedButton(onPressed: _tare, child: const Text("Tare")), + const SizedBox( + width: 15, + height: 10, + ), + ElevatedButton( + onPressed: _powerOff, child: const Text("power off")), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + )) + ], + ), + ), + ); + } + + void _tare() { + if (mac != null) { + IcBluetoothSdk.instance.deleteTareWeight(ICDevice(mac!), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _powerOff() { + if (mac != null) { + IcBluetoothSdk.instance.powerOffKitchenScale(ICDevice(mac!), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _OnUnitChange(int unit) { + log("_OnUnitChange"); + unitChecks[0] = unit == 0; + unitChecks[1] = unit == 1; + unitChecks[2] = unit == 2; + unitChecks[3] = unit == 3; + unitChecks[4] = unit == 4; + unitChecks[5] = unit == 5; + unitChecks[6] = unit == 6; + unitChecks[7] = unit == 7; + if (mac != null) { + IcBluetoothSdk.instance.setKitchenScaleUnit( + ICDevice(mac!), + ICConverUtil.kitchenScaleValueOf(unit), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.kitchen); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: + (ICDevice icDevice, ICAddDeviceCallBackCode code) {})); + } + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } else if (value == powerOff) { + if (mac != null) { + IcBluetoothSdk.instance.powerOffKitchenScale(ICDevice(mac), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState(() { + connectState = "Not Connect"; + }); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + DebugLogger.instance + .logText("onDeviceConnectionChanged: ${device.macAddr!} ->$state"); + mac = device.macAddr; + setState(() { + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) { + DebugLogger.instance + .logText("onReceiveKitchenScaleData: ${device.macAddr!} ->$data"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) {} + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) {} + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) {} + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) {} + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) {} +} diff --git a/gsf/lib/scale/page/log_page.dart b/gsf/lib/scale/page/log_page.dart new file mode 100644 index 0000000..072e5fe --- /dev/null +++ b/gsf/lib/scale/page/log_page.dart @@ -0,0 +1,65 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import '../../scale/utils/log_util.dart'; + +class LogPage extends StatefulWidget { + @override + State createState() => _LogPageState(); +} + +class _LogPageState extends State { + var result = ""; + + @override + void initState() { + super.initState(); + readLog(); + } + + void readLog() { + LogUtil.instance.readLog().then((value) { + log("读取:$value"); + setState(() { + result = value; + }); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Log"), + actions: [ + Container( + padding: const EdgeInsets.only(right: 10), + alignment: Alignment.center, + child: InkWell( + onTap: () { + LogUtil.instance.clearLog(); + readLog(); + }, + child: const Text("Clear Log"), + ), + ) + ], + ), + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + )) + ], + ), + ); + } +} diff --git a/gsf/lib/scale/page/main_home.dart b/gsf/lib/scale/page/main_home.dart new file mode 100644 index 0000000..9beda9e --- /dev/null +++ b/gsf/lib/scale/page/main_home.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/other/ICDeviceManagerConfig.dart'; + +import '../utils/NavigatorUtils.dart'; +import '../utils/local_storage.dart'; + +class MyHomePageScale extends StatefulWidget { + const MyHomePageScale({Key? key}) : super(key: key); + + @override + State createState() => _MyHomePageScaleState(); +} + +class _MyHomePageScaleState extends State { + @override + void initState() { + super.initState(); + LocalStorage.init(); + IcBluetoothSdk.instance.initSDK(ICDeviceManagerConfig()); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Scale'), + ), + body: Container( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + NavigatorUtils.goScaleHomePage(context); + }, + child: const Text( + "Scale", + style: TextStyle(fontSize: 20), + ), + ), + ), + const SizedBox( + width: 10, + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + NavigatorUtils.goKitchenScalePage(context); + }, + child: const Text( + "Kitchen Scale", + style: TextStyle(fontSize: 20), + )), + ), + const SizedBox( + width: 10, + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + NavigatorUtils.goRopePage(context); + }, + child: const Text( + "Jump Rope", + style: TextStyle(fontSize: 20), + )), + ), + const SizedBox( + width: 10, + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + NavigatorUtils.goRulerPage(context); + }, + child: const Text( + "Ruler ", + style: TextStyle(fontSize: 20), + )), + ), + const SizedBox( + width: 10, + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + NavigatorUtils.goHeightPage(context); + }, + child: const Text( + "Height ", + style: TextStyle(fontSize: 20), + )), + ), + ], + ), + ), + // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/gsf/lib/scale/page/ota_page.dart b/gsf/lib/scale/page/ota_page.dart new file mode 100644 index 0000000..ac0185a --- /dev/null +++ b/gsf/lib/scale/page/ota_page.dart @@ -0,0 +1,159 @@ + +import 'package:flutter/material.dart'; +import '../../scale/utils/log_util.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +class OTAPage extends StatefulWidget { + String mac; + + OTAPage(this.mac, {Key? key}) : super(key: key); + + @override + State createState() => _OTAPageState(); +} + +class _OTAPageState extends State implements ICDeviceManagerDelegate { + String percent = "升级进度:"; + + @override + void initState() { + super.initState(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + // otaDevice(); + } + + void otaDevice() { + var path = + "/data/user/0/cn.icomon.icblesdk.flutter.flutter_swift_example/cache/1649988516.zip"; + LogUtil.instance.writeLog("otaDevicex"); + IcBluetoothSdk.instance + .upgradeDevice(ICDevice(widget.mac), path, ICOTAMode.ICOTAModeAuto); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("OTA"), + ), + body: Center( + child: Column( + children: [ + SizedBox( + width: 10, + height: 50, + ), + Text(percent), + SizedBox( + width: 10, + height: 10, + ), + ElevatedButton( + onPressed: () { + otaDevice(); + }, + child: Text('OTA'), + ) + ], + ), + ), + ); + } + + @override + void onBleState(ICBleState state) {} + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) {} + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) {} + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent(ICDevice device, ICUpgradeStatus status, int p) { + setState(() { + if (status == ICUpgradeStatus.ICUpgradeStatusSuccess) { + this.percent = "升级成功"; + } else if (status == ICUpgradeStatus.ICUpgradeStatusUpgrading) { + this.percent = "升级进度:" + p.toString() + "%"; + } else { + this.percent = "升级失败"; + } + }); + } + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) {} + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) {} + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) {} + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) {} +} diff --git a/gsf/lib/scale/page/rope_home_page.dart b/gsf/lib/scale/page/rope_home_page.dart new file mode 100644 index 0000000..0d51fe8 --- /dev/null +++ b/gsf/lib/scale/page/rope_home_page.dart @@ -0,0 +1,805 @@ +import 'dart:developer'; + +import '../../scale/utils/log_util.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipLightSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipSoundSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/NavigatorUtils.dart'; +import '../../scale/utils/data_parse_util.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +class RopePage extends StatefulWidget { + @override + State createState() => _RopePageState(); +} + +class _RopePageState extends State + implements ICDeviceManagerDelegate { + var result = "Result:"; + var menuScan = "Scan"; + var menuConnect = "Connect"; + var menuDisConnect = "DisConnect"; + var menuLog = "Log"; + var settingUnit = ""; + var soundsSettingUnit = "times"; + var modeStr = "Free"; + var lightModeStr = "RPM"; + + var icLightMode = ICSkipLightMode.ICSkipLightModeRPM; + + List mode = [true, false, false]; + List lightMode = [true, false, false, false, false, false]; + + List soundsType = [true, false]; + List soundsMode = [true, false]; + List fullScore = [true]; + + var connectState = "Not Connect"; + String? mac; + var settingControl = TextEditingController(text: "0"); + var blueControl = TextEditingController(text: "50"); + var redControl = TextEditingController(text: "150"); + var greenControl = TextEditingController(text: "200"); + var soundsSettingControl = TextEditingController(text: "50"); + var fullScoreSettingControl = TextEditingController(text: "120"); + + @override + void initState() { + super.initState(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + LogUtil.instance.writeLog("page start"); + } + + @override + void dispose() { + super.dispose(); + LogUtil.instance.writeLog("page close"); + IcBluetoothSdk.instance.setDeviceManagerDelegate(null); + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuScan, child: Text(menuScan)), + PopupMenuItem(value: menuConnect, child: Text(menuConnect)), + PopupMenuItem(value: menuDisConnect, child: Text(menuDisConnect)), + PopupMenuItem(value: menuLog, child: Text(menuLog)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("Rope"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Skip Mode:"), + const SizedBox( + width: 15, + height: 5, + ), + InkWell( + onTap: _showModeTypeDialog, + child: Text( + modeStr, + style: const TextStyle(color: Colors.blue, fontSize: 16), + ), + ), + const SizedBox( + width: 30, + height: 5, + ), + const Text("Light Mode:"), + const SizedBox( + width: 15, + height: 5, + ), + InkWell( + onTap: _showLightModeTypeDialog, + child: Text( + lightModeStr, + style: const TextStyle(color: Colors.blue, fontSize: 16), + ), + ), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Row( + children: [ + const Text("Setting:"), + const SizedBox( + width: 10, + height: 10, + ), + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: settingControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + const SizedBox( + width: 5, + height: 5, + ), + Text(settingUnit), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Row( + children: [ + const Text( + "Light :", + style: TextStyle(fontSize: 14), + ), + const SizedBox( + width: 10, + height: 10, + ), + const Text( + "red ", + style: TextStyle(fontSize: 14), + ), + SizedBox( + width: 60, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: redControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + const SizedBox( + width: 5, + height: 5, + ), + const Text( + "blue ", + style: TextStyle(fontSize: 14), + ), + SizedBox( + width: 60, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: blueControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + const SizedBox( + width: 5, + height: 5, + ), + const Text( + "green ", + style: TextStyle(fontSize: 14), + ), + SizedBox( + width: 60, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: greenControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Row( + children: [ + const Text("Sound Type:"), + const SizedBox( + width: 15, + height: 5, + ), + InkWell( + onTap: _showSoundsTypeDialog, + child: Text( + soundsType[0] ? "Male" : "Female", + style: TextStyle(color: Colors.blue, fontSize: 15), + ), + ), + const SizedBox( + width: 50, + height: 10, + ), + const Text("Sound Mode:"), + const SizedBox( + width: 10, + height: 5, + ), + InkWell( + onTap: _showSoundsModeDialog, + child: Text( + soundsMode[0] ? "Count" : "Timer", + style: TextStyle(color: Colors.blue, fontSize: 15), + ), + ), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Row( + children: [ + const Text("Full Score BPM:"), + const SizedBox( + width: 5, + height: 5, + ), + SizedBox( + width: 60, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: fullScoreSettingControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + const Text("per/min"), + Checkbox( + value: fullScore[0], + onChanged: (value) { + setState(() => {fullScore[0] = value!}); + }) + ], + ), + Row( + children: [ + const Text("Sounds params:"), + const SizedBox( + width: 10, + height: 10, + ), + SizedBox( + width: 80, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: soundsSettingControl, + style: const TextStyle(color: Colors.blue), + autofocus: false, + ), + ), + const SizedBox( + width: 5, + height: 5, + ), + Text(soundsSettingUnit), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Row( + children: [ + const Text( + "state: ", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + width: 10, + height: 10, + ), + Text(connectState), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Row( + children: [ + ElevatedButton( + onPressed: _startSkip, child: const Text("Start")), + const SizedBox( + width: 10, + height: 10, + ), + ElevatedButton(onPressed: _stopSkip, child: const Text("Stop")), + const SizedBox( + width: 10, + height: 10, + ), + ElevatedButton( + onPressed: _setLight, child: const Text("Set Light")), + const SizedBox( + width: 10, + height: 10, + ), + ElevatedButton( + onPressed: _setSounds, child: const Text("Set Sounds")), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + )) + ], + ), + ), + ); + } + + void _startSkip() { + if (mac != null) { + ICSkipMode skipMode = _getSkipMode(); + var setting = settingControl.text; + if (skipMode != ICSkipMode.ICSkipModeFreedom) { + if (setting.isEmpty) { + Fluttertoast.showToast(msg: "setting is null"); + return; + } + } + var params = DataPareUtil.stringToInt(setting); + + IcBluetoothSdk.instance.startSkipMode(ICDevice(mac), skipMode, params, + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + ICSkipMode _getSkipMode() { + if (mode[1]) { + return ICSkipMode.ICSkipModeTiming; + } else if (mode[2]) { + return ICSkipMode.ICSkipModeCount; + } + return ICSkipMode.ICSkipModeFreedom; + } + + void _showLightModeTypeDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return SimpleDialog( + title: const Text('Light Mode'), + children: [ + SimpleDialogOption( + child: const Text('RPM'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModeRPM; + setState(() { + lightModeStr = "RPM"; + lightMode = [true, false, false, false, false, false]; + }); + }, + ), + SimpleDialogOption( + child: const Text('Timer'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModeTimer; + setState(() { + lightModeStr = "Timer"; + lightMode = [false, true, false, false, false, false]; + }); + }, + ), + SimpleDialogOption( + child: const Text('Count'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModeCount; + setState(() { + lightModeStr = "Count"; + lightMode = [false, false, true, false, false, false]; + }); + }, + ), + SimpleDialogOption( + child: const Text('Percent'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModePercent; + setState(() { + lightModeStr = "Percent"; + lightMode = [false, false, false, true, false, false]; + }); + }, + ), + SimpleDialogOption( + child: const Text('TripRope'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModeTripRope; + setState(() { + lightModeStr = "TripRope"; + lightMode = [false, false, false, false, true, false]; + }); + }, + ), + SimpleDialogOption( + child: const Text('Measuring'), + onPressed: () { + Navigator.of(context).pop(); + icLightMode = ICSkipLightMode.ICSkipLightModeMeasuring; + setState(() { + lightModeStr = "Measuring"; + lightMode = [false, false, false, false, false, true]; + }); + }, + ), + ], + ); + }, + ); + } + + void _showModeTypeDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return SimpleDialog( + title: const Text('Skip Mode'), + children: [ + SimpleDialogOption( + child: const Text('Free'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + modeStr = "Free"; + mode[0] = true; + mode[1] = false; + mode[2] = false; + settingUnit = ""; + }); + }, + ), + SimpleDialogOption( + child: const Text('Timer'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + modeStr = "Timer"; + settingUnit = "second"; + mode[0] = false; + mode[1] = true; + mode[2] = false; + }); + }, + ), + SimpleDialogOption( + child: const Text('Count'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + modeStr = "Count"; + mode[0] = false; + mode[1] = true; + mode[2] = false; + settingUnit = "time"; + }); + }, + ), + ], + ); + }, + ); + } + + void _showSoundsTypeDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return SimpleDialog( + title: const Text('Sounds Type'), + children: [ + SimpleDialogOption( + child: const Text('Male'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + soundsType[0] = true; + soundsType[1] = false; + }); + }, + ), + SimpleDialogOption( + child: const Text('Female'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + soundsType[1] = true; + soundsType[0] = false; + }); + }, + ), + ], + ); + }, + ); + } + + void _showSoundsModeDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return SimpleDialog( + title: const Text('Sounds Mode'), + children: [ + SimpleDialogOption( + child: const Text('Count'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + soundsSettingUnit = "times"; + soundsMode[0] = true; + soundsMode[1] = false; + }); + }, + ), + SimpleDialogOption( + child: const Text('Timer'), + onPressed: () { + Navigator.of(context).pop(); + setState(() { + soundsSettingUnit = "seconds"; + soundsMode[1] = true; + soundsMode[0] = false; + }); + }, + ), + ], + ); + }, + ); + } + + void _stopSkip() { + if (mac != null) { + IcBluetoothSdk.instance.stopSkip(ICDevice(mac), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _setLight() { + if (mac != null) { + ICSkipLightSettingData red = ICSkipLightSettingData(); + red.rpm = DataPareUtil.stringToInt(redControl.text); + red.r = 255; + ICSkipLightSettingData blue = ICSkipLightSettingData(); + blue.rpm = DataPareUtil.stringToInt(blueControl.text); + blue.b = 255; + ICSkipLightSettingData green = ICSkipLightSettingData(); + green.rpm = DataPareUtil.stringToInt(greenControl.text); + green.g = 255; + List lightEffects = []; + lightEffects.add(red); + lightEffects.add(blue); + lightEffects.add(green); + + IcBluetoothSdk.instance.setSkipLightSetting( + ICDevice(mac), + lightEffects, + icLightMode, + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _setSounds() { + if (mac != null) { + var data = ICSkipSoundSettingData(); + data.soundOn = true; + data.soundVolume = 20; + data.fullScoreOn = fullScore[0]; + if (data.fullScoreOn) { + data.fullScoreBPM = + DataPareUtil.stringToInt(fullScoreSettingControl.text); + } + if (soundsType[0]) { + data.soundType = ICSkipSoundType.ICSkipSoundTypeMale; + } else { + data.soundType = ICSkipSoundType.ICSkipSoundTypeFemale; + } + + if (soundsMode[0]) { + data.soundMode = ICSkipSoundMode.ICSkipSoundModeCount; + } else { + data.soundMode = ICSkipSoundMode.ICSkipSoundModeTime; + } + data.modeParam = DataPareUtil.stringToInt(soundsSettingControl.text); + + IcBluetoothSdk.instance.setSkipSoundSetting(ICDevice(mac), data, + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.rope); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: + (ICDevice icDevice, ICAddDeviceCallBackCode code) {})); + } + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState(() { + connectState = "Not Connect"; + }); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + print("onDeviceConnectionChanged ${device.macAddr}"); + mac = device.macAddr; + setState(() { + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) { + print("onReceiveHistorySkipData ${device.macAddr}"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) {} + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) { + print("onReceiveSkipData ${device.macAddr}"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) {} + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) {} + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) {} + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) {} +} diff --git a/gsf/lib/scale/page/ruler_home_page.dart b/gsf/lib/scale/page/ruler_home_page.dart new file mode 100644 index 0000000..23087a7 --- /dev/null +++ b/gsf/lib/scale/page/ruler_home_page.dart @@ -0,0 +1,312 @@ +import 'dart:developer'; + +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/NavigatorUtils.dart'; +import '../../scale/utils/debug_logger.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:flutter/material.dart'; + +class RulerPage extends StatefulWidget { + @override + State createState() => _RulerPageState(); +} + +class _RulerPageState extends State + implements ICDeviceManagerDelegate { + var result = "Result:"; + var menuScan = "Scan"; + var menuConnect = "Connect"; + var menuDisConnect = "DisConnect"; + var menuLog = "Log"; + List unitChecks = [true, false]; + var connectState = "Not Connect"; + String? mac; + + @override + void initState() { + super.initState(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + } + + @override + void dispose() { + super.dispose(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(null); + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuScan, child: Text(menuScan)), + PopupMenuItem(value: menuConnect, child: Text(menuConnect)), + PopupMenuItem(value: menuDisConnect, child: Text(menuDisConnect)), + PopupMenuItem(value: menuLog, child: Text(menuLog)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("Ruler"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Unit:"), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[0]) {_UnitChange(0)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: unitChecks[0], + onChanged: (value) { + setState(() => { + if (value!) {_UnitChange(0)} + }); + })), + const SizedBox(width: 10.0), + const Text("cm", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[1]) {_UnitChange(1)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: unitChecks[1], + onChanged: (value) { + setState(() => { + if (value!) {_UnitChange(1)} + }); + })), + const SizedBox(width: 10.0), + const Text("inch", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + const Text( + "state: ", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + width: 10, + height: 10, + ), + Text(connectState), + ], + ), + const SizedBox( + width: 10, + height: 15, + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + )) + ], + ), + ), + ); + } + + void _UnitChange(int unit) { + log("_OnUnitChange"); + unitChecks[0] = unit == 0; + unitChecks[1] = unit == 1; + } + + void _menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.ruler); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: + (ICDevice icDevice, ICAddDeviceCallBackCode code) {})); + } + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState(() { + connectState = "Not Connect"; + }); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + DebugLogger.instance + .logText("onDeviceConnectionChanged: ${device.macAddr!} ->$state"); + mac = device.macAddr; + setState(() { + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) {} + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) { + DebugLogger.instance + .logText("onReceiveRulerData: ${device.macAddr!} ->$data"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) { + DebugLogger.instance + .logText("onReceiveRulerHistoryData: ${device.macAddr!} ->$data"); + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) {} + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) {} + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) {} + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) {} +} diff --git a/gsf/lib/scale/page/scale_home_page.dart b/gsf/lib/scale/page/scale_home_page.dart new file mode 100644 index 0000000..9d9fab3 --- /dev/null +++ b/gsf/lib/scale/page/scale_home_page.dart @@ -0,0 +1,827 @@ +import 'dart:developer'; +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import '../../scale/utils/event_bus.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICCommonCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICFatAlgorithmsSettingCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/model/device_type.dart'; +import '../../scale/utils/NavigatorUtils.dart'; +import '../../scale/utils/data_parse_util.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:icdevicemanager_flutter/utils/ICConverUtil.dart'; + +import '../../scale/utils/debug_logger.dart'; + +class ScaleHomePage extends StatefulWidget { + const ScaleHomePage({Key? key}) : super(key: key); + + @override + State createState() => _ScaleHomePageState(); +} + +class _ScaleHomePageState extends State + implements ICDeviceManagerDelegate { + List sexChecks = [false, false]; + + List unitChecks = [true, false, false, false]; + + var result = "Result:"; + var connectState = "Not Connect"; + var menuScan = "Scan"; + var menuUserList = "UserList"; + var menuConnect = "Connect"; + var menuDisConnect = "DisConnect"; + var menuOTA = "OTA"; + var menuLog = "Log"; + + String? age; + String? height; + String? weight; + String? imp; + String? mac; + + ICUserInfo user = ICUserInfo(); + + List userList = []; + int spActiveId = 0; + + @override + void initState() { + super.initState(); + _initData(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + //getLogPath(); + eventBus.on().listen( + (event) { + if ("update_list" == event) { + if (mounted) { + setState(() { + _initData(); + user; + }); + } + } + }, + ); + + //del + _UpdateUser(); + } + + void getLogPath() { + IcBluetoothSdk.instance + .getLogPath(ICCommonCallback(callBack: (dynamic value) { + if (value != null) { + log("日记路径:" + value); + } else { + log("日记路径:null"); + } + })); + } + + @override + void dispose() { + super.dispose(); + IcBluetoothSdk.instance.setDeviceManagerDelegate(null); + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {}, + ), + ); + } + } + + void _initData() { + var value = LocalStorage.getData("UserList"); + + userList.clear(); + if (value != null) { + log("spUser " + value); + userList = List.from( + json.decode(value).map( + (model) => ICUserInfo.fromJson(model), + ), + ); + } + var acId = LocalStorage.getData("activeUserId"); + if (acId != null) spActiveId = acId; + + if (userList.isEmpty || spActiveId <= 0) { + log("spUser ==null "); + user.userId = 1; + user.userIndex = 1; + user.sex = ICSexType.ICSexTypeMale; + user.height = 172; + user.lastImp = 520; + user.weight = 55; + userList.add(user); + List> jsonData = + userList.map((dev) => dev.toJson()).toList(); + var jsonString = json.encode(jsonData); + LocalStorage.saveData("UserList", jsonString); + LocalStorage.saveData("activeUserId", 1); + } else { + for (var element in userList) { + if (element.userId == spActiveId) { + user = element; + break; + } + } + } + + if (user.sex == ICSexType.ICSexTypeFemale) { + sexChecks[0] = false; + sexChecks[1] = true; + } else { + sexChecks[0] = true; + sexChecks[1] = false; + } + + imp = user.lastImp.toString(); + weight = user.weight.toString(); + age = user.age.toString(); + height = user.height.toString(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuScan, child: Text(menuScan)), + PopupMenuItem(value: menuUserList, child: Text(menuUserList)), + PopupMenuItem(value: menuConnect, child: Text(menuConnect)), + PopupMenuItem( + value: menuDisConnect, child: Text(menuDisConnect)), + PopupMenuItem(value: menuOTA, child: Text(menuOTA)), + PopupMenuItem(value: menuLog, child: Text(menuLog)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("Scale"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Sex: "), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () => { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = !sexChecks[0] + }), + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[0], + onChanged: (value) { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = value! + }); + })), + const SizedBox(width: 10.0), + const Text( + "Male", + style: TextStyle(color: Colors.black), + ) + ], + ), + ), + ), + SizedBox( + width: 140, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: + MaterialStateProperty.all(Colors.transparent)), + onPressed: () { + setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = !sexChecks[1] + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[1], + onChanged: (value) { + setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = value! + }); + }, + ), + ), + const SizedBox(width: 10.0), + const Text( + "FeMale", + style: TextStyle(color: Colors.black), + ) + ], + ), + ), + ), + ], + ), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + decoration: const InputDecoration( + icon: Text("Age:"), + ), + controller: + TextEditingController(text: user.age.toString()), + onChanged: (value) { + age = value; + }, + autofocus: false, + ), + ), + const Padding( + padding: EdgeInsets.only( + right: 20, + ), + ), + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: + TextEditingController(text: user.height.toString()), + decoration: const InputDecoration( + icon: Text("Height:"), + ), + onChanged: (value) { + height = value; + }, + autofocus: false, + ), + ), + const Text("cm") + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 90, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + controller: TextEditingController( + text: user.userIndex.toString()), + decoration: const InputDecoration( + icon: Text("Index:"), + ), + enabled: false, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 5)), + SizedBox( + width: 90, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: TextEditingController(text: imp), + decoration: const InputDecoration( + icon: Text("Imp:"), + ), + onChanged: (value) { + imp = value; + }, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 10)), + SizedBox( + width: 120, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: TextEditingController(text: weight), + decoration: const InputDecoration( + icon: Text( + "Weight:", + style: TextStyle(fontSize: 14), + ), + ), + onChanged: (value) { + weight = value; + }, + autofocus: false, + ), + ), + const Text("kg") + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + controller: + TextEditingController(text: user.userId.toString()), + style: const TextStyle(color: Colors.blue), + decoration: const InputDecoration( + icon: Text("UserId:"), + ), + enabled: false, + autofocus: false, + ), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 120, + height: 40, + child: ElevatedButton( + onPressed: _UpdateUser, + child: const Text("Update User")), + ), + const SizedBox( + width: 20, + height: 10, + ), + SizedBox( + width: 120, + height: 40, + child: ElevatedButton( + onPressed: _CalcBodyFat, + child: const Text("CalcBodyFat")), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + const Text("Unit:"), + SizedBox( + width: 75, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[0]) {_OnUnitChange(0)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[0], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(0)} + }); + })), + const SizedBox(width: 10.0), + const Text("kg", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[1]) {_OnUnitChange(1)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[1], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(1)} + }); + })), + const SizedBox(width: 10.0), + const Text("lb", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 90, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[2]) {_OnUnitChange(2)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[2], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(2)} + }); + })), + const SizedBox(width: 10.0), + const Text("st:lb", + style: TextStyle(color: Colors.black)) + ])), + ), + SizedBox( + width: 70, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + if (!unitChecks[3]) {_OnUnitChange(3)} + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 14.0, + width: 14.0, + child: Checkbox( + value: unitChecks[3], + onChanged: (value) { + setState(() => { + if (value!) {_OnUnitChange(3)} + }); + })), + const SizedBox(width: 5.0), + const Text("jin", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + const Text( + "state: ", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + width: 10, + height: 10, + ), + Text(connectState), + ], + ), + const SizedBox( + width: 10, + height: 10, + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: Text( + result, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 18), + ), + ), + ), + ) + ], + ))); + } + + void _UpdateUser() { + // if (height != null && height!.isNotEmpty) { + user.height = 400; //DataPareUtil.stringToInt(height!); + // } + if (age != null && age!.isNotEmpty) { + user.age = DataPareUtil.stringToInt(age!); + } + if (weight != null && weight!.isNotEmpty) { + user.weight = DataPareUtil.stringToDouble(weight!); + } + // user.sex = ICSexType.ICSexTypeFemale; + String gender = 'male'; + + ICSexType scaleGender = + gender == 'male' ? ICSexType.ICSexTypeMale : ICSexType.ICSexTypeFemale; + + user.sex = scaleGender; + if (imp != null && imp!.isNotEmpty) { + user.lastImp = DataPareUtil.stringToInt(imp!); + } + + int listIndex = 0; + userList.asMap().forEach((index, value) { + if (value.userId == user.userId) { + listIndex = index; + } + }); + userList[listIndex] = user; + + List> jsonData = + userList.map((dev) => dev.toJson()).toList(); + LocalStorage.saveData("UserList", json.encode(jsonData)); + + DebugLogger.instance.logText("updateUserInfo --> $user"); + // DebugLogger.instance.logText("setUserList$userList"); + + // user.bfaType = ICBFAType.ICBFATypeWLA02; + IcBluetoothSdk.instance.updateUserInfo(user); + IcBluetoothSdk.instance.setUserList(userList); + debugPrint("IcBluetoothSdk ${user.age}"); + } + + void _CalcBodyFat() { + ICWeightData weightData = ICWeightData(); + weightData.imp = 530; + weightData.weight_kg = 78; + weightData.bfa_type = ICBFAType.ICBFATypeWLA02; + + ICUserInfo userInfo = ICUserInfo(); + userInfo.sex = ICSexType.ICSexTypeFemale; + userInfo.age = 25; + userInfo.height = 175; + userInfo.peopleType = ICPeopleType.ICPeopleTypeNormal; + + IcBluetoothSdk.instance.reCalcBodyFatWithWeightData(weightData, userInfo, + ICFatAlgorithmsSettingCallback(callBack: (ICWeightData code) { + log("_ScaleHomePageState _CalcBodyFat---" + code.toString()); + })); + } + + void _OnUnitChange(int unit) { + unitChecks[0] = unit == 0; + unitChecks[1] = unit == 1; + unitChecks[2] = unit == 2; + unitChecks[3] = unit == 3; + log("ICBluetoothManger flutter 设置单位---" + mac.toString()); + if (mac != null) { + IcBluetoothSdk.instance.setScaleUnit( + ICDevice(mac!), + ICConverUtil.weightUnitValueOf(unit), + ICSettingCallback(callBack: (ICSettingCallBackCode code) {})); + } + } + + void _menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.scale); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuUserList) { + NavigatorUtils.goUserListPage(context); + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: (ICDevice icDevice, ICAddDeviceCallBackCode code) {}, + ), + ); + } + } else if (value == menuOTA) { + if (mac != null) { + NavigatorUtils.goOTAPage(context, mac!); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState( + () { + connectState = "Not Connect"; + }, + ); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + DebugLogger.instance + .logText("onDeviceConnectionChanged: ${device.macAddr!} ->$state"); + setState(() { + mac = device.macAddr; + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) { + DebugLogger.instance.logText("onReceiveMeasureStepData:步骤 $step"); + if (step == ICMeasureStep.ICMeasureStepMeasureOver) { + var icWeight = data as ICWeightData; + user.weight = icWeight.weight_kg; + user.lastImp = icWeight.imp.toInt(); + DebugLogger.instance + .logText("ICMeasureStepMeasureOver ${device.macAddr!} ->$data"); + } + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\nstep:$step\n$data"; + }); + } + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) { + if (data.isStabilized) { + DebugLogger.instance + .logText("onReceiveWeightCenterData: ${device.macAddr!} ->$data"); + } + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) { + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\nWeightData weight:$data"; + }); + if (data.isStabilized) { + DebugLogger.instance + .logText("onReceiveWeightData: ${device.macAddr!} ->$data"); + setState(() { + user.weight = data.weight_kg; + user.lastImp = data.imp as int; + }); + } + } + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) { + DebugLogger.instance + .logText("onReceiveWeightHistoryData: ${device.macAddr!} ->$data"); + setState(() { + mac = device.macAddr; + connectState = "Connected"; + result = "Result:\nHistoryData$data"; + }); + } + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) { + var value = LocalStorage.getData("communicationType:${device.macAddr}"); + log("onReceiveWeightUnitChanged " + value); + if (value != null) { + if (value == 0) { + return; + } + } + unitChecks[0] = ICWeightUnit.ICWeightUnitKg == unit; + unitChecks[1] = ICWeightUnit.ICWeightUnitLb == unit; + unitChecks[2] = ICWeightUnit.ICWeightUnitSt == unit; + unitChecks[3] = ICWeightUnit.ICWeightUnitJin == unit; + setState(() { + unitChecks; + }); + } +} diff --git a/gsf/lib/scale/page/user_add_page.dart b/gsf/lib/scale/page/user_add_page.dart new file mode 100644 index 0000000..45cab09 --- /dev/null +++ b/gsf/lib/scale/page/user_add_page.dart @@ -0,0 +1,438 @@ +import 'dart:convert'; +import 'dart:ffi'; +import 'dart:math'; + +import '../../scale/utils/event_bus.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/utils/data_parse_util.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import '../../scale/utils/random_util.dart'; + +class UserAddPage extends StatefulWidget { + @override + State createState() => _UserAddPageState(); +} + +class _UserAddPageState extends State { + List sexChecks = [true, false]; + List peopleTypeChecks = [true, false]; + + List userIndexList = []; + List userIdList = []; + List users = []; + + int userIndex = 0; + int userId = 0; + + String? age; + String? height; + String? weight; + String? imp; + String? index; + String? id; + + Color indexTextColor = Colors.blue; + Color idTextColor = Colors.blue; + + late TextEditingController userIndexController; + + late TextEditingController userIdController; + + @override + void initState() { + super.initState(); + initData(); + userIndex = ICRandomUtil.getRandomUserIndex(userIndexList); + userId = ICRandomUtil.getRandomUserId(userIdList, Random().nextInt(1000)); + userIndexController = TextEditingController(text: userIndex.toString()); + userIdController = TextEditingController(text: userId.toString()); + } + + void initData() { + var value = LocalStorage.getData("UserList"); + if (value != null) { + users = List.from( + json.decode(value).map((model) => ICUserInfo.fromJson(model))); + } + userIndexList.clear(); + userIdList.clear(); + for (var user in users) { + userIndexList.add(user.userIndex); + userIdList.add(user.userId); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("User Add"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Sex: "), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = !sexChecks[0] + }), + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[0], + onChanged: (value) { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = value! + }); + })), + const SizedBox(width: 10.0), + const Text( + "Male", + style: TextStyle(color: Colors.black), + ) + ]))), + SizedBox( + width: 140, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = !sexChecks[1] + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[1], + onChanged: (value) { + setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = value! + }); + })), + const SizedBox(width: 10.0), + const Text("FeMale", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + decoration: const InputDecoration( + icon: Text("Age:"), + ), + onChanged: (String value) { + age = value; + }, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 20)), + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + decoration: const InputDecoration( + icon: Text("Height:"), + ), + onChanged: (String value) { + height = value; + }, + autofocus: false, + ), + ), + const Text("cm") + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + controller: userIndexController, + style: TextStyle(color: indexTextColor), + onChanged: _onUserIndexChange, + decoration: const InputDecoration( + icon: Text("Index:"), + ), + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 10)), + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + keyboardType: TextInputType.number, + decoration: const InputDecoration( + icon: Text("Imp:"), + ), + onChanged: (String value) { + imp = value; + }, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 20)), + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + decoration: const InputDecoration( + icon: Text("Weight:"), + ), + onChanged: (String value) { + weight = value; + }, + autofocus: false, + ), + ), + const Text("kg") + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + controller: userIdController, + style: TextStyle(color: idTextColor), + onChanged: _onUserIdChange, + decoration: const InputDecoration( + icon: Text("UserId:"), + ), + autofocus: false, + ), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + const Text("People Type: "), + SizedBox( + width: 120, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => { + setState( + () => { + peopleTypeChecks[1] = peopleTypeChecks[0], + peopleTypeChecks[0] = !peopleTypeChecks[0] + }, + ), + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: peopleTypeChecks[1], + onChanged: (value) { + setState( + () => { + peopleTypeChecks[1] = + peopleTypeChecks[0], + peopleTypeChecks[0] = value! + }, + ); + })), + const SizedBox(width: 10.0), + const Text( + "Normal", + style: TextStyle(color: Colors.black), + ) + ]))), + SizedBox( + width: 120, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + peopleTypeChecks[0] = peopleTypeChecks[1], + peopleTypeChecks[1] = !peopleTypeChecks[1] + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: peopleTypeChecks[0], + onChanged: (value) { + setState(() => { + peopleTypeChecks[0] = + peopleTypeChecks[1], + peopleTypeChecks[1] = value! + }); + })), + const SizedBox(width: 10.0), + const Text("Sport", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 30)), + SizedBox( + width: 250, + height: 40, + child: ElevatedButton( + onPressed: saveList, child: const Text("Save")), + ) + ], + ))); + } + + void _onUserIndexChange(String? value) { + index = value; + if (value != null && value.isNotEmpty) { + var index = DataPareUtil.stringToInt(value); + setState(() { + if (userIndexList.contains(index)) { + indexTextColor = Colors.red; + } else { + if (index < 1 || index > 4) { + indexTextColor = Colors.red; + } else { + indexTextColor = Colors.blue; + } + } + }); + } + } + + void _onUserIdChange(String? value) { + id = value; + if (value != null && value.isNotEmpty) { + setState(() { + if (userIdList.contains(DataPareUtil.stringToInt(value))) { + idTextColor = Colors.red; + } else { + idTextColor = Colors.blue; + } + }); + } + } + + void saveList() { + FocusManager.instance.primaryFocus?.unfocus(); + ICUserInfo icafUser = createUser(); + if (userIndexList.contains(icafUser.userIndex)) { + Fluttertoast.showToast(msg: "User list already contains this Index"); + return; + } + if (userIdList.contains(icafUser.userId)) { + Fluttertoast.showToast(msg: "User list already contains this UserId"); + return; + } + + if (icafUser.userIndex > 4 || icafUser.userIndex < 1) { + Fluttertoast.showToast(msg: "User Index Only enter 1-4"); + return; + } + users.add(icafUser); + List> jsonData = + users.map((dev) => dev.toJson()).toList(); + LocalStorage.saveData("UserList", json.encode(jsonData)); + eventBus.fire("update_list"); + Navigator.pop(context); + } + + ICUserInfo createUser() { + index = userIndexController.text; + id = userIdController.text; + ICUserInfo icafUser = ICUserInfo(); + icafUser.age = age == null ? 0 : DataPareUtil.stringToInt(age!); + icafUser.height = height == null ? 0 : DataPareUtil.stringToDouble(height!); + icafUser.userId = id == null ? 0 : DataPareUtil.stringToInt(id!); + icafUser.userIndex = index == null ? 0 : DataPareUtil.stringToInt(index!); + icafUser.lastImp = imp == null ? 0 : DataPareUtil.stringToInt(imp!); + icafUser.weight = weight == null ? 0 : DataPareUtil.stringToDouble(weight!); + if (sexChecks[0]) { + icafUser.sex = ICSexType.ICSexTypeMale; + } else { + icafUser.sex = ICSexType.ICSexTypeFemale; + } + if (peopleTypeChecks[0]) { + icafUser.peopleType = ICPeopleType.ICPeopleTypeNormal; + } else { + icafUser.peopleType = ICPeopleType.ICPeopleTypeSportman; + } + return icafUser; + } +} diff --git a/gsf/lib/scale/page/user_edit_page.dart b/gsf/lib/scale/page/user_edit_page.dart new file mode 100644 index 0000000..fdf89f8 --- /dev/null +++ b/gsf/lib/scale/page/user_edit_page.dart @@ -0,0 +1,494 @@ +import 'dart:convert'; + +import '../../scale/utils/event_bus.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/utils/data_parse_util.dart'; +import '../../scale/utils/local_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +class UserEditPage extends StatefulWidget { + ICUserInfo user; + int listPosition; + + UserEditPage(this.user, this.listPosition); + + @override + State createState() => _UserEditPageState(); +} + +class _UserEditPageState extends State { + List sexChecks = [true, false]; + List peopleTypeChecks = [true, false]; + + List userIndexList = []; + List userIdList = []; + List users = []; + + int activeUserId = 0; + int userIndex = 0; + int userId = 0; + + String? age; + String? height; + String? weight; + String? imp; + String? index; + String? id; + + Color indexTextColor = Colors.blue; + Color idTextColor = Colors.blue; + @override + void initState() { + super.initState(); + initData(); + userIndex = widget.user.userIndex; + userId = widget.user.userId; + + sexChecks[0] = widget.user.sex == ICSexType.ICSexTypeMale; + sexChecks[1] = widget.user.sex == ICSexType.ICSexTypeFemale; + peopleTypeChecks[0] = + widget.user.peopleType == ICPeopleType.ICPeopleTypeNormal; + peopleTypeChecks[1] = + widget.user.peopleType == ICPeopleType.ICPeopleTypeSportman; + age = widget.user.age.toString(); + height = widget.user.height.toString(); + weight = widget.user.weight.toString(); + imp = widget.user.lastImp.toString(); + id = widget.user.userId.toString(); + index = widget.user.userIndex.toString(); + } + + void initData() { + var acId = LocalStorage.getData("activeUserId"); + if (acId != null) activeUserId = acId; + + var value = LocalStorage.getData("UserList"); + if (value != null) { + users = List.from( + json.decode(value).map((model) => ICUserInfo.fromJson(model))); + } + userIndexList.clear(); + userIdList.clear(); + for (var user in users) { + userIndexList.add(user.userIndex); + userIdList.add(user.userId); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("User Edit"), + ), + body: Container( + padding: const EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + const Text("Sex: "), + SizedBox( + width: 100, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = !sexChecks[0] + }), + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[0], + onChanged: (value) { + setState(() => { + sexChecks[1] = sexChecks[0], + sexChecks[0] = value! + }); + })), + const SizedBox(width: 10.0), + const Text( + "Male", + style: TextStyle(color: Colors.black), + ) + ]))), + SizedBox( + width: 140, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = !sexChecks[1] + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: sexChecks[1], + onChanged: (value) { + setState(() => { + sexChecks[0] = sexChecks[1], + sexChecks[1] = value! + }); + })), + const SizedBox(width: 10.0), + const Text("FeMale", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: TextEditingController(text: age), + decoration: const InputDecoration( + icon: Text("Age:"), + ), + onChanged: (value) { + age = value; + }, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 20)), + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: TextEditingController(text: height), + decoration: const InputDecoration( + icon: Text("Height:"), + ), + onChanged: (value) { + height = value; + }, + autofocus: false, + ), + ), + const Text("cm") + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: + TextEditingController(text: userIndex.toString()), + style: const TextStyle(color: Colors.blue), + onChanged: _onUserIndexChange, + decoration: const InputDecoration( + icon: Text("Index:"), + ), + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 10)), + SizedBox( + width: 100, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle(color: Colors.blue), + keyboardType: TextInputType.number, + controller: TextEditingController(text: imp), + decoration: const InputDecoration( + icon: Text("Imp:"), + ), + onChanged: (value) { + imp = value; + }, + autofocus: false, + ), + ), + const Padding(padding: EdgeInsets.only(right: 10)), + SizedBox( + width: 110, + height: 30, + child: TextField( + maxLines: 1, + style: const TextStyle( + color: Colors.blue, + ), + keyboardType: TextInputType.number, + controller: TextEditingController(text: weight), + decoration: const InputDecoration( + icon: Text( + "Weight:", + style: TextStyle(fontSize: 14), + ), + ), + onChanged: (value) { + weight = value; + }, + autofocus: false, + ), + ), + const Text( + "kg", + style: TextStyle(fontSize: 14), + ) + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + SizedBox( + width: 140, + height: 30, + child: TextField( + maxLines: 1, + keyboardType: TextInputType.number, + controller: + TextEditingController(text: userId.toString()), + style: const TextStyle(color: Colors.blue), + onChanged: _onUserIdChange, + decoration: const InputDecoration( + icon: Text("UserId:"), + ), + autofocus: false, + ), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 10)), + Row( + children: [ + const Text("People Type: "), + SizedBox( + width: 140, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => { + setState( + () => { + peopleTypeChecks[1] = peopleTypeChecks[0], + peopleTypeChecks[0] = !peopleTypeChecks[0] + }, + ), + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: peopleTypeChecks[0], + onChanged: (value) { + setState( + () => { + peopleTypeChecks[1] = + peopleTypeChecks[0], + peopleTypeChecks[0] = value! + }, + ); + })), + const SizedBox(width: 10.0), + const Text( + "Normal", + style: TextStyle(color: Colors.black), + ) + ]))), + SizedBox( + width: 110, + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: MaterialStateProperty.all( + Colors.transparent)), + onPressed: () => setState(() => { + peopleTypeChecks[0] = peopleTypeChecks[1], + peopleTypeChecks[1] = !peopleTypeChecks[1] + }), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: peopleTypeChecks[1], + onChanged: (value) { + setState( + () => { + peopleTypeChecks[0] = + peopleTypeChecks[1], + peopleTypeChecks[1] = value! + }, + ); + })), + const SizedBox(width: 10.0), + const Text("Sport", + style: TextStyle(color: Colors.black)) + ])), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 30)), + Row( + children: [ + SizedBox( + width: 110, + height: 40, + child: ElevatedButton( + onPressed: _saveList, child: const Text("Save")), + ), + const SizedBox( + width: 15, + height: 10, + ), + if (activeUserId != widget.user.userId) + SizedBox( + width: 110, + height: 40, + child: ElevatedButton( + onPressed: _activeUser, + child: const Text("Active")), + ), + const SizedBox( + width: 15, + height: 10, + ), + if (activeUserId != widget.user.userId) + SizedBox( + width: 110, + height: 40, + child: ElevatedButton( + onPressed: _deleteUser, + child: const Text("Delete")), + ), + ], + ), + ], + ))); + } + + void _deleteUser() { + users.removeAt(widget.listPosition); + List> jsonData = + users.map((dev) => dev.toJson()).toList(); + LocalStorage.saveData("UserList", json.encode(jsonData)); + eventBus.fire("update_list"); + Navigator.pop(context); + } + + void _activeUser() { + LocalStorage.saveData("activeUserId", widget.user.userId); + eventBus.fire("update_list"); + Navigator.pop(context); + } + + void _onUserIndexChange(String? value) { + index = value; + if (value != null && value.isNotEmpty) { + var index = DataPareUtil.stringToInt(value); + setState(() { + if (userIndexList.contains(index)) { + indexTextColor = Colors.red; + } else { + if (index < 1 || index > 4) { + indexTextColor = Colors.red; + } else { + indexTextColor = Colors.blue; + } + } + }); + } + } + + void _onUserIdChange(String? value) { + id = value; + if (value != null && value.isNotEmpty) { + var id = DataPareUtil.stringToInt(value); + setState(() { + if (userIdList.contains(id)) { + idTextColor = Colors.red; + } else { + idTextColor = Colors.blue; + } + }); + } + } + + void _saveList() { + widget.user.age = age == null ? 0 : DataPareUtil.stringToInt(age!); + widget.user.height = + height == null ? 0 : DataPareUtil.stringToDouble(height!); + widget.user.weight = + weight == null ? 0 : DataPareUtil.stringToDouble(weight!); + widget.user.lastImp = imp == null ? 0 : DataPareUtil.stringToInt(imp!); + widget.user.userId = id == null ? 0 : DataPareUtil.stringToInt(id!); + widget.user.userIndex = + index == null ? 0 : DataPareUtil.stringToInt(index!); + if (sexChecks[0]) { + widget.user.sex = ICSexType.ICSexTypeMale; + } else { + widget.user.sex = ICSexType.ICSexTypeFemale; + } + widget.user.peopleType = ICPeopleType.ICPeopleTypeNormal; + if (peopleTypeChecks[0]) { + widget.user.peopleType = ICPeopleType.ICPeopleTypeNormal; + } else { + widget.user.peopleType = ICPeopleType.ICPeopleTypeSportman; + } + + if (widget.user.userIndex < 1 || widget.user.userIndex > 4) { + Fluttertoast.showToast(msg: "User Index Only enter 1-4"); + return; + } + + if (userIndex != widget.user.userIndex && + userIndexList.contains(widget.user.userIndex)) { + Fluttertoast.showToast(msg: "User list already contains this Index"); + return; + } + if (userId != widget.user.userId && + userIdList.contains(widget.user.userId)) { + Fluttertoast.showToast(msg: "User list already contains this UserId"); + return; + } + + users[widget.listPosition] = widget.user; + + List> jsonData = + users.map((dev) => dev.toJson()).toList(); + LocalStorage.saveData("UserList", json.encode(jsonData)); + eventBus.fire("update_list"); + Navigator.pop(context); + } +} diff --git a/gsf/lib/scale/page/user_list_page.dart b/gsf/lib/scale/page/user_list_page.dart new file mode 100644 index 0000000..e72f26f --- /dev/null +++ b/gsf/lib/scale/page/user_list_page.dart @@ -0,0 +1,183 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import '../../scale/utils/event_bus.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import '../../scale/utils/local_storage.dart'; + +import '../../scale/utils/NavigatorUtils.dart'; + +class UserListPage extends StatefulWidget { + @override + State createState() => _UserListPageState(); +} + +class _UserListPageState extends State { + var menuAddUser = "AddUser"; + var activeUserId = -1; + List listArray = []; + + @override + void initState() { + super.initState(); + _initList(); + eventBus.on().listen((event) { + if ("update_list" == event) { + if (mounted) { + setState(() { + _initList(); + }); + } + } + }); + } + + void _initList() { + var value = LocalStorage.getData("UserList"); + var idValue = LocalStorage.getData("activeUserId"); + debugPrint("Userlist V, $value"); + if (idValue != null) activeUserId = idValue; + + if (value != null) { + listArray = List.from( + json.decode(value).map( + (model) => ICUserInfo.fromJson(model), + ), + ); + } + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + debugPrint("Userlist, $listArray"); + return Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => [ + PopupMenuItem(value: menuAddUser, child: Text(menuAddUser)), + ], + onSelected: _menuSelectValue, + ) + ], + title: const Text("User List"), + ), + body: ListView.builder( + itemCount: listArray.length, + itemBuilder: (context, index) { + return UserItem(listArray[index], index, activeUserId); + }, + ), + ); + } + + void _menuSelectValue(value) { + if (value == menuAddUser) { + NavigatorUtils.goUserAddPage(context); + } + } +} + +class UserItem extends StatelessWidget { + final ICUserInfo? userInfo; + final int position; + final int activeUserId; + + const UserItem(this.userInfo, this.position, this.activeUserId, {Key? key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + NavigatorUtils.goUserEditPage(context, userInfo!, position); + }, + child: Container( + padding: + const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10), + child: Column( + children: [ + Row( + children: [ + Text( + "Index:${userInfo!.userIndex}", + style: TextStyle(fontSize: 16, color: _activeTextColor()), + ), + const SizedBox( + width: 10, + height: 0, + ), + Text( + "Age:${userInfo!.age}", + style: const TextStyle(fontSize: 14), + ), + const SizedBox(width: 10, height: -0), + Text( + "Sex:${_getSexString(userInfo!.sex)}", + style: const TextStyle(fontSize: 14), + ), + const SizedBox(width: 10, height: 0), + Text( + "Height:${userInfo!.height}", + style: const TextStyle(fontSize: 14), + ), + const SizedBox( + width: 10, + height: 0, + ), + Text( + "Imp:${userInfo!.lastImp}", + style: const TextStyle(fontSize: 14), + ) + ], + ), + const SizedBox( + width: 0, + height: 5, + ), + Row( + children: [ + Text( + "UserId:${userInfo!.userId}", + style: const TextStyle(fontSize: 14), + ), + const SizedBox(width: 10, height: 0), + Text( + "Weight:${userInfo!.age}", + style: const TextStyle(fontSize: 14), + ), + const SizedBox(width: 10, height: 0), + Text( + "PeopleType:${_getPeopleTypeString(userInfo!.peopleType)}", + style: const TextStyle(fontSize: 14), + ) + ], + ), + ], + ), + )); + } + + Color _activeTextColor() { + if (userInfo!.userId == activeUserId) { + return Colors.blue; + } else { + return Colors.black; + } + } + + String _getSexString(ICSexType sexType) { + activeUserId; + return ICSexType.ICSexTypeMale == sexType ? "Male" : "FeMale"; + } + + String _getPeopleTypeString(ICPeopleType type) { + return ICPeopleType.ICPeopleTypeSportman == type ? "Sport" : "Normal"; + } +} diff --git a/gsf/lib/scale/utils/NavigatorUtils.dart b/gsf/lib/scale/utils/NavigatorUtils.dart new file mode 100644 index 0000000..b07b9a3 --- /dev/null +++ b/gsf/lib/scale/utils/NavigatorUtils.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import '../model/device_type.dart'; +import '../page/device_scan_page.dart'; +import '../page/height_home_page.dart'; +import '../page/kitchen_scale_home_page.dart'; +import '../page/log_page.dart'; +import '../page/ota_page.dart'; +import '../page/rope_home_page.dart'; +import '../page/ruler_home_page.dart'; +import '../page/scale_home_page.dart'; +import '../page/user_add_page.dart'; +import '../page/user_edit_page.dart'; +import '../page/user_list_page.dart'; + +class NavigatorUtils { + static goScaleHomePage(BuildContext context) { + NavigatorRouter(context, const ScaleHomePage()); + } + + static goKitchenScalePage(BuildContext context) { + NavigatorRouter(context, KitchenScalePage()); + } + + static goRopePage(BuildContext context) { + NavigatorRouter(context, RopePage()); + } + + static goHeightPage(BuildContext context) { + NavigatorRouter(context, HeightPage()); + } + + static goRulerPage(BuildContext context) { + NavigatorRouter(context, RulerPage()); + } + + static goScaleScanPage(BuildContext context, int devType) { + NavigatorRouter(context, DeviceScanPage(devType: DeviceType.scale)); + } + + static goUserListPage(BuildContext context) { + NavigatorRouter(context, UserListPage()); + } + + static goUserAddPage(BuildContext context) { + NavigatorRouter(context, UserAddPage()); + } + + static goUserEditPage( + BuildContext context, ICUserInfo userInfo, int position) { + NavigatorRouter(context, UserEditPage(userInfo, position)); + } + + static goLogPage(BuildContext context) { + NavigatorRouter(context, LogPage()); + } + + static goOTAPage(BuildContext context, String mac) { + NavigatorRouter(context, OTAPage(mac)); + } + + static NavigatorRouter(BuildContext context, Widget widget) { + return Navigator.push( + context, + MaterialPageRoute( + builder: (context) => pageContainer(widget, context))); + } + + ///Page页面的容器,做一次通用自定义 + static Widget pageContainer(widget, BuildContext context) { + return MediaQuery( + + ///不受系统字体缩放影响 + data: MediaQuery.of(context).copyWith(textScaleFactor: 1), + child: widget); + } +} diff --git a/gsf/lib/scale/utils/data_parse_util.dart b/gsf/lib/scale/utils/data_parse_util.dart new file mode 100644 index 0000000..7d5ee94 --- /dev/null +++ b/gsf/lib/scale/utils/data_parse_util.dart @@ -0,0 +1,27 @@ +import '../../scale/utils/debug_logger.dart'; + +class DataPareUtil { + static int stringToInt(String? data) { + if (data == null) return 0; + var result = 0; + try { + result = int.parse(data); + } catch (e) { + DebugLogger.instance.logText("stringToInt $e"); + } + + return result; + } + + static double stringToDouble(String? data) { + if (data == null) return 0.0; + var result = 0.0; + try { + result = double.parse(data); + } catch (e) { + DebugLogger.instance.logText("stringToDouble $e"); + } + + return result; + } +} diff --git a/gsf/lib/scale/utils/debug_logger.dart b/gsf/lib/scale/utils/debug_logger.dart new file mode 100644 index 0000000..798e5a0 --- /dev/null +++ b/gsf/lib/scale/utils/debug_logger.dart @@ -0,0 +1,16 @@ +import 'dart:developer'; + +import '../../scale/utils/log_util.dart'; + +class DebugLogger { + static DebugLogger? _instance; + + DebugLogger._(); + + static DebugLogger get instance => _instance ??= DebugLogger._(); + + void logText(String text) { + log(text); + LogUtil.instance.writeLog(text); + } +} diff --git a/gsf/lib/scale/utils/event_bus.dart b/gsf/lib/scale/utils/event_bus.dart new file mode 100644 index 0000000..3c0b923 --- /dev/null +++ b/gsf/lib/scale/utils/event_bus.dart @@ -0,0 +1,8 @@ + +import 'package:event_bus/event_bus.dart'; + +EventBus eventBus = EventBus(); +class EventFn { + String obj; + EventFn(this.obj); +} \ No newline at end of file diff --git a/gsf/lib/scale/utils/local_storage.dart b/gsf/lib/scale/utils/local_storage.dart new file mode 100644 index 0000000..fb1f87d --- /dev/null +++ b/gsf/lib/scale/utils/local_storage.dart @@ -0,0 +1,54 @@ + +import 'package:shared_preferences/shared_preferences.dart'; + +///SharedPreferences 本地存储 +class LocalStorage { + + static late final SharedPreferences prefs; + + static bool _init = false; + static Future init() async { + if (_init) return; + prefs = await SharedPreferences.getInstance(); + _init = true; + return prefs; + } + + static saveData(String key, T value) { + switch (T) { + case String: + prefs.setString(key, value as String); + break; + case int: + prefs.setInt(key, value as int); + break; + case bool: + prefs.setBool(key, value as bool); + break; + case double: + prefs.setDouble(key, value as double); + break; + } + } + + + static T? getData(String key) { + T? res; + switch (T) { + case String: + res = prefs.getString(key) as T?; + break; + case int: + res = prefs.getInt(key) as T?; + break; + case bool: + res = prefs.getBool(key) as T?; + break; + case double: + res = prefs.getDouble(key) as T?; + break; + } + return res; + } + +} diff --git a/gsf/lib/scale/utils/log_util.dart b/gsf/lib/scale/utils/log_util.dart new file mode 100644 index 0000000..9bd69bf --- /dev/null +++ b/gsf/lib/scale/utils/log_util.dart @@ -0,0 +1,63 @@ +import 'dart:developer'; +import 'dart:io'; + +import 'package:intl/intl.dart'; +import 'package:path_provider/path_provider.dart'; + + + + + +class LogUtil { + static LogUtil? _instance; + + LogUtil._(); + + static LogUtil get instance => _instance ??= LogUtil._(); + + + + Future writeLog(String str) async { + log("写入日记:$str"); + var date = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now()); + var text = "\n${"[$date][LogUtil"}]: $str"; + final Directory directory = await getApplicationDocumentsDirectory(); + final File file = File('${directory.path}/data_log.txt'); + await file.writeAsString(text, mode: FileMode.append); + } + + Future clearLog() async { + final Directory directory = await getApplicationDocumentsDirectory(); + final File file = File('${directory.path}/data_log.txt'); + await file.writeAsString(""); + } + + + + + Future readLog() async { + String text=""; + try { + final Directory directory = await getApplicationDocumentsDirectory(); + final File file = File('${directory.path}/data_log.txt'); + + await file.readAsLines().then( + (List lines) { + for (var line in lines) { + if(text.isNotEmpty){ + text="$text\n\n$line"; + }else { + text="$text$line"; + } + + } + }, + ); + //text = await file.readAsString(); + } catch (e) { + log("Couldn't read file"); + } + log("读取日记:$text"); + return text; + } +} diff --git a/gsf/lib/scale/utils/random_util.dart b/gsf/lib/scale/utils/random_util.dart new file mode 100644 index 0000000..1ce3d99 --- /dev/null +++ b/gsf/lib/scale/utils/random_util.dart @@ -0,0 +1,26 @@ +import 'dart:math'; + +class ICRandomUtil { + + + static int getRandomUserId(List ids,int id) { + while (ids.contains(id)) { + getRandomUserId(ids,Random().nextInt(1000)); + } + return id; + } + + static int getRandomUserIndex(List ids) { + if (!ids.contains(1)) { + return 1; + } + if (!ids.contains(2)) { + return 2; + } + + if (!ids.contains(3)) { + return 3; + } + return 4; + } +} \ No newline at end of file diff --git a/gsf/lib/view_model/BioscaleOverview.dart b/gsf/lib/view_model/BioscaleOverview.dart new file mode 100644 index 0000000..08d12b6 --- /dev/null +++ b/gsf/lib/view_model/BioscaleOverview.dart @@ -0,0 +1,33 @@ +import 'dart:async'; + +import 'package:get/get.dart'; +import 'package:gsp_app/api/StreamEnum.dart'; +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/modals/BioscalOverviewForallDates.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../api/base_manager.dart'; + +BioscaleOverviewForallDates? allDatesData; + +class BioScaleOverview extends GetxController { + // Future> dataForallDAtes() async { + // final response = await NetworkApi().getApi( + // Endpoints.userScaleDataWithDate + '?created_at=', + // ); + // allDatesData = BioscaleOverviewForallDates.fromJson(response.data); + + // print( + // "response from dataForallDates ${allDatesData?.authorisation?.userData?.first.muscleRate}"); + // return response; + // } + Future> dataForallDAtes(updata) async { + final response = await NetworkApi().postApi( + data: updata, + url: Endpoints.userScaleDataFilter, + ); + allDatesData = BioscaleOverviewForallDates.fromJson(response.data); + + return response; + } +} diff --git a/gsf/lib/view_model/GetMoodometerValue.dart b/gsf/lib/view_model/GetMoodometerValue.dart new file mode 100644 index 0000000..227d9cc --- /dev/null +++ b/gsf/lib/view_model/GetMoodometerValue.dart @@ -0,0 +1,29 @@ +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/components/mood_meter.dart'; + +import '../api/base_manager.dart'; + +class GetMoodometerValue { + Future> getmoodValue() async { + final response = await NetworkApi().getApi(Endpoints.getMoodOMeterValue); + print("response of mood value $response"); + + if (response.status == ResponseStatus.SUCCESS) { + if (response.data['success']) { + if (response.data['result'] == 'Very Happy') { + activeIndexMoodOMeter = 0; + } else if (response.data['result'] == 'Happy') { + activeIndexMoodOMeter = 1; + } else if (response.data['result'] == 'Ok') { + activeIndexMoodOMeter = 2; + } else if (response.data['result'] == 'Whatever') { + activeIndexMoodOMeter = 3; + } else if (response.data['result'] == 'Sad') { + activeIndexMoodOMeter = 4; + } + } + } + return response; + } +} diff --git a/gsf/lib/view_model/QuizApis.dart b/gsf/lib/view_model/QuizApis.dart new file mode 100644 index 0000000..470e7c2 --- /dev/null +++ b/gsf/lib/view_model/QuizApis.dart @@ -0,0 +1,46 @@ +import 'package:get/get.dart'; +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/modals/QuizModel.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/pages/quiz/quiz_home.dart'; + +import '../api/base_manager.dart'; + +QuizeModel? quizData; + +class QuizeApis { + Future> storePoints(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.storePoints, data: updata); + if (response.status == ResponseStatus.SUCCESS) { + showQuizbool = false; + } + print("response from store points $response"); + + return response; + } + + Future> getQuiz() async { + final response = await NetworkApi().getApi(Endpoints.getquiz); + quizData = QuizeModel.fromJson(response.data); + return response; + } + + Future> showQuiz() async { + final response = await NetworkApi().getApi(Endpoints.showQuiz); + List? quizResultlist = response.data['result']; + if (quizResultlist != null && quizResultlist.isEmpty) { + print("no data present"); + showQuizbool = true; + } else { + String isactive = response.data['result'].first['is_active']; + if (isactive == "1") { + showQuizbool = false; + } else { + showQuizbool = true; + } + } + + return response; + } +} diff --git a/gsf/lib/view_model/ResetPassword.dart b/gsf/lib/view_model/ResetPassword.dart new file mode 100644 index 0000000..f6437ad --- /dev/null +++ b/gsf/lib/view_model/ResetPassword.dart @@ -0,0 +1,30 @@ +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/repository/services/cj/generate_otp_service.dart'; + +import '../api/base_manager.dart'; + +class ResetPassword { + Future> resetpasswordapi(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.resetPassword, data: updata); + + return response; + } + + Future> generateOTP(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.generateOTPV2, data: updata); + + if (response.status == ResponseStatus.SUCCESS) { + if (response.data['status'] == 200) { + return response; + } else if (response.data['status'] == 404) { + return ResponseData( + response.data['message'], ResponseStatus.PRIVATE); + } + } + + return response; + } +} diff --git a/gsf/lib/view_model/StepcountController.dart b/gsf/lib/view_model/StepcountController.dart new file mode 100644 index 0000000..2877caf --- /dev/null +++ b/gsf/lib/view_model/StepcountController.dart @@ -0,0 +1,5 @@ +import 'package:get/get.dart'; + +class StepCountController extends GetxController { + RxInt appStepCountGlobal = 0.obs; +} diff --git a/gsf/lib/view_model/Stepcounts.dart b/gsf/lib/view_model/Stepcounts.dart new file mode 100644 index 0000000..d5f9093 --- /dev/null +++ b/gsf/lib/view_model/Stepcounts.dart @@ -0,0 +1,13 @@ +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../api/base_manager.dart'; + +class StepCounts { + Future> storeSteps(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.storeSteps, data: updata); + print("response from step count $response"); + return response; + } +} diff --git a/gsf/lib/view_model/VersionControl.dart b/gsf/lib/view_model/VersionControl.dart new file mode 100644 index 0000000..fcfb348 --- /dev/null +++ b/gsf/lib/view_model/VersionControl.dart @@ -0,0 +1,23 @@ +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/modals/VersionControlModels.dart'; +import 'package:gsp_app/repository/endpoints.dart'; + +import '../api/base_manager.dart'; + +VersionControlModel? version; + +class VersionControl { + Future> storeCurrentVersion(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.storeVersion, data: updata); + print("response from step count $response"); + return response; + } + + Future> getCurrentVersion() async { + final response = await NetworkApi().getApi(Endpoints.getNewVersion); + version = VersionControlModel.fromJson(response.data); + if (response.status == ResponseStatus.SUCCESS) {} + return response; + } +} diff --git a/gsf/lib/view_model/app_data_controller.dart b/gsf/lib/view_model/app_data_controller.dart new file mode 100644 index 0000000..58f7016 --- /dev/null +++ b/gsf/lib/view_model/app_data_controller.dart @@ -0,0 +1,46 @@ +import 'package:get/get.dart'; + +import '../modals/user_model.dart'; +import '../modals/view_frnd_profile_model.dart'; + +class AppDataController extends GetConnect { + //user + RxInt id = 0.obs; + RxString name = ''.obs; + RxString phoneNo = ''.obs; + RxString email = ''.obs; + RxString profilePicUrl = ''.obs; + RxString bio = ''.obs; + RxString gender = ''.obs; + RxInt age = 0.obs; + RxString address = ''.obs; + RxString city = ''.obs; + RxDouble height = 0.0.obs; + RxDouble weight = 0.0.obs; + + RxInt selfPosition = 0.obs; + + //manage banner + RxString bannerPath = ''.obs; + RxInt bannerPosition = 0.obs; + + //view friends profile + RxList viewFriendsProfileModels = + [].obs; + + void fromUserModel(UserModel userModel) { + id.value = userModel.id; + name.value = userModel.name; + phoneNo.value = userModel.phoneNo; + email.value = userModel.email; + + profilePicUrl.value = userModel.profilePicUrl ?? ''; + bio.value = userModel.bio ?? ''; + gender.value = userModel.gender ?? ''; + age.value = userModel.age ?? 0; + address.value = userModel.address ?? ''; + city.value = userModel.city ?? ''; + height.value = userModel.height ?? 0.0; + // weight.value = userModel.weight ?? 0.0; + } +} diff --git a/gsf/lib/view_model/app_tour_controller.dart b/gsf/lib/view_model/app_tour_controller.dart new file mode 100644 index 0000000..bcb861b --- /dev/null +++ b/gsf/lib/view_model/app_tour_controller.dart @@ -0,0 +1,306 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; + +class AppTourController extends GetxController { + final navDrawer = GlobalKey(); + final notifications = GlobalKey(); + // final settings = GlobalKey(); + final home = GlobalKey(); + final Sessions = GlobalKey(); + final bioMaker = GlobalKey(); + final myRanking = GlobalKey(); + final myProfile = GlobalKey(); + + void startAppTour(BuildContext context, VoidCallback laterAction) { + TutorialCoachMark( + colorShadow: const Color.fromARGB(255, 20, 31, 0), + opacityShadow: 0.975, + textStyleSkip: const TextStyle( + fontWeight: FontWeight.w700, + fontFamily: "Poppins", + color: ColorConstants.kPrimaryColor, + fontSize: 16, + ), + targets: [ + //nav drawer + TargetFocus( + identify: "navigationDrawer", + keyTarget: navDrawer, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.bottom, + builder: (context, controller) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + "Click here to open a drawer and explore option like,", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + SizedBox(height: 18), + Text( + "1. View/Edit Profile", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + SizedBox(height: 8), + // Text( + // "2. Visit GSF Instagram Page", + // style: TextStyle( + // color: Colors.white, + // fontSize: 16, + // ), + // ), + // SizedBox(height: 8), + Text( + "2. About GSF", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + SizedBox(height: 8), + Text( + "3. Watch Bites", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + SizedBox(height: 8), + Text( + "4. View Frequently Asked Questions", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + SizedBox(height: 8), + Text( + "5. Contact Us", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + // SizedBox(height: 8), + // Text( + // "7. Switch Between Light / Dark Theme", + // style: TextStyle( + // color: Colors.white, + // fontSize: 16, + // ), + // ), + SizedBox(height: 8), + Text( + "6. Logout from the Application", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + ], + ); + }, + ), + ], + ), + + //notifications + TargetFocus( + identify: "notifications", + keyTarget: notifications, + alignSkip: Alignment.topLeft, + contents: [ + TargetContent( + align: ContentAlign.bottom, + builder: (context, controller) { + return const Align( + alignment: Alignment.topRight, + child: Text( + "Click here to view notification", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + + //settings + // TargetFocus( + // identify: "settings", + // keyTarget: settings, + // alignSkip: Alignment.topLeft, + // contents: [ + // TargetContent( + // align: ContentAlign.bottom, + // builder: (context, controller) { + // return const Align( + // alignment: Alignment.topRight, + // child: Text( + // "Click here to change settings", + // style: TextStyle( + // color: Colors.white, + // fontWeight: FontWeight.w600, + // fontFamily: "SFPRO", + // fontSize: 18, + // ), + // ), + // ); + // }, + // ), + // ], + // ), + + //home + TargetFocus( + identify: "home", + keyTarget: home, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.top, + builder: (context, controller) { + return const Align( + alignment: Alignment.centerLeft, + child: Text( + "Click here to visit home page", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + + //live session + TargetFocus( + identify: "Sessions", + keyTarget: Sessions, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.top, + builder: (context, controller) { + return const Align( + alignment: Alignment.centerLeft, + child: Text( + "Click here to watch live Sessions", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + + //Bio maker + TargetFocus( + identify: "bioMaker", + keyTarget: bioMaker, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.top, + builder: (context, controller) { + return const Align( + alignment: Alignment.centerLeft, + child: Text( + "Click here to connect your scale", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + + //My ranking + TargetFocus( + identify: "myRanking", + keyTarget: myRanking, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.top, + builder: (context, controller) { + return const Align( + alignment: Alignment.centerLeft, + child: Text( + "Click here to view leaderboard", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + + //profile + TargetFocus( + identify: "myProfile", + keyTarget: myProfile, + alignSkip: Alignment.topRight, + contents: [ + TargetContent( + align: ContentAlign.top, + builder: (context, controller) { + return const Align( + alignment: Alignment.centerLeft, + child: Text( + "Click here for visiting bites section", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w600, + fontFamily: "SFPRO", + fontSize: 18, + ), + ), + ); + }, + ), + ], + ), + ], + onSkip: laterAction, + onFinish: laterAction, + ).show(context: context); + } +} diff --git a/gsf/lib/view_model/bottom_navigation_controller.dart b/gsf/lib/view_model/bottom_navigation_controller.dart new file mode 100644 index 0000000..4d77b9f --- /dev/null +++ b/gsf/lib/view_model/bottom_navigation_controller.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class NavigationCrontroller extends GetxController { + final a = GlobalKey>(); + final b = GlobalKey>(); + final c = GlobalKey>(); + final d = GlobalKey>(); + final e = GlobalKey>(); + final f = GlobalKey>(); + final g = GlobalKey>(); + final h = GlobalKey>(); + final i = GlobalKey>(); + final j = GlobalKey>(); +} diff --git a/gsf/lib/view_model/common_functions.dart b/gsf/lib/view_model/common_functions.dart new file mode 100644 index 0000000..bbe828b --- /dev/null +++ b/gsf/lib/view_model/common_functions.dart @@ -0,0 +1,4 @@ +String correctImgUrl(String raw) { + var x = raw.split("/").last; + return "https://thegsf.co/public/uploads/profile_images/$x"; +} diff --git a/gsf/lib/view_model/connectivity.dart b/gsf/lib/view_model/connectivity.dart new file mode 100644 index 0000000..26d0b41 --- /dev/null +++ b/gsf/lib/view_model/connectivity.dart @@ -0,0 +1,71 @@ +import 'dart:async'; + +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class ConnectivityController extends GetxController { + var connectionType = "".obs; + final Connectivity connectivity = Connectivity(); + late StreamSubscription streamSubscription; + RxBool isConnected = true.obs; + @override + void onInit() { + super.onInit(); + getConnctionStatus(); + streamSubscription = + connectivity.onConnectivityChanged.listen(getConnectionType); + } + + void getConnctionStatus() async { + ConnectivityResult connectionResult; + try { + connectionResult = await connectivity.checkConnectivity(); + // print(connectionResult); + getConnectionType(connectionResult); + } catch (e) { + Get.snackbar("excepetion", "Error during connectivity cheking"); + } + } + + void getConnectionType(connectionResult) { + if (connectionResult == ConnectivityResult.wifi) { + connectionType.value = "Wifi"; + isConnected.value = true; + // print('wifi'); + // Get.snackbar('Wifi c ', 'Please check you\'r Inernt connection'); + Get.snackbar( + 'Internet Connection ', + 'Internet Connected', + backgroundColor: Colors.white, + snackPosition: SnackPosition.BOTTOM, + ); + } else if (connectionResult == ConnectivityResult.mobile) { + connectionType.value = "Mobile Internet"; + isConnected.value = true; + // print('Mobile Internet'); + // Get.snackbar('No Internt ', 'Please check you\'r Inernt connection'); + Get.snackbar( + 'Internet Connection', + 'Internet Connected', + backgroundColor: Colors.white, + snackPosition: SnackPosition.BOTTOM, + ); + } else { + connectionType.value = "No Internet"; + isConnected.value = false; + Get.snackbar( + 'No Internet', + 'Please check you\'r Internet connection', + backgroundColor: Colors.white, + snackPosition: SnackPosition.BOTTOM, + ); + } + } +@override + void onClose() { + streamSubscription.cancel(); + super.onClose(); + } + +} diff --git a/gsf/lib/view_model/diet_chart_controller.dart b/gsf/lib/view_model/diet_chart_controller.dart new file mode 100644 index 0000000..6c445d6 --- /dev/null +++ b/gsf/lib/view_model/diet_chart_controller.dart @@ -0,0 +1,5 @@ +import 'package:get/get.dart'; + +class DietChartController extends GetxController { + RxString vegNveg = 'Veg'.obs; +} diff --git a/gsf/lib/view_model/global_controller.dart b/gsf/lib/view_model/global_controller.dart new file mode 100644 index 0000000..baf919e --- /dev/null +++ b/gsf/lib/view_model/global_controller.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +import '../views/theme.dart'; + +class GlobalController extends GetxController{ + + // bool box = GetStorage().read("isDarkMode"); + // final key = 'isDarkMode'; + // bool loadThemeFromBox() => GetStorage().read('isDarkMode') ?? true; + + + + // saveThemeToBox(bool isDarkMode) => box.write(key, isDarkMode); + + // RxBool darkMode = box.read(key) ?? true.obs; + // bool darkMode = loadThemeFromBox(); + + final box = GetStorage(); + final key = 'isDarkMode'; + + saveThemeToBox(bool isDarkMode) => box.write(key, isDarkMode); + + bool loadThemeFromBox() => box.read(key) ?? true; + ThemeMode get theme => loadThemeFromBox() ? ThemeMode.dark : ThemeMode.light; + void switchTheme() { + Get.changeThemeMode(loadThemeFromBox() ? ThemeMode.light : ThemeMode.dark); + saveThemeToBox(!loadThemeFromBox()); + } + + RxBool darkMode = RxBool(ThemseServices().loadThemeFromBox()); + +} \ No newline at end of file diff --git a/gsf/lib/view_model/home_controller.dart b/gsf/lib/view_model/home_controller.dart new file mode 100644 index 0000000..073c281 --- /dev/null +++ b/gsf/lib/view_model/home_controller.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +final box = GetStorage(); + +class TabsController extends GetxController { + // bool loggedIn = false; + bool isLoggedIn = box.read('isLoggedIn') ?? false; + var scaffoldKey = GlobalKey(); + void openDrawer() { + scaffoldKey.currentState?.openDrawer(); + } +} diff --git a/gsf/lib/view_model/home_page_controller.dart b/gsf/lib/view_model/home_page_controller.dart new file mode 100644 index 0000000..9bc840f --- /dev/null +++ b/gsf/lib/view_model/home_page_controller.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +class HomePageController extends GetxController { + RxInt bottomNavIndex = 0.obs; + void updateBottomNavIndex(int bottomNavIndex) => + this.bottomNavIndex.value = bottomNavIndex; + + //live session + static int SessionsActiveTabIndex = 0; +} diff --git a/gsf/lib/view_model/local_storage.dart b/gsf/lib/view_model/local_storage.dart new file mode 100644 index 0000000..444d9b8 --- /dev/null +++ b/gsf/lib/view_model/local_storage.dart @@ -0,0 +1,6 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +final box = GetStorage(); + +class LocalStorageController extends GetxController {} diff --git a/gsf/lib/view_model/my_ranking_controller.dart b/gsf/lib/view_model/my_ranking_controller.dart new file mode 100644 index 0000000..76fa488 --- /dev/null +++ b/gsf/lib/view_model/my_ranking_controller.dart @@ -0,0 +1,12 @@ + +import 'package:get/get.dart'; + +class MyRankingController extends GetxController { + RxString gender = 'All'.obs; + RxString groupLevel = 'Swole'.obs; + + RxString defaultGenderStore = ''.obs; + RxString defaultGroupLevelStore = ''.obs; + RxString defaultGroupLevelStoreHome = ''.obs; + +} \ No newline at end of file diff --git a/gsf/lib/view_model/profile_controller.dart b/gsf/lib/view_model/profile_controller.dart new file mode 100644 index 0000000..77296fb --- /dev/null +++ b/gsf/lib/view_model/profile_controller.dart @@ -0,0 +1,5 @@ +import 'dart:async'; + +class ProfileController { + static StreamController streamController = StreamController(); +} diff --git a/gsf/lib/view_model/profile_slider_controller.dart b/gsf/lib/view_model/profile_slider_controller.dart new file mode 100644 index 0000000..1906e7a --- /dev/null +++ b/gsf/lib/view_model/profile_slider_controller.dart @@ -0,0 +1,47 @@ +// ignore_for_file: prefer_typing_uninitialized_variables + +import 'package:carousel_slider/carousel_controller.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/bioMaker/overview.dart'; + +import '../views/pages/profile/profile_exports.dart'; + +class ProfileSliderController extends GetxController { + final CarouselController sliderController = CarouselController(); + + List overviewDataList = []; + var mrVAlue, bFat, skeletalMuscle, protein, bmr, water, age; + setValues() { + overviewDataList = overviewDataReturnglobal; + // print('overviewDataList global value ${overviewDataList}'); + mrVAlue = overviewDataList[0]['intValue']; + bFat = overviewDataList[1]['intValue']; + skeletalMuscle = overviewDataList[2]['intValue']; + protein = overviewDataList[3]['intValue']; + // bmr = overviewDataList[4]['intValue']; + water = overviewDataList[4]['intValue']; + age = overviewDataList[5]['intValue']; + setvaluesofList(); + } + + setvaluesofList() { + List list = [ + MuscleRate(mrValueDateWise: mrVAlue ?? '0.0'), + BodyFat(bFat: bFat ?? '0'), + BoneMass(skeletalMuscleApi: skeletalMuscle ?? '0'), + ProteinRate(proteinApi: protein ?? '0'), + // BasalMetaBolism(apiBmr: bmr ?? '0'), + Moisture(water: water ?? '0'), + BodyAge(bodyAgeApi: age ?? '0') + // const IdealWeight(), + // const FatMass(), + // const FatRate(), + // const LeanBodyMass(), + // const FatIndex(), + // const BodyType(), + ]; + + return list; + } +} diff --git a/gsf/lib/view_model/select_profile_picture_controller.dart b/gsf/lib/view_model/select_profile_picture_controller.dart new file mode 100644 index 0000000..c24ec32 --- /dev/null +++ b/gsf/lib/view_model/select_profile_picture_controller.dart @@ -0,0 +1,51 @@ +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:image_cropper/image_cropper.dart'; +import 'package:flutter/material.dart'; + +class SelectProfilePictureController extends GetxController { + RxString profilePicPath = "".obs; + // RxBool showSelectedProfilePic = false.obs; + + void selectImg(ImageSource imgSource) async { + final ImagePicker picker = ImagePicker(); + final XFile? pickedImg = await picker.pickImage(source: imgSource); + if (pickedImg != null) { + final CroppedFile? croppedImg = await ImageCropper().cropImage( + sourcePath: pickedImg.path, + aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1), + compressFormat: ImageCompressFormat.jpg, + maxHeight: 512, + maxWidth: 512, + compressQuality: 100, + cropStyle: CropStyle.circle, + aspectRatioPresets: [ + CropAspectRatioPreset.square, + // CropAspectRatioPreset.ratio3x2, + // CropAspectRatioPreset.original, + // CropAspectRatioPreset.ratio4x3, + // CropAspectRatioPreset.ratio16x9 + ], + uiSettings: [ + AndroidUiSettings( + toolbarTitle: "Crop Image", + toolbarColor: Get.theme.appBarTheme.backgroundColor, + toolbarWidgetColor: ColorConstants.kWhite, + backgroundColor: Colors.black, + activeControlsWidgetColor: Colors.red, + // initAspectRatio: CropAspectRatioPreset.original, + cropFrameColor: Colors.white, + lockAspectRatio: false, + ), + IOSUiSettings( + title: 'Crop Image', + ), + ]); + if (croppedImg != null) { + profilePicPath.value = croppedImg.path; + Get.back(); + } + } + } +} diff --git a/gsf/lib/view_model/utc_time_contoller.dart b/gsf/lib/view_model/utc_time_contoller.dart new file mode 100644 index 0000000..beb515a --- /dev/null +++ b/gsf/lib/view_model/utc_time_contoller.dart @@ -0,0 +1,50 @@ +import 'package:intl/intl.dart'; + + +String convertUtcToLocalTime(String utcTime) { + // Define a UTC time format + DateFormat utcFormatter = DateFormat("HH:mm"); + + // Parse the UTC time string + DateTime utcDateTime = utcFormatter.parseUTC(utcTime); + + + + // Get the local timezone + + // Create a new DateTime object in the local timezone + DateTime localDateTime = utcDateTime.toLocal(); + + + + // Format the local time as a string with AM/PM indicator + DateFormat localFormatter = DateFormat("hh:mm a"); + String localTime = localFormatter.format(localDateTime); + + + return localTime; +} + + +convertTimeInUtcWithouAmAndPm(utcTime){ + + // Define a UTC time format + DateFormat utcFormatter = DateFormat("HH:mm"); + + // Parse the UTC time string + DateTime utcDateTime = utcFormatter.parseUTC(utcTime); + + + // Get the local timezone + + // Create a new DateTime object in the local timezone + DateTime localDateTime = utcDateTime.toLocal(); + + + // Format the local time as a string with AM/PM indicator + DateFormat localFormatter = DateFormat("HH:MM"); + String localTime = localFormatter.format(localDateTime); + // print('utcFormatter ${localTime}'); + + return localTime; +} \ No newline at end of file diff --git a/gsf/lib/views/components/appbar.dart b/gsf/lib/views/components/appbar.dart new file mode 100644 index 0000000..cb9f877 --- /dev/null +++ b/gsf/lib/views/components/appbar.dart @@ -0,0 +1,102 @@ +// ignore_for_file: must_be_immutable + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/home_page_controller.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; + +import '../short_video_player/svp_lib/video_page.dart'; +import '../theme.dart'; + +class CustomAppBars extends StatelessWidget { + CustomAppBars({ + Key? key, + required this.titleHead, + this.rightAction, + this.showLeading = true, + this.backgroundColor, + this.editProfileFromUserProfile = false, + this.fromHome, + }) : super(key: key); + + String titleHead; + Widget? rightAction; + bool showLeading; + Color? backgroundColor; + bool editProfileFromUserProfile; + bool? fromHome; + HomePageController homePageController = Get.put(HomePageController()); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return AppBar( + automaticallyImplyLeading: false, + backgroundColor: backgroundColor, + leadingWidth: 70, + leading: showLeading + ? Padding( + padding: const EdgeInsets.only( + top: 10, left: 18, right: 15, bottom: 10), + child: InkWell( + splashColor: const Color(0xff313030).withOpacity(0.5), + borderRadius: BorderRadius.circular(7), + onTap: () { + VideoPage.currentController?.pause(); + VideoPage.currentController?.dispose(); + if (editProfileFromUserProfile) { + Get.offAll(const HomePage()); + } else if (fromHome ?? false) { + homePageController.bottomNavIndex.value = 0; + } else { + Get.back(); + } + }, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.1) + : const Color(0xff313030), + borderRadius: BorderRadius.circular(7), + ), + child: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Icon( + Icons.arrow_back_ios, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + size: 20, + ), + ), + ), + ), + ) + : null, + // leadingWidth: 30, + titleSpacing: 0, + centerTitle: true, + // backgroundColor: ColorConstants.kBlack, + elevation: (brightness == Brightness.light) ? 1 : 0, + title: Text( + titleHead, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + actions: [ + if (rightAction != null) + Padding( + padding: const EdgeInsets.only(right: 15, top: 2), + child: rightAction, + ), + ], + ); + } +} diff --git a/gsf/lib/views/components/bottom_navigation.dart b/gsf/lib/views/components/bottom_navigation.dart new file mode 100644 index 0000000..205d4dd --- /dev/null +++ b/gsf/lib/views/components/bottom_navigation.dart @@ -0,0 +1,247 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/bottom_navigation_controller.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; + +import '../../view_model/app_tour_controller.dart'; +import '../../view_model/home_controller.dart'; +import '../../view_model/home_page_controller.dart'; +import '../theme.dart'; + +class BottomNavigation extends StatefulWidget { + const BottomNavigation({ + Key? key, + }) : super(key: key); + @override + State createState() => _BottomNavigationState(); +} + +class _BottomNavigationState extends State { + int _selectedIndex = 0; + HomePageController homePageController = Get.put(HomePageController()); + final TabsController controller = TabsController(); + final NavigationCrontroller navController = Get.find(); + + void _onItemTapped(int index) { + HomePageController.SessionsActiveTabIndex = 0; + homePageController.updateBottomNavIndex(index); + } + + @override + void initState() { + super.initState(); + _selectedIndex = homePageController.bottomNavIndex.value; + } + + void ontaps() { + if (controller.isLoggedIn) { + _selectedIndex; + } else { + Get.to(() => const SignIn()); + } + } + + AppTourController appTourController = Get.find(); + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + double iconSize = 24; + return + // Theme( + // data: Get.theme.copyWith( + // canvasColor: const Color(0xff1C1B1B), + // ), + // child: + Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.6), + blurRadius: 10, + spreadRadius: 2, + // offset: + ) + ], + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + ), + ), + child: Obx( + () => BottomNavigationBar( + unselectedFontSize: 10, + selectedFontSize: 10, + unselectedItemColor: !globalContoller.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : ColorConstants.kWhite, + items: [ + BottomNavigationBarItem( + activeIcon: + // Showcase( + // key: navController.d, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + ActiveIcon( + key: appTourController.home, + iconPath: + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'home_black' : 'home'}.svg', + selectedIndex: _selectedIndex, + ), + // ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'home_black' : 'home'}.svg', + width: iconSize, + height: iconSize, + ), + ), + label: 'Home', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'live_black' : 'live'}.svg', + selectedIndex: _selectedIndex, + ), + icon: + // Showcase( + // key: navController.e, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + Padding( + key: appTourController.Sessions, + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'live_black' : 'live'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // ), + label: 'Workout', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + key: appTourController.bioMaker, + iconPath: + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'weight_scale_black' : 'weight_scale'}.svg', + selectedIndex: _selectedIndex, + ), + icon: + // Showcase( + // key: navController.f, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + Padding( + key: appTourController.bioMaker, + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'weight_scale_black' : 'weight_scale'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // ), + label: 'Bioscale', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + key: appTourController.myRanking, + iconPath: + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'ranking_black' : 'ranking'}.svg', + selectedIndex: _selectedIndex, + ), + icon: + // Showcase( + // key: navController.g, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + Padding( + key: appTourController.myRanking, + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'ranking_black' : 'ranking'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // ), + label: 'Leaderboard', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + key: appTourController.myProfile, + iconPath: + 'assets/image/sidebarIcons/${!globalContoller.darkMode.value ? 'video_black' : 'video'}.svg', + selectedIndex: _selectedIndex, + ), + icon: + // Showcase( + // key: navController.h, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + Padding( + key: appTourController.myProfile, + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/sidebarIcons/${!globalContoller.darkMode.value ? 'video_black' : 'video'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // ), + label: 'Bites', + ), + ], + type: BottomNavigationBarType.fixed, + currentIndex: _selectedIndex, + selectedItemColor: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + iconSize: 40, + onTap: _onItemTapped, + elevation: 0, + ), + ), + ); + // ); + } +} + +class ActiveIcon extends StatelessWidget { + const ActiveIcon({ + required this.iconPath, + required this.selectedIndex, + Key? key, + }) : super(key: key); + + final String iconPath; + final int selectedIndex; + + @override + Widget build(BuildContext context) { + return Container( + width: 28, + height: 28, + padding: const EdgeInsets.all(5), + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: ColorConstants.kPrimaryColor, + ), + child: SvgPicture.asset( + iconPath, + color: Colors.black, + ), + ); + } +} diff --git a/gsf/lib/views/components/btn.dart b/gsf/lib/views/components/btn.dart new file mode 100644 index 0000000..5fee48b --- /dev/null +++ b/gsf/lib/views/components/btn.dart @@ -0,0 +1,140 @@ +import 'package:flutter/material.dart'; + +import '../theme.dart'; + +// class FullWdtBtn extends StatelessWidget { +// const FullWdtBtn({ +// Key? key, +// required this.btnText, +// required this.onTap, +// this.styleElement, +// }) : super(key: key); +// final String btnText; +// // final IconData icon; +// final VoidCallback onTap; +// final TextStyle? styleElement; +// @override +// Widget build(BuildContext context) { +// final screenSize = MediaQuery.of(context).size; +// return InkWell( +// onTap: onTap, +// child: Container( +// width: screenSize.width * 1, +// height: 50, +// decoration: BoxDecoration( +// color: ColorConstants.kPrimaryColor, +// borderRadius: BorderRadius.circular(30), +// ), +// child: Center( +// child: Text( +// btnText, +// style: styleElement ?? +// const TextStyle( +// fontSize: 16, +// color: Color(0xff000000), +// fontWeight: FontWeight.w500, +// fontFamily: 'Poppins', +// ), +// ), +// ), +// ), +// ); +// } +// } + +class FullWdtBtn extends StatelessWidget { + final String btnText; + // final IconData icon; + final VoidCallback onTap; + final TextStyle? styleElement; + final bool isBgTransparent; + final bool disabled; + + const FullWdtBtn({ + Key? key, + required this.btnText, + required this.onTap, + this.styleElement, + this.isBgTransparent = false, + this.disabled = false, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + elevation: isBgTransparent ? 0 : null, + shape: const StadiumBorder(), + backgroundColor: isBgTransparent + ? const Color.fromARGB(43, 0, 0, 0) + : disabled?const Color.fromARGB(255, 70, 90, 25):ColorConstants.kPrimaryColor, + foregroundColor: + isBgTransparent ? ColorConstants.kWhite : ColorConstants.kBlack, + fixedSize: const Size(double.infinity, 50), + textStyle: TextStyle( + fontSize: 15, + color: isBgTransparent ? Colors.white : Colors.black, + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + ), + ), + + // style: ButtonStyle( + // shape: MaterialStateProperty.all( + // RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(30.0), + // ), + // ), + // backgroundColor: MaterialStateProperty.all( + // isBgTransparent ? Colors.transparent : ColorConstants.kPrimaryColor, + // ), + // foregroundColor: + // MaterialStateProperty.all(ColorConstants.kBlack), + // fixedSize: MaterialStateProperty.all( + // const Size.fromHeight(50), + // ), + // ), + onPressed: onTap, + child: Center( + child: Text(btnText), + ), + ); + } +} + +class FullWdtBtnLoader extends StatelessWidget { + const FullWdtBtnLoader({ + Key? key, + required this.onTap, + this.styleElement, + }) : super(key: key); + // final IconData icon; + final VoidCallback onTap; + final TextStyle? styleElement; + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + ), + backgroundColor: MaterialStateProperty.all( + ColorConstants.kPrimaryColor, + ), + foregroundColor: + MaterialStateProperty.all(ColorConstants.kBlack), + fixedSize: MaterialStateProperty.all( + const Size.fromHeight(50), + ), + ), + onPressed: onTap, + child: const Center( + child: CircularProgressIndicator( + color: Colors.black, + ), + ), + ); + } +} diff --git a/gsf/lib/views/components/community_member.dart b/gsf/lib/views/components/community_member.dart new file mode 100644 index 0000000..5f4969f --- /dev/null +++ b/gsf/lib/views/components/community_member.dart @@ -0,0 +1,267 @@ +// import 'package:flutter/material.dart'; +// import 'package:get/get.dart'; +// import '../../theme.dart'; +// import '../modal/member_modal.dart'; +// import 'appbar.dart'; + +// class CommnutyMember extends StatefulWidget { +// final List communityModel; +// const CommnutyMember({required this.communityModel, Key? key}) +// : super(key: key); + +// @override +// State createState() => _CommnutyMemberState(); +// } + +// class _CommnutyMemberState extends State { +// // bool fullDesc = false; +// @override +// Widget build(BuildContext context) { +// final screenSize = Get.mediaQuery.size; +// return Scaffold( +// backgroundColor: ColorConstants.kBlack, +// appBar: PreferredSize( +// preferredSize: const Size.fromHeight(60), +// child: CustomAppBars(titleHead: 'Community'), +// ), +// body: ListView.builder( +// physics: const BouncingScrollPhysics(), +// itemCount: widget.communityModel.length, +// itemBuilder: (context, index) => Container( +// margin: const EdgeInsets.all(10), +// width: screenSize.width * 0.8, +// decoration: BoxDecoration( +// color: const Color(0xff191919), +// borderRadius: BorderRadius.circular(11), +// ), +// child: Padding( +// padding: const EdgeInsets.all(16.0), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// // clipBehavior: Clip.none, +// children: [ +// // Positioned( +// // top: -0, +// // left: -0, +// // child: ClipRRect( +// // borderRadius: BorderRadius.circular(12), +// // child: Image.network( +// // '${communityModel[index].img}', +// // width: 100, +// // height: 150, +// // fit: BoxFit.cover, +// // ), +// // ), +// // ), +// Expanded( +// flex: 3, +// child: ClipRRect( +// borderRadius: BorderRadius.circular(12), +// child: Image.network( +// '${widget.communityModel[index].img}', +// width: 100, +// height: 150, +// fit: BoxFit.cover, +// ), +// ), +// ), +// Expanded( +// flex: 6, +// child: Padding( +// padding: const EdgeInsets.only(left: 20.0), +// child: Column( +// // mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// '${widget.communityModel[index].title}', +// style: const TextStyle( +// fontSize: 12, +// color: ColorConstants.kPrimaryColor), +// ), +// SizedBox( +// height: 20, +// child: ListView.builder( +// itemCount: 5, +// scrollDirection: Axis.horizontal, +// itemBuilder: (context, index1) { +// if (index1 < +// widget.communityModel[index].rating!) { +// return const Icon( +// Icons.star, +// size: 18, +// color: ColorConstants.kPrimaryColor, +// ); +// } else { +// return const Icon( +// Icons.star_outline, +// size: 18, +// color: Color(0xff8D8D8D), +// ); +// } +// }, +// ), +// ), +// const SizedBox(height: 10), +// StatefulBuilder( +// builder: (BuildContext context, setState) { +// return Column( +// mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// !widget.communityModel[index].isExpanded +// ? Text( +// '${widget.communityModel[index].desc}', +// style: const TextStyle( +// fontSize: 12, +// color: Color(0xffD9D9D9), +// height: 1.3, +// ), +// maxLines: 5, +// overflow: TextOverflow.ellipsis, +// ) +// : Text( +// '${widget.communityModel[index].desc}', +// style: const TextStyle( +// fontSize: 12, +// color: Color(0xffD9D9D9), +// height: 1.3, +// ), +// ), +// const SizedBox(height: 5), +// (widget.communityModel[index].desc!.length > 40) +// ? Align( +// alignment: Alignment.bottomRight, +// child: GestureDetector( +// onTap: () { +// setState(() { +// // fullDesc = !fullDesc; +// widget.communityModel[index] +// .isExpanded = +// !widget.communityModel[index] +// .isExpanded; +// }); +// }, +// child: Text( +// !widget.communityModel[index] +// .isExpanded +// ? 'Read More' +// : 'Read Less', +// style: const TextStyle( +// fontSize: 12, +// color: +// ColorConstants.kPrimaryColor, +// ), +// ), +// ), +// ) +// : const SizedBox(), +// ], +// ); +// }, +// ), +// // RichText( +// // text: TextSpan( +// // children: [ +// // TextSpan( +// // text: '${communityModel[index].desc}', +// // style: const TextStyle( +// // fontSize: 12, +// // color: Color(0xffD9D9D9), +// // height: 1.3, +// // overflow: TextOverflow.ellipsis, +// // ), +// // ), + +// // ], +// // ), +// // maxLines: 4, +// // ), +// const SizedBox(height: 5), +// Text( +// '${widget.communityModel[index].memberName}', +// style: const TextStyle( +// fontSize: 12, +// color: ColorConstants.kWhite, +// fontWeight: FontWeight.w600, +// ), +// ) +// ], +// ), +// ), +// ), +// // Row( +// // mainAxisAlignment: MainAxisAlignment.start, +// // crossAxisAlignment: CrossAxisAlignment.start, +// // children: [ +// // const Expanded( +// // child: SizedBox(), +// // flex: 2, +// // ), +// // Expanded( +// // flex: 6, +// // child: Padding( +// // padding: const EdgeInsets.only(left: 20.0), +// // child: Column( +// // // mainAxisAlignment: MainAxisAlignment.start, +// // crossAxisAlignment: CrossAxisAlignment.start, +// // children: [ +// // Text( +// // '${communityModel[index].title}', +// // style: const TextStyle( +// // fontSize: 12, +// // color: ColorConstants.kPrimaryColor), +// // ), +// // SizedBox( +// // height: 20, +// // child: ListView.builder( +// // itemCount: 5, +// // scrollDirection: Axis.horizontal, +// // itemBuilder: (context, index1) { +// // if (index1 < communityModel[index].rating!) { +// // return const Icon( +// // Icons.star, +// // size: 18, +// // color: ColorConstants.kPrimaryColor, +// // ); +// // } else { +// // return const Icon( +// // Icons.star_outline, +// // size: 18, +// // color: Color(0xff8D8D8D), +// // ); +// // } +// // }, +// // ), +// // ), +// // const SizedBox(height: 10), +// // Text( +// // '${communityModel[index].desc}', +// // style: const TextStyle( +// // fontSize: 12, +// // color: Color(0xffD9D9D9), +// // height: 1.3), +// // ), +// // const SizedBox(height: 5), +// // Text( +// // '${communityModel[index].memberName}', +// // style: const TextStyle( +// // fontSize: 12, +// // color: ColorConstants.kWhite, +// // fontWeight: FontWeight.w600, +// // ), +// // ) +// // ], +// // ), +// // ), +// // ), +// // ], +// // ), +// ], +// ), +// ), +// ), +// ), +// ); +// } +// } diff --git a/gsf/lib/views/components/const.dart b/gsf/lib/views/components/const.dart new file mode 100644 index 0000000..3a5f4c5 --- /dev/null +++ b/gsf/lib/views/components/const.dart @@ -0,0 +1,22 @@ +class SignInData { + static dynamic data; + static dynamic name; + static dynamic token; + static dynamic status; + static dynamic mobileNumber; + static dynamic emailId; + static dynamic selectedGender; +} + +class EditProfileData { + static dynamic name; + static dynamic bio; + static dynamic gender; + static dynamic age; + static dynamic phoneNumber; + static dynamic emailIds; + static dynamic fullAddress; + static dynamic city; + static dynamic height; + static dynamic weight; +} diff --git a/gsf/lib/views/components/custom_skeleton.dart b/gsf/lib/views/components/custom_skeleton.dart new file mode 100644 index 0000000..d834d61 --- /dev/null +++ b/gsf/lib/views/components/custom_skeleton.dart @@ -0,0 +1,727 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:skeletons/skeletons.dart'; + +import '../../view_model/global_controller.dart'; + +// =================homa page skeleton running start================ + +class HomePageSkeleton extends StatelessWidget { + const HomePageSkeleton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + body: SingleChildScrollView( + // physics: const NeverScrollableScrollPhysics(), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 15), + SizedBox( + width: context.width, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + const SizedBox(height: 15), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: context.width, + height: 170, + borderRadius: BorderRadius.circular(10), + ), + ), + const SizedBox(height: 30), + gsfTrendingChamps(), + const SizedBox(height: 30), + floatingBannerSkeleton(), + const SizedBox(height: 30), + headWithArrow(), + const SizedBox(height: 10), + upcomingActivities(), + const SizedBox(height: 30), + headWithArrow(), + const SizedBox(height: 10), + personalizedDietPlan(), + const SizedBox(height: 30), + headWithArrow(), + const SizedBox(height: 10), + shortClips(), + const SizedBox(height: 30), + headWithArrow(), + const SizedBox(height: 10), + courses(), + const SizedBox(height: 30), + headWithArrow(), + const SizedBox(height: 10), + meetTheCommunity() + ], + ), + ), + ), + ); + } + + gsfTrendingChamps() { + return Column( + children: [ + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 3.5, + height: 120, + borderRadius: BorderRadius.circular(10), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 3.5, + height: 120, + borderRadius: BorderRadius.circular(10), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 3.5, + height: 120, + borderRadius: BorderRadius.circular(10), + ), + ), + ], + ), + const SizedBox(height: 20), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 20), + width: Get.width, + height: 50, + borderRadius: BorderRadius.circular(25), + ), + ), + ], + ); + } + + floatingBannerSkeleton() { + return SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 0), + width: Get.width, + height: 200, + borderRadius: BorderRadius.circular(0), + ), + ); + } + + upcomingActivities() { + return SizedBox( + height: 200, + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 3, + itemBuilder: (context, index) => SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ); + } + + personalizedDietPlan() { + return SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width, + height: 170, + borderRadius: BorderRadius.circular(10), + ), + ); + } + + shortClips() { + return SizedBox( + height: 240, + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 3, + itemBuilder: (context, index) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 3.2, + height: 180, + borderRadius: BorderRadius.circular(20), + ), + ), + // const SizedBox(height: 10), + SizedBox( + width: Get.width / 3.2, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + padding: const EdgeInsets.symmetric( + horizontal: 0, vertical: 8), + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 12, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ); + }), + ); + } + + courses() { + return SizedBox( + height: 130, + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 3, + itemBuilder: (context, index) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 2.5, + height: 100, + borderRadius: BorderRadius.circular(8), + ), + ), + // const SizedBox(height: 10), + SizedBox( + width: Get.width / 2.5, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + padding: + const EdgeInsets.symmetric(horizontal: 0, vertical: 8), + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + height: 12, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ); + }, + ), + ); + } + + meetTheCommunity() { + return SizedBox( + height: 180, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 3, + physics: const ScrollPhysics(), + itemBuilder: (context, index) => SizedBox( + width: Get.width * 0.95, + child: Row( + children: [ + Expanded( + flex: 2, + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width, + height: 170, + borderRadius: BorderRadius.circular(10), + ), + ), + ), + Expanded( + flex: 4, + child: Column( + children: [ + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 3, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + const SizedBox(height: 5), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + headWithArrow() { + return Row( + children: [ + Expanded( + flex: 10, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + height: 25, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + const Expanded(flex: 1, child: SizedBox()), + Expanded( + flex: 1, + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 0), + width: Get.width, + height: 25, + borderRadius: BorderRadius.circular(8), + ), + ), + ) + ], + ); + } +} + +//========my ranking page skeleton start====================== + +class LeaderboardSkeleton extends StatelessWidget { + const LeaderboardSkeleton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + topMembersSkeleton(), + const SizedBox(height: 40), + listMemberSkeleton(), + ], + ), + ), + ); + } + + topMembersSkeleton() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: Get.width / 3.5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 150), + SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: const EdgeInsets.symmetric(horizontal: 0), + width: 110, + height: 110, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + SizedBox( + width: Get.width / 3.5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: const EdgeInsets.symmetric(horizontal: 0), + width: 110, + height: 110, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + SizedBox( + width: Get.width / 3.5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 150), + SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: const EdgeInsets.symmetric(horizontal: 0), + width: 110, + height: 110, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + ], + ); + } + + listMemberSkeleton() { + return ListView.builder( + shrinkWrap: true, + itemCount: 15, + physics: const ScrollPhysics(), + itemBuilder: (context, index) => Container( + margin: const EdgeInsets.symmetric(horizontal: 0, vertical: 8), + decoration: BoxDecoration( + color: const Color(0xff333333), + borderRadius: BorderRadius.circular(50)), + child: Row( + children: [ + Expanded( + flex: 1, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + width: Get.width, + height: 20, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + Expanded( + flex: 5, + child: Row( + children: [ + Expanded( + flex: 1, + child: Align( + alignment: Alignment.center, + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + // maxWidth: Get.width, + padding: const EdgeInsets.symmetric(horizontal: 0), + width: 50, + height: 50, + borderRadius: BorderRadius.circular(100), + ), + ), + ), + ), + Expanded( + flex: 3, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + width: Get.width, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ), + ), + Expanded( + flex: 1, + child: SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + height: 20, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ) + ], + ), + ), + ); + } +} + +//========profile page skeleton start====================== + +class ProfileSkeleton extends StatelessWidget { + const ProfileSkeleton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: SafeArea( + child: Column( + children: [ + const SizedBox(height: 80), + Container( + height: 280, + width: Get.width, + margin: const EdgeInsets.all(8), + decoration: const BoxDecoration( + color: Color(0xff333333), + ), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -50, + left: 0, + right: 0, + child: Align( + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: const EdgeInsets.symmetric(horizontal: 0), + width: 120, + height: 120, + borderRadius: BorderRadius.circular(100), + ), + ), + ), + ), + // const SizedBox(height: 20), + Column( + children: [ + const SizedBox(height: 100), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + const SizedBox(height: 10), + Row( + children: [ + Expanded( + flex: 1, + child: Column( + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: const EdgeInsets.symmetric( + horizontal: 0), + width: Get.width, + height: 40, + borderRadius: BorderRadius.circular(100), + ), + ), + const SizedBox(height: 10), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Column( + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + width: Get.width, + height: 40, + borderRadius: BorderRadius.circular(100), + ), + ), + const SizedBox(height: 10), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + ], + ), + ], + ) + ], + ), + ), + const SizedBox(height: 8), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + alignment: Alignment.center, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + const SizedBox(height: 8), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 3, + spacing: 10, + lineStyle: SkeletonLineStyle( + // randomLength: true, + height: 15, + alignment: Alignment.centerLeft, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/components/dialog_app_tour_permission.dart b/gsf/lib/views/components/dialog_app_tour_permission.dart new file mode 100644 index 0000000..0407c65 --- /dev/null +++ b/gsf/lib/views/components/dialog_app_tour_permission.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +import '../pages/home/home_page.dart'; +import '../theme.dart'; +import 'btn.dart'; + +void guidedTourPremission(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + var box = GetStorage(); + Get.bottomSheet( + SizedBox( + height: screenSize.width * 0.7, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.1), + child: Column( + children: [ + const Spacer(flex: 3), + Text( + 'Would you like a guided tour\n of our app?', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 20, + color: ColorConstants.kWhite.withOpacity(0.8), + ), + ), + const SizedBox(height: 30), + FullWdtBtn( + isBgTransparent: false, + btnText: 'Yes', + onTap: () { + box.write("showMoodOmeter", false); + box.write('ShowModalSheet', false); + box.write('showAppTour', true); + box.write('isLoggedIn', true); + Get.offAll(() => const HomePage()); + // box.write('isUserRegistered', true).then((value) { + // Get.to(() => const ShareThought()); + // }); + // if (widget.fromHomePage) { + // SignInData.data == 'success' + // ? Get.offAll(const HomePage()) + // : null; + // Get.offAll(const HomePage()); + // Get.offAll( + // ShowCaseWidget( + // builder: Builder( + // builder: (context) => const HomePage(), + // ), + // ), + // ); + // Get.offAll(() => const HomePage()); + // } else { + // box.write('showAppTour', true).then((value) { + // Get.back(); + // Get.back(); + // SignInData.data == 'success' + // ? Get.off(const HomePage()) + // : null; + // }); + // Get.offAll(const HomePage()); + // } + }), + const SizedBox(height: 10), + /* + InkWell( + onTap: () { + box.write('showAppTour', false).then((value) { + Get.off(const HomePage()); + }); + box.write('isLoggedIn', true); + }, + splashColor: Colors.transparent, + child: const Text( + 'No', + style: TextStyle( + fontSize: 18, + color: Color(0xffffffff), + ), + ), + ), + */ + FullWdtBtn( + isBgTransparent: true, + btnText: "No", + onTap: () { + box.write("showMoodOmeter", true); + box.write('ShowModalSheet', true); + box.write('showAppTour', false); + box.write('isLoggedIn', true); + Get.offAll(const HomePage()); + }, + ), + const Spacer(flex: 2), + ], + ), + ), + ), + backgroundColor: const Color(0xff212121), + barrierColor: ColorConstants.kBlack, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + ); +} diff --git a/gsf/lib/views/components/floating_action_btn.dart b/gsf/lib/views/components/floating_action_btn.dart new file mode 100644 index 0000000..37d3dea --- /dev/null +++ b/gsf/lib/views/components/floating_action_btn.dart @@ -0,0 +1,73 @@ +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; + +import '../pages/quiz/quiz_home.dart'; +import '../theme.dart'; + +class FlotingActionBtn extends StatelessWidget { + const FlotingActionBtn({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // return InkWell( + // // onTap: () => Get.to(() => const QuizHome()), + // splashColor: Colors.transparent, + // child: Container( + // width: 80, + // height: 80, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(100), + // ), + // child: Image.asset( + // 'assets/image/quiz.png', + // fit: BoxFit.cover, + // ), + // ), + // ); + return OpenContainerWrappersQuiz( + closeBuild: Container( + width: 80, + height: 80, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + child: Image.asset( + 'assets/image/quiz.png', + fit: BoxFit.cover, + ), + ), + openBuild: const QuizHome()); + } +} + +class OpenContainerWrappersQuiz extends StatelessWidget { + const OpenContainerWrappersQuiz({ + Key? key, + required this.closeBuild, + required this.openBuild, + }) : super(key: key); + + final Widget closeBuild; + final Widget openBuild; + + @override + Widget build(BuildContext context) { + return OpenContainer( + closedColor: ColorConstants.kBlack, + openColor: ColorConstants.kBlack, + transitionDuration: const Duration(milliseconds: 500), + closedShape: RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(100.0), + ), + ), + openBuilder: (BuildContext _, VoidCallback openContainer) { + return openBuild; + }, + closedBuilder: (BuildContext _, VoidCallback openContainer) { + return closeBuild; + }, + transitionType: ContainerTransitionType.fade, + ); + } +} diff --git a/gsf/lib/views/components/home_appbar.dart b/gsf/lib/views/components/home_appbar.dart new file mode 100644 index 0000000..5ad9473 --- /dev/null +++ b/gsf/lib/views/components/home_appbar.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +import '../../view_model/home_controller.dart'; +import '../theme.dart'; + +homeAppBar() { + final TabsController controller = TabsController(); + return AppBar( + backgroundColor: ColorConstants.kBlack, + leading: InkWell( + onTap: () { + controller.openDrawer; + }, + child: Padding( + padding: const EdgeInsets.all(8), + child: Image.asset('assets/image/menu.png'), + ), + ), + actions: [ + SizedBox( + child: (controller.isLoggedIn) + ? Row( + children: [ + GestureDetector( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(0), + child: InkWell( + onTap: () {}, + child: const Icon( + Icons.notifications, + color: ColorConstants.kWhite, + ), + ), + ), + ), + GestureDetector( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(12), + child: InkWell( + splashColor: Colors.transparent, + onTap: () {}, + child: const Icon( + Icons.settings_outlined, + color: ColorConstants.kWhite, + ), + ), + ), + ) + ], + ) + : GestureDetector( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(12), + child: Image.asset( + 'assets/image/logout.png', + width: 30, + ), + ), + ), + ) + ], + ); +} diff --git a/gsf/lib/views/components/leaderboard_element.dart b/gsf/lib/views/components/leaderboard_element.dart new file mode 100644 index 0000000..9504501 --- /dev/null +++ b/gsf/lib/views/components/leaderboard_element.dart @@ -0,0 +1,216 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; + +import '../../view_model/common_functions.dart'; +import '../theme.dart'; + +List> leaderboardJson = [ + { + "id": 1, + "rank": 1, + "points": 70000, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_right.svg", + "imgPath": "assets/image/4.png", + "userName": "Kartikey", + }, + { + "id": 2, + "rank": 5, + "points": 60540, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_up.svg", + "imgPath": "assets/image/4.png", + "userName": "Uzer", + }, + { + "id": 3, + "rank": 6, + "points": 60440, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_down.svg", + "imgPath": "assets/image/4.png", + "userName": "Vimlesh", + }, + { + "id": 4, + "rank": 7, + "points": 50440, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_right.svg", + "imgPath": "assets/image/4.png", + "userName": "Rushabh", + }, + { + "id": 5, + "rank": 8, + "points": 60540, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_up.svg", + "imgPath": "assets/image/4.png", + "userName": "Ravi", + }, + { + "id": 6, + "rank": 9, + "points": 60440, + "leaderboardArrowIconPath": "assets/image/arrows/arrow_down.svg", + "imgPath": "assets/image/4.png", + "userName": "Kamlesh", + }, +]; + +class LeaderboardElement extends StatelessWidget { + const LeaderboardElement({ + required this.id, + required this.rank, + required this.points, + required this.leaderboardArrowIconPath, + required this.imgPath, + required this.userName, + this.lastUpdate, + Key? key, + }) : super(key: key); + + final int id; + final int rank; + final int points; + final String leaderboardArrowIconPath; + final String imgPath; + final String userName; + final String? lastUpdate; + + @override + Widget build(BuildContext context) { + // final brightess = Get.theme.brightness; + GlobalController globalController = Get.find(); + return Obx( + () => Container( + height: 56, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 4), + margin: const EdgeInsets.only(bottom: 0), + decoration: BoxDecoration( + color: id.isOdd + ? !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.1) + : const Color.fromARGB(255, 31, 31, 31) + : !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.1) + : const Color(0xff333333), + borderRadius: BorderRadius.circular(30), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(50), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const SizedBox(width: 4), + Expanded( + flex: 0, + child: Text( + rank.toString(), + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 22, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ), + ), + const SizedBox(width: 14), + Expanded( + flex: 1, + child: SvgPicture.asset( + leaderboardArrowIconPath, + width: 16, + height: 16, + ), + ), + ClipRRect( + borderRadius: BorderRadius.circular(300), + child: Container( + width: 38, + height: 38, + color: const Color.fromARGB(255, 22, 22, 22), + child: imgPath.isEmpty + ? Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I=', + ) + : Image.network( + correctImgUrl(imgPath), + fit: BoxFit.cover, + ), + ), + ), + const SizedBox( + width: 20, + ), + Expanded( + flex: 5, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + userName, + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + height: 1, + fontSize: 14, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + // Row( + // children: [ + // SvgPicture.asset( + // "assets/image/profile/crown.svg", + // ), + // const SizedBox(width: 4), + // SvgPicture.asset( + // "assets/image/profile/dumbell.svg", + // ), + // const SizedBox(width: 4), + // SvgPicture.asset( + // "assets/image/profile/runner.svg", + // ), + // ], + // ), + const SizedBox(height: 5), + Text( + '${lastUpdate}', + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + height: 1, + fontSize: 12, + ), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Align( + alignment: Alignment.centerRight, + child: Text( + "$points Pt", + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w700, + color:!globalController.darkMode.value? ColorConstants.kBlack:ColorConstants.kPrimaryColor, + fontSize: 17, + ), + ), + ), + ), + const SizedBox(height: 18) + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/components/mood_meter.dart b/gsf/lib/views/components/mood_meter.dart new file mode 100644 index 0000000..1a31916 --- /dev/null +++ b/gsf/lib/views/components/mood_meter.dart @@ -0,0 +1,366 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/services/home_controller.dart'; +import 'package:gsp_app/repository/services/mood_o_meter_service.dart'; + +import '../../modals/set_mood_res_modal.dart'; +import '../../repository/response_data.dart'; +import '../../repository/services/cj/moodOmeter_services.dart'; +import '../theme.dart'; + +int activeIndexMoodOMeter = -1; + + +class MoodOMeter extends StatefulWidget { + const MoodOMeter({Key? key}) : super(key: key); + + @override + State createState() => _MoodOMeterState(); +} + +class _MoodOMeterState extends State { + // static int activeIndexMoodOMeter = -1; + bool isLoading = false; + HomeApiController homeApiController = Get.put(HomeApiController()); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + setState(() => isLoading = !isLoading); + MoodOMeterService() + .uploadMood("Very Happy") + .then((value) async { + var jsonResp = jsonDecode(value.body); + homeApiController.setMoodOMeterResp(jsonResp); + // SetMoodResponse setMoodResponse = SetMoodResponse(); + // setMoodResponse = SetMoodResponse.fromJson(jsonResp); + // print("setMoodResponse $setMoodResponse"); + // // SetMoodRespon; + // // setMoodResponse.success; + // print( "setMoodResponse ${setMoodResponse.success}"); + // print("pro ${setMoodResponse.progressBar}"); + + // print("uploadMood $value"); + var moodResult = await MoodOMeterService().getMoodOMeter(); + // if() + if(moodResult.responseStatus == ResponseStatus.success ){ + setState(() { + activeIndexMoodOMeter = 0; + isLoading = !isLoading; + }); + } + } + ); + }, + child: SvgPicture.asset( + activeIndexMoodOMeter == 0 + ? 'assets/image/mood_icons/active/mood_very_happy_active.svg' + : 'assets/image/mood_icons/inactive/mood_very_happy_inactive.svg', + width: 50, + height: 50, + ), + ), + GestureDetector( + onTap: () { + setState(() => isLoading = !isLoading); + MoodOMeterService() + .uploadMood("Happy") + .then((value) async { + var jsonResp = jsonDecode(value.body); + homeApiController.setMoodOMeterResp(jsonResp); + var moodResult = await MoodOMeterService().getMoodOMeter(); + // if() + if(moodResult.responseStatus == ResponseStatus.success ){ + setState(() { + activeIndexMoodOMeter = 1; + isLoading = !isLoading; + }); + } + } + // => setState(() { + // activeIndexMoodOMeter = 1; + // isLoading = !isLoading; + // }) + ); + }, + child: SvgPicture.asset( + activeIndexMoodOMeter == 1 + ? 'assets/image/mood_icons/active/mood_happy_active.svg' + : 'assets/image/mood_icons/inactive/mood_happy_inactive.svg', + width: 50, + height: 50, + ), + ), + GestureDetector( + onTap: () { + setState(() => isLoading = !isLoading); + MoodOMeterService() + .uploadMood("Ok") + .then((value) async { + var jsonResp = jsonDecode(value.body); + homeApiController.setMoodOMeterResp(jsonResp); + var moodResult = await MoodOMeterService().getMoodOMeter(); + // if() + if(moodResult.responseStatus == ResponseStatus.success ){ + setState(() { + activeIndexMoodOMeter = 2; + isLoading = !isLoading; + }); + } + } + // => setState(() { + // activeIndexMoodOMeter = 2; + // isLoading = !isLoading; + // }) + ); + }, + child: SvgPicture.asset( + activeIndexMoodOMeter == 2 + ? 'assets/image/mood_icons/active/mood_ok_active.svg' + : 'assets/image/mood_icons/inactive/mood_ok_inactive.svg', + width: 50, + height: 50, + ), + ), + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: GestureDetector( + onTap: () { + setState(() => isLoading = !isLoading); + MoodOMeterService().uploadMood("Whatever").then( + (value) async { + var jsonResp = jsonDecode(value.body); + homeApiController.setMoodOMeterResp(jsonResp); + var moodResult = await MoodOMeterService().getMoodOMeter(); + // if() + if(moodResult.responseStatus == ResponseStatus.success ){ + setState(() { + activeIndexMoodOMeter = 3; + isLoading = !isLoading; + }); + } + } + // => setState( + // () { + // activeIndexMoodOMeter = 3; + // isLoading = !isLoading; + // }, + // ), + ); + }, + child: SvgPicture.asset( + activeIndexMoodOMeter == 3 + ? 'assets/image/mood_icons/active/mood_whatever_active.svg' + : 'assets/image/mood_icons/inactive/mood_whatever_inactive.svg', + width: 50, + height: 50, + ), + ), + ), + GestureDetector( + onTap: () { + setState(() => isLoading = !isLoading); + MoodOMeterService() + .uploadMood("Sad") + .then((value) async { + var jsonResp = jsonDecode(value.body); + homeApiController.setMoodOMeterResp(jsonResp); + var moodResult = await MoodOMeterService().getMoodOMeter(); + // if() + if(moodResult.responseStatus == ResponseStatus.success ){ + setState(() { + activeIndexMoodOMeter = 4; + isLoading = !isLoading; + }); + } + } + // => setState(() { + // activeIndexMoodOMeter = 4; + // isLoading = !isLoading; + // }) + ); + }, + child: SvgPicture.asset( + activeIndexMoodOMeter == 4 + ? 'assets/image/mood_icons/active/mood_sad_active.svg' + : 'assets/image/mood_icons/inactive/mood_sad_inactive.svg', + width: 50, + height: 50, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Stack( + children: [ + Row( + children: [ + Expanded( + child: Container( + height: 8, + color: activeIndexMoodOMeter == 0 + ? ColorConstants.kPrimaryColor + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + Expanded( + child: Container( + height: 8, + color: activeIndexMoodOMeter == 1 + ? ColorConstants.kPrimaryColor + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + Expanded( + child: Container( + height: 8, + color: activeIndexMoodOMeter == 2 + ? ColorConstants.kPrimaryColor + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + Expanded( + child: Container( + height: 8, + color: activeIndexMoodOMeter == 3 + ? ColorConstants.kPrimaryColor + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + Expanded( + child: Stack( + children: [ + Container( + height: 8, + color: activeIndexMoodOMeter == 4 + ? ColorConstants.kPrimaryColor + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ], + ), + ), + ], + ), + Visibility( + visible: isLoading, + child: const LinearProgressIndicator( + minHeight: 8, + color: ColorConstants.kPrimaryColor, + ), + ) + ], + ), + const SizedBox(height: 12), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Text( + "Very Happy", + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + fontSize: 12, + color: activeIndexMoodOMeter == 0 + ? (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + ), + Expanded( + child: Text( + "Happy", + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + fontSize: 12, + color: activeIndexMoodOMeter == 1 + ? (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + ), + Expanded( + child: Text( + "Ok", + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + fontSize: 12, + color: activeIndexMoodOMeter == 2 + ? (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + ), + Expanded( + child: Text( + "Whatever", + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + fontSize: 12, + color: activeIndexMoodOMeter == 3 + ? (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + ), + Expanded( + child: Text( + "Sad", + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + fontSize: 12, + color: activeIndexMoodOMeter == 4 + ? (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white + : (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color.fromRGBO(255, 255, 255, 0.35), + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/gsf/lib/views/components/notification_icon.dart b/gsf/lib/views/components/notification_icon.dart new file mode 100644 index 0000000..9d7fca1 --- /dev/null +++ b/gsf/lib/views/components/notification_icon.dart @@ -0,0 +1,107 @@ +// ignore_for_file: prefer_typing_uninitialized_variables + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/modals/notification_model.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/cj/get_notification_count_service.dart'; +import '../../view_model/global_controller.dart'; +import '../pages/notification.dart'; +import '../theme.dart'; + +class NotificationIcon extends StatefulWidget { + const NotificationIcon({Key? key}) : super(key: key); + @override + State createState() => _NotificationIconState(); +} + +class _NotificationIconState extends State + with SingleTickerProviderStateMixin { + AnimationController? _animationController; + + GlobalController globalContoller = Get.find(); + + @override + void initState() { + _animationController = AnimationController( + vsync: this, duration: const Duration(milliseconds: 500)); + super.initState(); + } + + void _runAnimation() async { + for (int i = 0; i < 1; i++) { + await _animationController?.forward(); + await _animationController?.reverse(); + } + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + return RotationTransition( + turns: Tween(begin: 0.0, end: -.1) + .chain(CurveTween(curve: Curves.elasticIn)) + .animate(_animationController!), + child: GestureDetector( + onTap: () { + _runAnimation(); + Get.to(() => const Notifications()); + }, + child: FutureBuilder( + future: GetNotificationCount().getNotificationCout(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + NotificationModel data = snapshot.data!.data; + // print('Snap all data of notifications ${data.success}'); + List filteredNotifications = data.notificationList + .where((notification) => notification.isRead == "0") + .toList(); + return Padding( + padding: const EdgeInsets.all(0), + child: Stack( + clipBehavior: Clip.none, + children: [ + Obx(() => Icon( + Icons.notifications, + color: globalContoller.darkMode.value?ColorConstants.kWhite:ColorConstants.kBlack, + // color: Colors.red, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + size: 30, + )), + filteredNotifications.isNotEmpty + ? Positioned( + top: -5, + left: -5, + child: Container( + width: 22, + height: 22, + // padding: const EdgeInsets.all(3), + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.circular(100)), + child: Center( + child: Text( + '${filteredNotifications.length}', + style: const TextStyle( + color: Colors.black, + fontSize: 11, + fontWeight: FontWeight.w600), + ), + ), + ), + ) + : const SizedBox(), + ], + ), + ); + } + + return const SizedBox(); + }, + )), + ); + } +} diff --git a/gsf/lib/views/components/page_animation.dart b/gsf/lib/views/components/page_animation.dart new file mode 100644 index 0000000..ae727d1 --- /dev/null +++ b/gsf/lib/views/components/page_animation.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:animations/animations.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import '../theme.dart'; + +class OpenContainerWrappers extends StatelessWidget { + const OpenContainerWrappers({ + Key? key, + required this.closeBuild, + required this.openBuild, + }) : super(key: key); + + final Widget closeBuild; + final Widget openBuild; + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + return Obx( + () => OpenContainer( + closedElevation: 0, + closedColor: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + openColor: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + transitionDuration: const Duration(milliseconds: 500), + middleColor: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + closedShape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(0), + ), + openBuilder: (BuildContext _, VoidCallback openContainer) { + return openBuild; + }, + closedBuilder: (BuildContext _, VoidCallback openContainer) { + return closeBuild; + }, + transitionType: ContainerTransitionType.fade, + ), + ); + } +} diff --git a/gsf/lib/views/components/pretty_exception.dart b/gsf/lib/views/components/pretty_exception.dart new file mode 100644 index 0000000..07a8c85 --- /dev/null +++ b/gsf/lib/views/components/pretty_exception.dart @@ -0,0 +1,11 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; + +String prettyException(String prefix, dynamic e) { + if (e is FlutterBluePlusException) { + return "$prefix ${e.errorString}"; + } else if (e is PlatformException) { + return "$prefix ${e.message}"; + } + return prefix + e.toString(); +} \ No newline at end of file diff --git a/gsf/lib/views/components/primary_button.dart b/gsf/lib/views/components/primary_button.dart new file mode 100644 index 0000000..a369f10 --- /dev/null +++ b/gsf/lib/views/components/primary_button.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get/get_core/src/get_main.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../view_model/global_controller.dart'; +import '../theme.dart'; + +class PrimaryButton extends StatelessWidget { + const PrimaryButton({ + Key? key, + required this.controller, + required this.onTap, + required this.text, + this.bgColor = ColorConstants.kPrimaryColor, + }) : super(key: key); + + final RoundedLoadingButtonController controller; + final VoidCallback onTap; + final String text; + final Color bgColor; + + + + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: controller.stateStream, + builder: (context, snapshot) { + return RoundedLoadingButton( + color: bgColor, + valueColor: ColorConstants.kBlack, + successColor: ColorConstants.kPrimaryColor, + successIcon: Icons.done_all_rounded, + errorColor: ColorConstants.kErroColor, + loaderStrokeWidth: 2.4, + child: Text( + text, + style: const TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + color: ColorConstants.kBlack + ), + ), + controller: controller, + onPressed: onTap, + ); + }, + ); + } +} diff --git a/gsf/lib/views/components/shimmer_skeleton_base.dart b/gsf/lib/views/components/shimmer_skeleton_base.dart new file mode 100644 index 0000000..342568b --- /dev/null +++ b/gsf/lib/views/components/shimmer_skeleton_base.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +class ShimmerSkeletonBase extends StatelessWidget { + const ShimmerSkeletonBase({ + required this.width, + required this.height, + required this.radius, + Key? key, + }) : super(key: key); + + final double width, height, radius; + + @override + Widget build(BuildContext context) { + return Container( + height: height, + width: width, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(radius), + ), + ); + } +} diff --git a/gsf/lib/views/components/tween_max.dart b/gsf/lib/views/components/tween_max.dart new file mode 100644 index 0000000..f5b8e9b --- /dev/null +++ b/gsf/lib/views/components/tween_max.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +tweenMaxAnimationbottom(Widget childs, double val) { + return TweenAnimationBuilder( + tween: Tween(begin: 0, end: 1), + duration: const Duration(milliseconds: 1000), + builder: (BuildContext context, double value, Widget? child) { + return Opacity( + opacity: value, + child: Padding( + padding: EdgeInsets.only(bottom: value * val), + child: childs, + ), + ); + }, + ); +} + +tweenMaxAnimationtop(Widget childs, double val) { + return TweenAnimationBuilder( + tween: Tween(begin: 1, end: 0.8), + duration: const Duration(milliseconds: 1000), + builder: (BuildContext context, double value, Widget? child) { + return Opacity( + opacity: value, + child: Padding( + padding: EdgeInsets.only(top: value * val), + child: childs, + ), + ); + }, + ); +} + +tweenMaxAnimationleft(Widget childs, double val) { + return TweenAnimationBuilder( + tween: Tween(begin: 1, end: 0.8), + duration: const Duration(milliseconds: 1000), + builder: (BuildContext context, double value, Widget? child) { + return Opacity( + opacity: value, + child: Padding( + padding: EdgeInsets.only(left: value * val), + child: childs, + ), + ); + }, + ); +} diff --git a/gsf/lib/views/components/upcoming_session.dart b/gsf/lib/views/components/upcoming_session.dart new file mode 100644 index 0000000..24fc5ed --- /dev/null +++ b/gsf/lib/views/components/upcoming_session.dart @@ -0,0 +1,180 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:skeletons/skeletons.dart'; + +import '../../modals/upcoming_session_model.dart'; +import '../../repository/response_data.dart'; +import '../../repository/services/cj/upcoming_activity_service.dart'; +import '../pages/Sessions/count_me.dart'; +import '../theme.dart'; + +class UpcomingSession extends StatelessWidget { + const UpcomingSession({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: UpcomingActivityServices().getUpcomingActivitydata(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + List data = snapshot.data!.data; + return data.isNotEmpty + ? Column( + children: [ + SizedBox( + height: 200, + child: ListView.builder( + shrinkWrap: true, + itemCount: data.length, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Stack( + children: [ + Image.network( + data[index].activityDayBanner, + width: Get.width * 0.85, + fit: BoxFit.cover, + ), + Positioned( + bottom: 0, + right: 0, + left: 0, + child: Container( + color: Colors.black38, + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 20, + vertical: 10), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + 'Level - ${data[index].subscription.planName.split(' ')[0]}', + style: const TextStyle( + fontSize: 14, + color: + ColorConstants.kWhite, + fontWeight: + FontWeight.w500, + ), + ), + Text( + 'With ${data[index].activityData.first.techerData.teacherName}', + style: const TextStyle( + fontSize: 14, + color: + ColorConstants.kWhite, + fontWeight: + FontWeight.w500, + ), + ) + ], + ), + ), + ), + ), + ], + ), + ), + ), + openBuild: CountMe( + activityTitle: data[index].activityName, + date: data[index].date, + timer: data[index].time, + ), + ); + }, + ), + ), + // const SizedBox(height: 16), + // SizedBox( + // width: Get.width, + // height: 69, + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 22), + // child: Column( + // children: [ + // Align( + // alignment: Alignment.centerLeft, + // child: Text( + // "Yoga For Stress Relief", + // style: QuizTextStyles.heading.copyWith( + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite), + // ), + // ), + // const SizedBox(height: 4), + // Align( + // alignment: Alignment.centerLeft, + // child: Text( + // "With Tinku Maharaj", + // style: TextStyle( + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack.withOpacity(0.6) + // : const Color.fromRGBO( + // 255, 255, 255, 0.5), + // ), + // ), + // ), + // Align( + // alignment: Alignment.centerLeft, + // child: Text( + // "Duration: 60 mins", + // style: TextStyle( + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack.withOpacity(0.6) + // : const Color.fromRGBO( + // 255, 255, 255, 0.5), + // ), + // ), + // ), + // ], + // ), + // ), + // ) + ], + ) + : const SizedBox( + height: 200, + child: Center( + child: Text('No Activity Found'), + )); + } + return SizedBox( + height: 200, + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 4, + itemBuilder: (context, index) => Container( + margin: const EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ); + } +} \ No newline at end of file diff --git a/gsf/lib/views/components/videos_not_found.dart b/gsf/lib/views/components/videos_not_found.dart new file mode 100644 index 0000000..07eced8 --- /dev/null +++ b/gsf/lib/views/components/videos_not_found.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class VideosNotFound extends StatelessWidget { + const VideosNotFound({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 210, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.video_library_rounded, + color: Colors.white, + size: 42, + ), + SizedBox(height: 8), + Text("Videos Not Found") + ]), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/AddNewPeriod.dart b/gsf/lib/views/pages/MenstrualCycleTracker/AddNewPeriod.dart new file mode 100644 index 0000000..55732c2 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/AddNewPeriod.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/components/btn.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/OverviewPage.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/SecondQuestion.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/TrackerHomePage.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import 'viewModel/StoringDates.dart'; + +class AddNewPeriod extends StatefulWidget { + const AddNewPeriod({super.key}); + + @override + State createState() => _AddNewPeriodState(); +} + +class _AddNewPeriodState extends State { + final periodLength = TextEditingController(); + bool showTextField = false; + @override + void initState() { + super.initState(); + } + + _validate() async { + if (!hasNullEndDate(helperController.pickerdateRange)) { + if (helperController.pickerdateRange.isEmpty) { + Fluttertoast.showToast( + msg: 'Please select atleast one date range', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0, + ); + } else { + Fluttertoast.showToast( + msg: 'Period date successfully logged', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + // backgroundColor: Colors.red, + // textColor: Colors.white, + fontSize: 16.0, + ); + await helperController.recalculate(); + await helperController.calculateOutOfDays(); + await helperController.calculatePeriodDateForCalender(); + Get.to(() => TrackerHomePage( + fromAddNewPeriod: true, + )); + } + } else { + Fluttertoast.showToast( + msg: 'End date cannot be null', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0, + ); + } + } + + bool hasNullEndDate(RxList ranges) { + return ranges.any((range) => range.endDate == null); + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + return false; + }, + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + showLeading: false, + titleHead: 'Menstrual Cycle Tracker', + ), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only(left: 16, right: 16, top: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsets.only( + left: 10.0, + ), + child: Text( + "Log new Period Range", + style: TextStyle(fontSize: 16), + ), + ), + const SizedBox( + height: 10, + ), + SizedBox( + height: Get.height * 0.6, + child: SfDateRangePicker( + initialSelectedRanges: + helperController.pickerdateRange.toSet().toList(), + todayHighlightColor: ColorConstants.kPrimaryColor, + rangeSelectionColor: ColorConstants.periodsColor, + startRangeSelectionColor: ColorConstants.periodsColor, + endRangeSelectionColor: ColorConstants.periodsColor, + showActionButtons: false, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.month, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.multiRange, + maxDate: DateTime.now(), + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + helperController.pickerdateRange.value = args.value; + // print("range value is :- ${pickerdateRange.first}"); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + }, + onSubmit: (p0) { + //calculatePeriodCycleLength(); + _validate(); + }, + ), + ), + FullWdtBtn( + onTap: () { + _validate(); + }, + btnText: 'Save', + ), + // SizedBox( + // height: 20, + // ), + // FullWdtBtn( + // onTap: () { + // Get.back(); + // }, + // btnText: 'Cancel', + // ), + ], + )), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/DemoPage.dart b/gsf/lib/views/pages/MenstrualCycleTracker/DemoPage.dart new file mode 100644 index 0000000..9d0a356 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/DemoPage.dart @@ -0,0 +1,62 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +class DemoPage extends StatefulWidget { + const DemoPage({super.key}); + + @override + State createState() => _DemoPageState(); +} + +class _DemoPageState extends State { + List pickerdateRange = []; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SfDateRangePicker( + onSubmit: (p0) { + print("final value $p0"); + }, + showActionButtons: false, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.year, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.multiRange, + onSelectionChanged: (DateRangePickerSelectionChangedArgs args) { + List? selectedRanges = + args.value as List?; + + if (selectedRanges != null && selectedRanges.isNotEmpty) { + print("Selected ranges:"); + } + + // Example: Adding a new PickerDateRange to the pickerdateRange list + pickerdateRange.add(PickerDateRange( + DateTime.now(), DateTime.now().add(Duration(days: 3)))); + + // Print the generated list + print("Generated list is: ${pickerdateRange.first.startDate}"); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + if (_visibleView == DateRangePickerView.month) { + // setState(() { + // dayView = true; + // }); + } + }, + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/FirstQuestion.dart b/gsf/lib/views/pages/MenstrualCycleTracker/FirstQuestion.dart new file mode 100644 index 0000000..076f9cd --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/FirstQuestion.dart @@ -0,0 +1,209 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/SecondQuestion.dart'; + +import 'viewModel/StoringDates.dart'; + +class FirstQuestion extends StatefulWidget { + const FirstQuestion({super.key}); + + @override + State createState() => _FirstQuestionState(); +} + +class _FirstQuestionState extends State { + final periodLength = TextEditingController(); + bool showTextField = false; + + _validateAnswer() { + String answer = periodLength.text; + int? intValue = int.tryParse(answer); + + if (intValue != null && intValue >= 1 && intValue <= 12) { + Get.to( + () => const SecondQuestion(), + ); + helperController.periodLength.value = int.parse(periodLength.text); + } else { + // Value is outside the valid range + Fluttertoast.showToast( + msg: 'Value must be between 1 to 12 days.', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0, + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Menstrual Cycle Tracker', + ), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Container( + width: double.infinity, + decoration: const BoxDecoration( + color: Color(0xFF383838), // Set the background color + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.0), + topRight: Radius.circular(12.0), + ), + ), + child: Column( + children: [ + const SizedBox( + height: 64, + ), + Image.asset( + 'assets/image/cycle_time.png', + height: 64, + width: 64, + ), + const SizedBox( + height: 31, + ), + const Text( + "How long do your periods usually last?", + style: TextStyle(fontSize: 18), + ), + const SizedBox( + height: 20, + ), + Container( + width: 147, + height: 43, + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: Center( + child: showTextField + ? GestureDetector( + onTap: () { + setState(() { + showTextField = !showTextField; + }); + }, + child: const Text( + 'Period Length', + style: TextStyle( + fontSize: 14, // Adjust the font size as needed + color: Colors.black, + ), + )) + : TextFormField( + //textAlign: TextAlign.center, + autofocus: true, + maxLength: 3, + keyboardType: TextInputType.number, + controller: periodLength, + decoration: const InputDecoration( + border: InputBorder.none, + counterText: '', // Hide the character counter + contentPadding: + EdgeInsets.only(left: 60, right: 10), + ), + style: const TextStyle( + // Adjust the text style as needed + color: Colors.black, + ), + onChanged: (value) { + if (value.isEmpty) { + setState(() { + showTextField = !showTextField; + }); + } + }, + ), + ), + ), + const SizedBox( + height: 5, + ), + const Text( + "Days", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + height: 10, + ), + const Text( + "From the first day of bleeding to the last.", + style: TextStyle(fontSize: 18), + ), + const SizedBox( + height: 100, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + Get.back(); + }, + child: Container( + width: 147, + height: 39, + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: const Center( + child: Text( + "Back", + style: TextStyle(color: Colors.black), + )), + ), + ), + GestureDetector( + onTap: () { + _validateAnswer(); + }, + child: Container( + width: 147, + height: 39, + decoration: ShapeDecoration( + shape: RoundedRectangleBorder( + side: const BorderSide( + width: 1, color: Colors.white), + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: const Center(child: Text("Next")), + ), + ) + ], + ), + ), + SizedBox( + height: 20, + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart b/gsf/lib/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart new file mode 100644 index 0000000..7d80684 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart @@ -0,0 +1,378 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart'; +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import '../../../../api/base_manager.dart'; +import 'StorageService.dart'; + +class HelperMethods extends GetxController { + RxString fertility = "May not be fertile".obs; + Rx fertilityColor = Color(0xFFFFEB3B).obs; + RxString observableDateTime = "15 December".obs; + RxString observableDateTimeOnTrackerHomePage = + DateFormat('dd MMMM').format(DateTime.now()).obs; + Rx updateDateForHomepage = DateTime.now().obs; + + changeObservableDateTimeOnTrackerHomePage(bool front) { + DateTime currentDate = + DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value); +// Set the current year to the parsed date + DateTime updatedDate = DateTime( + DateTime.now().year, + currentDate.month, + currentDate.day, + ); + // Add one day to the current date + + if (front) { + updatedDate = updatedDate.add(Duration(days: 1)); + currentPositionInCycleIndex + 1; + } else { + updatedDate = updatedDate.subtract(Duration(days: 1)); + currentPositionInCycleIndex - 1; + } + +//For HomePage + updateDateForHomepage.value = updatedDate; + // Format the updated date and update the observable + observableDateTimeOnTrackerHomePage.value = + DateFormat('dd MMMM').format(updatedDate); + calculateOutOfDays(); + } + + updateFertility(String value) { + fertility.value = value; + } + + // Method to format DateTime as "dd MMMM" (e.g., "15 December") + formatDateTime(DateTime dateTime) { + observableDateTime.value = DateFormat('dd MMMM').format(dateTime); + } + + RxBool showPeriodCycleText = true.obs; + RxString formattedDay = "".obs; + + // Method to format DateTime as "dd" for periodCycle 1/22 on overview page + formatDateTime2(DateTime dateTime) { + formattedDay.value = DateFormat('dd').format(dateTime); + if (int.parse(formattedDay.value) > currentPeriodCycle.value) { + showPeriodCycleText.value = false; + } else { + showPeriodCycleText.value = true; + } + } + + //Period calculation + + Rx firstPeriodDate = Rx(null); + RxInt periodCycleLength = RxInt(0); + RxInt periodLength = RxInt(0); + RxList predictedDate = [].obs; + RxList pickerdateRange = [].obs; + +//---------++++++++++-------------- +//Other days calculation + + RxList fertileDates = [].obs; + RxList ovulatingDate = [].obs; + //RxList notfertilityDates = [].obs; + List periodCycleLengthList = []; + RxBool isLoading = true.obs; +// -----------+++++++++++++----------- + calculateFirstTime() async { + predictedDate.add( + firstPeriodDate.value!.add(Duration(days: periodCycleLength.value))); + + pickerdateRange.add(PickerDateRange(firstPeriodDate.value, + firstPeriodDate.value!.add(Duration(days: periodLength.value - 1)))); + periodCycleLengthList.add(periodCycleLength.value); + if (periodCycleLength.value > 21) { + ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14))); + } + List> dateMaps = []; + // Iterate through selectedRanges and add each PickerDateRange to the list of maps + for (PickerDateRange range in pickerdateRange.value) { + Map dateMap = { + "start": range.startDate ?? DateTime.now(), + "end": range.endDate ?? DateTime.now(), + }; + dateMaps.add(dateMap); + } + var updata = { + "predicted_dates": predictedDate.value.toString(), + "fertile_dates": fertileDates.value.toString(), + "ovulating_dates": ovulatingDate.value.toString(), + "pickerdateRange": dateMaps.toString(), + "period_cycle_length": periodCycleLengthList.first + }; + final resp = await StoringDates().storeAllList(updata); + if (resp.status == ResponseStatus.SUCCESS) { + Future.delayed(const Duration(seconds: 2), () { + isLoading.value = false; + }); + StorageService().storeinitialSetup(); + } + } + + // reCalculateFromApi() { + // predictedDate.add( + // firstPeriodDate.value!.add(Duration(days: periodCycleLength.value))); + + // pickerdateRange.add(PickerDateRange(firstPeriodDate.value, + // firstPeriodDate.value!.add(Duration(days: periodLength.value - 1)))); + // periodCycleLengthList.add(periodCycleLength.value); + // if (periodCycleLength.value > 21) { + // ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14))); + // } + // } + + recalculate() async { + List data = calculatePeriodCycleLength(); + predictedDate.clear(); + ovulatingDate.clear(); + for (var i = 0; i < pickerdateRange.length; i++) { + predictedDate + .add(pickerdateRange[i].startDate!.add(Duration(days: data[i]))); + if (periodCycleLength.value > 21) { + ovulatingDate + .add(pickerdateRange[i].startDate!.add(const Duration(days: 14))); + } + } + List> dateMaps = []; + // Iterate through selectedRanges and add each PickerDateRange to the list of maps + for (PickerDateRange range in pickerdateRange.value) { + Map dateMap = { + "start": range.startDate ?? DateTime.now(), + "end": range.endDate ?? DateTime.now(), + }; + dateMaps.add(dateMap); + } + var updata = { + "predicted_dates": predictedDate.value.toString(), + "fertile_dates": fertileDates.value.toString(), + "ovulating_dates": ovulatingDate.value.toString(), + "pickerdateRange": dateMaps.toString(), + "period_cycle_length": periodCycleLengthList.first + }; + + //await StoringDates().storeAllList(updata); + isLoading.value = true; + final resp = await StoringDates().storeAllList(updata); + if (resp.status == ResponseStatus.SUCCESS) { + Future.delayed(const Duration(seconds: 1), () { + isLoading.value = false; + }); + StorageService().storeinitialSetup(); + } + getLast5PeriodDates(); + } + + List calculatePeriodCycleLength() { + if (pickerdateRange.length >= 2) { + // int totalPeriodCycleLength = 0; + // // Clear all elements except the first one + if (periodCycleLengthList.length > 1) { + periodCycleLengthList.removeRange(1, periodCycleLengthList.length); + } + pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!)); + // Calculate the sum of period cycle lengths + for (int i = 0; i < pickerdateRange.length - 1; i++) { + DateTime? currentStartDate = pickerdateRange[i].startDate; + DateTime? nextStartDate = pickerdateRange[i + 1].startDate; + + // Calculate the difference in days and add it to the list + int periodCycleLength = + nextStartDate!.difference(currentStartDate!).inDays; + periodCycleLengthList.add(periodCycleLength); + } + + // // Calculate the average period cycle length + // int averagePeriodCycleLength = + // totalPeriodCycleLength ~/ (pickerdateRange.length - 1); + } + return periodCycleLengthList; + + // avg end ++++++++--------+++++ + // if (pickerdateRange.length >= 2) { + // pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!)); + // DateTime? secondLastStartDate = + // pickerdateRange[pickerdateRange.length - 2].startDate; + // DateTime? lastStartDate = pickerdateRange.last.startDate; + + // // Calculate the period cycle length in days + // int periodCycleLength = + // lastStartDate!.difference(secondLastStartDate!).inDays; + + // print("calculated period cycle length is $periodCycleLength"); + // // Clear all elements except the first one + // if (periodCycleLengthList.length > 1) { + // periodCycleLengthList.removeRange(1, periodCycleLengthList.length); + // } + // periodCycleLengthList.add(periodCycleLength); + // } + // return periodCycleLengthList; + } + + Rx predictedPeriodCycleForHomePage = Rx(null); + // RxInt indexOfCurrentPeriodCycle = 0.obs; + int calculatePeriodCycle() { + DateTime currentDate = DateTime.now(); + List data = calculatePeriodCycleLength(); + + int index = predictedDate + .indexWhere((date) => date != null && date.isAfter(currentDate)); + if (index >= 0) { + predictedPeriodCycleForHomePage.value = predictedDate[index]; + //indexOfCurrentPeriodCycle.value = index; + return data[index]; + } else { + return 99999; + } + } + + RxInt currentPeriodCycle = 0.obs; + RxInt outOfDays = 0.obs; + + calculateOutOfDays() { + int result = calculatePeriodCycle(); + if (result != 99999) { + currentPeriodCycle.value = result; + triggerManipulation(); + disabledNext = false.obs; + // showNext = true.obs; + // showPrev = true.obs; + } else { + showNext = false.obs; + showPrev = false.obs; + disabledNext = true.obs; + } + update(); + print("calculateOutOfDays: ${currentPeriodCycle.value} "); + } + + RxBool showNext = true.obs; + RxBool showPrev = true.obs; + RxBool endOfCycle = true.obs; + RxBool disabledNext = false.obs; + + triggerManipulation() { + if (currentPositionInCycleIndex.value == currentPeriodCycle.value) { + showNext.value = false; + endOfCycle.value = false; + } else if (currentPositionInCycleIndex.value == 0) { + showPrev.value = false; + } else { + showNext.value = true; + showPrev.value = true; + endOfCycle.value = true; + } + } + +//for changing color of centre calendar icon + RxList allDatesList = [].obs; + + calculatePeriodDateForCalender() { + allDatesList = generateAllDates(pickerdateRange); + } + + RxList generateAllDates(RxList ranges) { + RxList allDates = [].obs; + + for (var range in ranges) { + DateTime currentDate = range.startDate!; + while (currentDate.isBefore(range.endDate!) || + currentDate.isAtSameMomentAs(range.endDate!)) { + allDates.add(currentDate); + currentDate = currentDate.add(const Duration(days: 1)); + } + } + + return allDates; + } + + storePredictedDateFromApi(List dateStrings) { + List predictedDates = + dateStrings.map((dateString) => DateTime.parse(dateString)).toList(); + + predictedDate.assignAll(predictedDates); + + print("Predicted Dates: ${helperController.predictedDate.value}"); + } + + storeOvulatingDateFromApi(List dateStrings) { + // Convert the List of strings into a List + List ovulatingDate1 = + dateStrings.map((dateString) => DateTime.parse(dateString)).toList(); + ovulatingDate.value = ovulatingDate1; + } + + storeFirstPeriodDate() { + helperController.firstPeriodDate.value = pickerdateRange.first.startDate; + } + + storePeriodCycles(response) { + periodCycleLengthList.add(response); + + periodCycleLength.value = response; + } + + List last5startDates = []; + + getLast5PeriodDates() { +// Calculate the number of elements to consider (minimum between 5 and the list length) + int elementsToConsider = + pickerdateRange.length < 5 ? pickerdateRange.length : 5; + last5startDates.clear(); +// Extract start dates from the last elementsToConsider ranges + for (int i = pickerdateRange.length - elementsToConsider; + i < pickerdateRange.length; + i++) { + last5startDates.add(pickerdateRange[i].startDate!); + } + +// Now, startDates contains the last elementsToConsider start dates + print("Start Dates: $last5startDates"); + } + + RxInt currentPositionInCycleIndex = 0.obs; + + calculateCurrentPositionInCycle(DateTime valueFromOverview) { + List dateList = generateDateList( + pickerdateRange.last.startDate!, + helperController.predictedPeriodCycleForHomePage.value ?? + DateTime.now()); +// Search date which was visible on Homepage Inside circle + // DateTime currentDate1 = + // DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value); + +// //Search date which is in overview page -> Period cycle: +// DateTime currentDate1 = +// DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value); +// // Set the current year to the parsed date +// DateTime updatedDate = DateTime( +// DateTime.now().year, +// currentDate1.month, +// currentDate1.day, +// ); + currentPositionInCycleIndex.value = dateList.indexOf(valueFromOverview); + + if (currentPositionInCycleIndex.value == -1) { + showPeriodCycleText.value = false; + } + } + + List generateDateList(DateTime startDate, DateTime endDate) { + List dateList = []; + dateList.add(startDate); + + while (startDate.isBefore(endDate)) { + startDate = startDate.add(Duration(days: 1)); + dateList.add(startDate); + } + + return dateList; + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/Helper/StorageService.dart b/gsf/lib/views/pages/MenstrualCycleTracker/Helper/StorageService.dart new file mode 100644 index 0000000..5338f97 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/Helper/StorageService.dart @@ -0,0 +1,51 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +class StorageService { + static final StorageService _instance = StorageService._internal(); + + StorageService._internal(); + + factory StorageService() { + return _instance; + } + + storeinitialSetup() { + GetStorage().write('initialsetup', true); + } + + bool readinitialSetup() { + return GetStorage().read('initialsetup') ?? false; + } + + void savePredictedDate(RxList predictedDate) { + GetStorage().write('predictedDate', predictedDate); + } + + RxList readPredictedDate() { + return (GetStorage().read('predictedDate') ?? []).obs + as RxList; + } + + void savePickerDateRange(RxList pickerdateRange) { + GetStorage().write( + 'pickerdateRange', + pickerdateRange.map((item) => item).toList(), + ); + } + + RxList readPickerDateRange() { + return (GetStorage().read('predictedDate') ?? []).obs + as RxList; + // return (GetStorage().read('pickerdateRange') ?? []) + // .map((item) { + // return PickerDateRange( + // DateTime.parse(item['startDate']), + // DateTime.parse(item['endDate']), + // ); + // }) + // .toList() + // .obs; + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/OverviewPage.dart b/gsf/lib/views/pages/MenstrualCycleTracker/OverviewPage.dart new file mode 100644 index 0000000..6bb4292 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/OverviewPage.dart @@ -0,0 +1,454 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import 'Helper/StorageService.dart'; +import 'viewModel/StoringDates.dart'; + +class OverviewPage extends StatefulWidget { + const OverviewPage({super.key}); + + @override + State createState() => _OverviewPageState(); +} + +class _OverviewPageState extends State { + final periodLength = TextEditingController(); + bool showTextField = false; + final dateController = DateRangePickerController(); + final ScrollController myscrollController = ScrollController(); + + bool dayView = true; + + void _changeFertilityFromDate(DateTime dateReceived) { + if (allDates.contains(dateReceived)) { + helperController.fertility.value = "Period Date"; + helperController.fertilityColor.value = const Color(0xFFE24747); + } + // else if (fertileDates.contains(dateReceived)) { + // helperController.fertility.value = "Fertile"; + // helperController.fertilityColor.value = const Color(0xFF4CAF50); + // } + else if (helperController.ovulatingDate.contains(dateReceived)) { + helperController.fertility.value = "Ovulating"; + helperController.fertilityColor.value = const Color(0xFF9C27B0); + } + // else if (notFertileDates.contains(dateReceived)) { + // helperController.fertility.value = "Not Fertile"; + // helperController.fertilityColor.value = const Color(0xFFFFDB10); + // } + else if (helperController.predictedDate.contains(dateReceived)) { + helperController.fertility.value = "Predicted Period Date"; + helperController.fertilityColor.value = const Color(0xFFF44336); + } else { + helperController.fertility.value = ""; + helperController.fertilityColor.value = const Color(0x00000000); + } + } + + formateDate() { + helperController.observableDateTime.value = + DateFormat('dd MMMM').format(DateTime.now()); + } + + List allDates = []; + calculatePeriodDateForCalender() { + allDates = generateAllDates(helperController.pickerdateRange); + } + + List generateAllDates(List ranges) { + List allDates = []; + + for (var range in ranges) { + DateTime currentDate = range.startDate!; + while (currentDate.isBefore(range.endDate!) || + currentDate.isAtSameMomentAs(range.endDate!)) { + allDates.add(currentDate); + currentDate = currentDate.add(const Duration(days: 1)); + } + } + + return allDates; + } + + Future? myfuture; + + @override + void initState() { + formateDate(); + calculatePeriodDateForCalender(); + final data = StorageService().readinitialSetup(); + print("pickerRange from storage $data"); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Overview', + ), + ), + body: _buildBody(), + // FutureBuilder( + // future: myfuture, + // builder: (ctx, snapshot) { + // if (snapshot.data == null) { + // return Column( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: const [Center(child: CircularProgressIndicator())], + // ); + // } + // if (snapshot.connectionState == ConnectionState.done) { + // if (snapshot.hasError) { + // return Center( + // child: Text( + // '${snapshot.error} occured', + // style: TextStyle(fontSize: 18), + // ), + // ); + // } + // } + // return + // }, + // ), + ); + } + + _buildBody() { + return SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: dayView + ? SfDateRangePicker( + // allowViewNavigation: false, + + todayHighlightColor: ColorConstants.kPrimaryColor, + // rangeSelectionColor: Color(0xFFE24747), + selectionColor: const Color.fromRGBO(26, 24, 24, 0.882), + selectionTextStyle: const TextStyle(color: Colors.black), + showActionButtons: false, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.month, + cellBuilder: (BuildContext context, + DateRangePickerCellDetails details) { + final DateTime currentDate = details.date; + final DateRangePickerView? currentView = + dateController.view; + + // Check if the current view is set to month and if the current date is in the period cycle dates or ovulation dates + if ((allDates.contains(currentDate))) { + return CircleAvatar( + backgroundColor: ColorConstants.periodsColor, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + details.date.day.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + // } + // } else if (notFertileDates.contains(currentDate)) { + // return Container( + // // width: 30, + // // height: 30, + // decoration: ShapeDecoration( + // color: + // Colors.white.withOpacity(0.2199999988079071), + // shape: const CircleBorder( + // side: BorderSide( + // width: 1, color: Color(0xFFFFDB10)), + // ), + // ), + // child: Center( + // child: Text( + // '${details.date.day}', + // style: const TextStyle(color: Colors.white), + // ), + // ), + // ); + // } else if (fertileDates.contains(currentDate)) { + // return Container( + // // width: 30, + // // height: 30, + // decoration: ShapeDecoration( + // color: + // Colors.white.withOpacity(0.2199999988079071), + // shape: const CircleBorder( + // side: BorderSide( + // width: 1, color: Color(0xFF2AC455)), + // ), + // ), + // child: Center( + // child: Text( + // '${details.date.day}', + // style: const TextStyle(color: Colors.white), + // ), + // ), + // ); + } else if (helperController.ovulatingDate + .contains(currentDate)) { + return Container( + // width: 30, + // height: 30, + decoration: ShapeDecoration( + color: Colors.white.withOpacity(0.2199999988079071), + shape: const CircleBorder( + side: BorderSide( + width: 1, + color: Colors.purple, + ), + ), + ), + child: Center( + child: Text( + '${details.date.day}', + style: const TextStyle(color: Colors.white), + ), + ), + ); + } else if (helperController.predictedDate + .contains(currentDate)) { + return Container( + // width: 30, + // height: 30, + decoration: ShapeDecoration( + color: Colors.white.withOpacity(0.2199999988079071), + shape: const CircleBorder( + side: BorderSide( + width: 1, + color: Colors.red, + ), + ), + ), + child: Center( + child: Text( + '${details.date.day}', + style: const TextStyle(color: Colors.white), + ), + ), + ); + } else { + // Return the default cell for other views + return Container( + alignment: Alignment.center, + child: Text( + details.date.day.toString(), + ), + ); + } + }, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.single, + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + _changeFertilityFromDate(args.value); + helperController.formatDateTime(args.value); + helperController.formatDateTime2(args.value); + helperController.calculateCurrentPositionInCycle(args.value); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + + if (_visibleView != DateRangePickerView.month) { + setState(() { + dayView = false; + }); + } + }, + ) + : SfDateRangePicker( + showActionButtons: true, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.year, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.range, + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + + if (_visibleView == DateRangePickerView.month) { + setState(() { + dayView = true; + }); + } + }, + ), + ), + Container( + width: double.infinity, + padding: const EdgeInsets.all(23), + decoration: ShapeDecoration( + color: const Color(0xFF383838), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Obx( + () => Text(helperController.observableDateTime.value), + ), + const SizedBox( + height: 5, + ), + Obx(() => helperController.showPeriodCycleText.value + ? Text( + "Period Cycle: ${helperController.currentPositionInCycleIndex.value}/${helperController.currentPeriodCycle}") + : const Text("")), + const SizedBox( + height: 15, + ), + Row( + children: [ + Obx( + () => CircleAvatar( + backgroundColor: helperController + .fertilityColor.value, // Colors.yellow, + radius: 5, + ), + ), + const SizedBox( + width: 10, + ), + Obx( + () => Padding( + padding: const EdgeInsets.only(top: 10), + child: Text( + helperController.fertility.value, + style: const TextStyle( + color: Color(0xFFE75050), + fontSize: 16, + fontWeight: FontWeight.w400, + decoration: TextDecoration.underline, + height: 0.14, + letterSpacing: 0.53, + ), + ), + ), + ) + ], + ), + const SizedBox( + height: 20, + ), + Row( + children: [ + SvgPicture.asset('assets/image/IconBookMCT.svg'), + const SizedBox( + width: 10, + ), + const Text("Last 5 period dates"), + ], + ), + const SizedBox( + height: 10, + ), + Container( + width: double.infinity, + height: 130, + decoration: ShapeDecoration( + color: Colors.black.withOpacity(0.4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Column( + children: [ + SizedBox( + height: 125, + child: Scrollbar( + controller: myscrollController, + thumbVisibility: true, + child: ListView.separated( + controller: myscrollController, + shrinkWrap: true, + itemCount: helperController.last5startDates + .toSet() + .toList() + .length, + itemBuilder: (context, index) { + // Reverse the order of items for correct rendering + int reversedIndex = + helperController.last5startDates.length - + 1 - + index; + String formattedDate = DateFormat('d MMMM y') + .format(helperController + .last5startDates[reversedIndex]); + return Container( + padding: const EdgeInsets.only(top: 5), + decoration: const BoxDecoration(), + child: Row( + children: [ + const SizedBox( + width: 10, + ), + const Text( + "•", + style: TextStyle(fontSize: 20), + ), + const SizedBox( + width: 5, + ), + Text( + formattedDate, + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return const Divider(); + }, + ), + ), + ), + ], + ), + ) + ], + ), + ) + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/PeriodCalendarWidget.dart b/gsf/lib/views/pages/MenstrualCycleTracker/PeriodCalendarWidget.dart new file mode 100644 index 0000000..3d2dc1f --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/PeriodCalendarWidget.dart @@ -0,0 +1,123 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +class PeriodCalendar extends StatefulWidget { + const PeriodCalendar({super.key}); + + @override + State createState() => _PeriodCalendarState(); +} + +class _PeriodCalendarState extends State { + final List periodCycleDates = [ + DateTime(2023, 12, 5), + DateTime(2023, 12, 10), + // Add more period cycle dates as needed + ]; + + final List ovulationDates = [ + DateTime(2023, 12, 8), + DateTime(2023, 12, 15), + // Add more ovulation dates as needed + ]; + bool dayView = true; + final dateController = DateRangePickerController(); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Menstrual Cycle Tracker'), + ), + body: SizedBox( + width: double.infinity, + height: 300, + child: dayView + ? SfDateRangePicker( + showActionButtons: true, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.month, + cellBuilder: (BuildContext context, + DateRangePickerCellDetails details) { + final DateTime currentDate = details.date; + final DateRangePickerView? currentView = + dateController.view; + + // Check if the current view is set to month and if the current date is in the period cycle dates or ovulation dates + if ((periodCycleDates.contains(currentDate) || + ovulationDates.contains(currentDate))) { + return CircleAvatar( + backgroundColor: Colors + .red, // You can customize the color based on your logic + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + details.date.day.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } else { + // Return the default cell for other views + return Container( + alignment: Alignment.center, + child: Text( + details.date.day.toString(), + ), + ); + } + }, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.range, + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + + if (_visibleView != DateRangePickerView.month) { + setState(() { + dayView = false; + }); + } + }, + ) + : SfDateRangePicker( + showActionButtons: true, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.year, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.range, + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + }, + onViewChanged: (DateRangePickerViewChangedArgs args) { + final DateRangePickerView _visibleView = args.view; + + if (_visibleView == DateRangePickerView.month) { + setState(() { + dayView = true; + }); + } + }, + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/PeriodSelection.dart b/gsf/lib/views/pages/MenstrualCycleTracker/PeriodSelection.dart new file mode 100644 index 0000000..c628e57 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/PeriodSelection.dart @@ -0,0 +1,164 @@ +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/FirstQuestion.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/SecondQuestion.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +class PeriodSelection extends StatefulWidget { + const PeriodSelection({super.key}); + + @override + State createState() => _PeriodSelectionState(); +} + +class _PeriodSelectionState extends State { + final periodLength = TextEditingController(); + bool showTextField = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Menstrual Cycle Tracker', + ), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Container( + width: double.infinity, + decoration: const BoxDecoration( + color: Color(0xFF383838), // Set the background color + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.0), + topRight: Radius.circular(12.0), + ), + ), + child: Column( + children: [ + const SizedBox( + height: 64, + ), + Image.asset( + 'assets/image/cycle_time.png', + height: 64, + width: 64, + ), + const SizedBox( + height: 31, + ), + const Text( + "When was the first day of your last period?", + style: TextStyle(fontSize: 18), + ), + const SizedBox( + height: 20, + ), + SfDateRangePicker( + selectionColor: ColorConstants.periodsColor, + todayHighlightColor: ColorConstants.kPrimaryColor, + showActionButtons: true, + showNavigationArrow: true, + initialSelectedDate: DateTime.now(), + view: DateRangePickerView.month, + monthCellStyle: const DateRangePickerMonthCellStyle( + todayTextStyle: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + selectionMode: DateRangePickerSelectionMode.single, + maxDate: DateTime.now(), + onSelectionChanged: + (DateRangePickerSelectionChangedArgs args) { + print("selected date is :- ${args.value} "); + helperController.firstPeriodDate.value = args.value; + }, + onSubmit: (p0) { + DateTime selectedDate = + (p0 as DateTime).toLocal(); // Convert to local time + + // Set time to 00:00:00.000 + DateTime dateWithMidnight = DateTime( + selectedDate.year, + selectedDate.month, + selectedDate.day, + ); + + helperController.firstPeriodDate.value = dateWithMidnight; + print( + "controller value is ${helperController.firstPeriodDate.value}"); + Get.to(() => FirstQuestion()); + }, + onCancel: () { + Get.back(); + }, + ), + const SizedBox( + height: 200, + ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 15), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // GestureDetector( + // onTap: () { + // Get.back(); + // }, + // child: Container( + // width: 147, + // height: 39, + // decoration: ShapeDecoration( + // color: const Color(0xFFBBF046), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(25.50), + // ), + // ), + // child: const Center( + // child: Text( + // "Back", + // style: TextStyle(color: Colors.black), + // )), + // ), + // ), + // GestureDetector( + // onTap: () { + // Get.to( + // () => const SecondQuestion(), + // ); + // }, + // child: Container( + // width: 147, + // height: 39, + // decoration: ShapeDecoration( + // shape: RoundedRectangleBorder( + // side: const BorderSide( + // width: 1, color: Colors.white), + // borderRadius: BorderRadius.circular(25.50), + // ), + // ), + // child: const Center(child: Text("Next")), + // ), + // ) + // ], + // ), + // ), + // const SizedBox( + // height: 20, + // ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/SecondQuestion.dart b/gsf/lib/views/pages/MenstrualCycleTracker/SecondQuestion.dart new file mode 100644 index 0000000..6fa8add --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/SecondQuestion.dart @@ -0,0 +1,210 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/TrackerHomePage.dart'; + +import 'viewModel/StoringDates.dart'; + +class SecondQuestion extends StatefulWidget { + const SecondQuestion({super.key}); + + @override + State createState() => _SecondQuestionState(); +} + +class _SecondQuestionState extends State { + final periodCycleLength = TextEditingController(); + bool showTextField = false; + + _validateAnswer() { + String answer = periodCycleLength.text; + int? intValue = int.tryParse(answer); + + if (intValue != null && intValue >= 21 && intValue <= 100) { + helperController.periodCycleLength.value = + int.parse(periodCycleLength.text); + Get.to(() => TrackerHomePage()); + } else { + // Value is outside the valid range + Fluttertoast.showToast( + msg: 'Value must be between 21 to 100 days.', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0, + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Menstrual Cycle Tracker', + ), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Container( + width: double.infinity, + decoration: const BoxDecoration( + color: Color(0xFF383838), // Set the background color + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.0), + topRight: Radius.circular(12.0), + ), + ), + child: Column( + children: [ + const SizedBox( + height: 64, + ), + Image.asset( + 'assets/image/cycle_time.png', + height: 64, + width: 64, + ), + const SizedBox( + height: 31, + ), + const Text( + "How long do your Cycle usually last?", + style: TextStyle(fontSize: 18), + ), + const SizedBox( + height: 20, + ), + Container( + width: 147, + height: 43, + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: Center( + child: showTextField + ? GestureDetector( + onTap: () { + setState(() { + showTextField = !showTextField; + }); + }, + child: const Text( + 'Period Length', + style: TextStyle( + fontSize: 14, // Adjust the font size as needed + color: Colors.black, + ), + )) + : TextFormField( + //textAlign: TextAlign.center, + autofocus: true, + maxLength: 3, + keyboardType: TextInputType.number, + controller: periodCycleLength, + decoration: const InputDecoration( + border: InputBorder.none, + counterText: '', // Hide the character counter + contentPadding: + EdgeInsets.only(left: 60, right: 10), + ), + style: const TextStyle( + // Adjust the text style as needed + color: Colors.black, + ), + onChanged: (value) { + if (value.isEmpty) { + setState(() { + showTextField = !showTextField; + }); + } + }, + ), + ), + ), + const SizedBox( + height: 5, + ), + const Text( + "Days", + style: TextStyle(fontSize: 16), + ), + const SizedBox( + height: 10, + ), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 14), + child: Text( + "From the day one period starts until the next one starts.", + style: TextStyle(fontSize: 18), + ), + ), + const SizedBox( + height: 100, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + Get.back(); + }, + child: Container( + width: 147, + height: 39, + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: const Center( + child: Text( + "Back", + style: TextStyle(color: Colors.black), + )), + ), + ), + GestureDetector( + onTap: () { + _validateAnswer(); + }, + child: Container( + width: 147, + height: 39, + decoration: ShapeDecoration( + shape: RoundedRectangleBorder( + side: const BorderSide( + width: 1, color: Colors.white), + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: const Center(child: Text("Next")), + ), + ) + ], + ), + ), + const SizedBox( + height: 20, + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/TrackerHomePage.dart b/gsf/lib/views/pages/MenstrualCycleTracker/TrackerHomePage.dart new file mode 100644 index 0000000..b91bfab --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/TrackerHomePage.dart @@ -0,0 +1,556 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/AddNewPeriod.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/StorageService.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/OverviewPage.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/SecondQuestion.dart'; +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import 'viewModel/StoringDates.dart'; + +class TrackerHomePage extends StatefulWidget { + TrackerHomePage({super.key, this.fromAddNewPeriod}); + + @override + State createState() => _TrackerHomePageState(); + bool? fromAddNewPeriod; +} + +class _TrackerHomePageState extends State { + final periodLength = TextEditingController(); + bool showTextField = false; + Future? myfuture; + bool? isFilled; + @override + void initState() { + isFilled = StorageService().readinitialSetup(); + if (isFilled!) { + } else { + callCalculations(); + } + + // myfuture = StoringDates().getAllList(); + super.initState(); + } + + _validateAnswer() { + String answer = periodLength.text; + int? intValue = int.tryParse(answer); + + if (intValue != null && intValue >= 1 && intValue <= 12) { + Get.to( + () => const SecondQuestion(), + ); + } else { + // Value is outside the valid range + Fluttertoast.showToast( + msg: 'Value must be between 1 to 12 days.', + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0, + ); + } + } + + callCalculations() async { + await helperController.calculateFirstTime(); + await helperController.calculatePeriodDateForCalender(); + await helperController.calculateOutOfDays(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + showLeading: true, + titleHead: 'Menstrual Cycle Tracker', + editProfileFromUserProfile: true, + ), + ), + body: Obx( + () => helperController.isLoading.value + ? const Center(child: CircularProgressIndicator()) + : FutureBuilder( + future: StoringDates().getAllList(), + builder: (ctx, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occurred', + style: TextStyle(fontSize: 18), + ), + ); + } + if (snapshot.connectionState == ConnectionState.done) { + helperController.pickerdateRange = pickerdateRange; + // if (widget.fromAddNewPeriod ?? false) { + // } else { + if (isFilled!) { + helperController.calculatePeriodDateForCalender(); + } + // } + + helperController.observableDateTimeOnTrackerHomePage.value = + DateFormat('dd MMMM').format(DateTime.now()); + // helperController.calculatePeriodDateForCalender(); + // helperController.calculateOutOfDays(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: const TextStyle(fontSize: 18), + ), + ); + } + } + return _buildBody(); + }, + ), + ), + ); + } + + _buildBody() { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Obx(() => + // helperController.endOfCycle.value + // ? + !helperController.disabledNext.value + ? Container( + width: 169, + height: 94, + decoration: ShapeDecoration( + color: const Color(0xFF212121), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8)), + ), + child: Padding( + padding: const EdgeInsets.all(14), + child: Column( + children: [ + Row( + children: [ + Container( + width: 36, + height: 37, + padding: const EdgeInsets.all(5), + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular( + 8)), + ), + child: SvgPicture.asset( + 'assets/image/Icon2MCT.svg'), + ), + const SizedBox( + width: 7, + ), + const Text( + "Next cycle:", + style: TextStyle(fontSize: 16), + ) + ], + ), + const SizedBox( + height: 5, + ), + Obx(() => helperController + .predictedPeriodCycleForHomePage + .value != + null + ? Padding( + padding: + EdgeInsets.only(left: 15), + child: Text( + DateFormat('dd MMMM').format( + helperController + .predictedPeriodCycleForHomePage + .value!), + style: + TextStyle(fontSize: 14), + ), + ) + : const Padding( + padding: + EdgeInsets.only(left: 20), + child: Text( + "Not Tracking", + style: + TextStyle(fontSize: 14), + ), + )) + ], + ), + ), + ) + + //----+++++--- period cycle Container + //Container( + // width: 169, + // height: 94, + // decoration: ShapeDecoration( + // color: const Color(0xFF212121), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8)), + // ), + // child: Padding( + // padding: const EdgeInsets.all(14), + // child: Column( + // children: [ + // Row( + // children: [ + // Container( + // width: 36, + // height: 37, + // padding: const EdgeInsets.all(5), + // decoration: ShapeDecoration( + // color: const Color(0xFFBBF046), + // shape: RoundedRectangleBorder( + // borderRadius: + // BorderRadius.circular(8)), + // ), + // child: SvgPicture.asset( + // 'assets/image/Icon1MCT.svg'), + // ), + // const SizedBox( + // width: 7, + // ), + // const Text( + // "Period cycle:", + // style: TextStyle(fontSize: 16), + // ) + // ], + // ), + // const SizedBox( + // height: 5, + // ), + // Obx(() { + // return Padding( + // padding: + // const EdgeInsets.only(left: 20), + // child: Text( + // " ${helperController.currentPositionInCycleIndex} / ${helperController.currentPeriodCycle.value} days", + // style: const TextStyle(fontSize: 14), + // ), + // ); + // }) + // ], + // ), + // ), + // ) + : Container( + width: 169, + height: 94, + ) + // : + // Container( + // width: 169, + // height: 94, + // ) + ), + Obx(() => !helperController.disabledNext.value + ? Container( + width: 169, + height: 94, + decoration: ShapeDecoration( + color: const Color(0xFF212121), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8)), + ), + child: Padding( + padding: const EdgeInsets.all(14), + child: Column( + children: [ + Row( + children: [ + Container( + width: 36, + height: 37, + padding: const EdgeInsets.all(5), + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(8)), + ), + child: SvgPicture.asset( + 'assets/image/Icon2MCT.svg'), + ), + const SizedBox( + width: 7, + ), + Flexible( + child: const Text( + "Ovulation Date:", + style: TextStyle(fontSize: 16), + ), + ) + ], + ), + const SizedBox( + height: 5, + ), + Obx(() => helperController + .predictedPeriodCycleForHomePage + .value != + null + ? Padding( + padding: EdgeInsets.only(left: 15), + child: Text( + DateFormat('dd MMMM').format( + helperController + .ovulatingDate.last!), + style: TextStyle(fontSize: 14), + ), + ) + : Padding( + padding: EdgeInsets.only(left: 20), + child: Text( + "Not Tracking", + style: TextStyle(fontSize: 14), + ), + )) + ], + ), + ), + ) + : Container( + width: 169, + height: 94, + )) + ], + ), + const SizedBox( + height: 111, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Obx(() => helperController.showPrev.value + ? GestureDetector( + onTap: () { + helperController + .changeObservableDateTimeOnTrackerHomePage( + false); + }, + child: Image.asset( + 'assets/image/Icon3MCT.png', + width: 34, + height: 34, + ), + ) + : helperController.disabledNext.value + ? Image.asset( + 'assets/image/MCT_disabled_prev.png', + width: 34, + height: 34, + ) + : Container( + width: 34, + height: 34, + )), + Stack( + children: [ + Obx( + () { + if (helperController.ovulatingDate.contains( + helperController.updateDateForHomepage.value)) { + return Image.asset( + 'assets/image/MCT_purple_new.png', + width: 156, + height: 156, + ); + } else if (helperController.allDatesList.contains( + helperController.updateDateForHomepage.value)) { + return Image.asset( + 'assets/image/MCT_red_new.png', + width: 156, + height: 156, + ); + } else if (helperController.disabledNext.value) { + return Image.asset( + 'assets/image/MCT_disabled_center_new.png', + width: 156, + height: 156, + ); + } else { + return Image.asset( + 'assets/image/Icon5MCT_new.png', + width: 156, + height: 156, + ); + } + }, + ), + Positioned( + bottom: 85, + right: 40, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Obx( + () => Text( + helperController + .observableDateTimeOnTrackerHomePage + .value, + style: const TextStyle(color: Colors.black), + ), + ), + const SizedBox( + height: 5, + ), + // Container( + // padding: EdgeInsets.all(3.0), // Add padding + // // decoration: BoxDecoration( + // // borderRadius: BorderRadius.circular( + // // 8.0), // Add rounded corners + // // border: Border.all( + // // color: Colors.black, // Border color + // // width: 1.0, // Border width + // // ), + // // ), + // child: Text( + // "Overview", + // style: TextStyle( + // color: Colors.black, + // fontSize: 12, + // ), + // ), + // ) + ], + ), + ), + Positioned( + bottom: 45, + right: 47, + child: InkWell( + onTap: () { + Get.to(() => const OverviewPage()); + }, + child: Text( + "Overview", + style: TextStyle( + color: Color.fromRGBO(0, 0, 0, 1), + fontSize: 14, + ), + ), + ), + ) + ], + ), + Obx(() => helperController.showNext.value + ? GestureDetector( + onTap: () { + helperController + .changeObservableDateTimeOnTrackerHomePage( + true); + }, + child: Image.asset( + 'assets/image/Icon4MCT.png', + width: 34, + height: 34, + ), + ) + : helperController.disabledNext.value + ? Image.asset( + 'assets/image/MCT_disabled_next.png', + width: 34, + height: 34, + ) + : Container( + width: 34, + height: 34, + )) + ], + ), + ), + const SizedBox( + height: 15, + ), + Obx(() => !helperController.endOfCycle.value + ? const Text("Start of new Cycle") + : helperController.disabledNext.value + ? Text("Not tracking") + : const Text("")), + const SizedBox( + height: 80, + ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 15), + // child: GestureDetector( + // onTap: () { + // Get.to(() => const OverviewPage()); + // }, + // child: Container( + // width: double.infinity, + // height: 39, + // decoration: ShapeDecoration( + // color: const Color(0xFFBBF046), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(25.50), + // ), + // ), + // child: const Center( + // child: Text( + // "View Overview", + // style: TextStyle(color: Colors.black), + // ), + // ), + // ), + // ), + // ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: GestureDetector( + onTap: () { + Get.to(() => const AddNewPeriod()); + }, + child: Container( + width: double.infinity, + height: 39, + decoration: ShapeDecoration( + color: const Color(0xFFBBF046), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25.50), + ), + ), + child: const Center( + child: Text( + "Edit Period Date", + style: TextStyle(color: Colors.black), + ), + ), + ), + ), + ) + ], + )), + ); + } +} diff --git a/gsf/lib/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart b/gsf/lib/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart new file mode 100644 index 0000000..ea01673 --- /dev/null +++ b/gsf/lib/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart @@ -0,0 +1,154 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:get/get.dart'; +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/modals/QuizModel.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart'; +import 'package:gsp_app/views/pages/quiz/quiz_home.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; + +import '../../../../api/base_manager.dart'; + +QuizeModel? quizData; +RxList pickerdateRange = [].obs; + +final HelperMethods helperController = Get.put(HelperMethods()); + +class StoringDates { + Future> storeAllList(updata) async { + final response = + await NetworkApi().postApi(url: Endpoints.storeDates, data: updata); + if (response.status == ResponseStatus.SUCCESS) {} + print("$response"); + + return response; + } + + Future> getAllList() async { + final response = await NetworkApi().getApi(Endpoints.getPeriodDates); + + String pickerdateRangeString = response.data['result']['pickerdateRange']; +// Use a regular expression to remove [ and ] from the start and end of the string + // RegExp exp1 = RegExp(r"^\[(.*)\]$"); + // Match? match1 = exp1.firstMatch(pickerdateRangeString); + // String resultString = match1!.group(1)!; + // RegExp exp = RegExp( + // r"PickerDateRange#\w+\(startDate: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}), endDate: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\)"); + // Iterable matches = exp.allMatches(resultString); + + // pickerdateRange.assignAll(matches.map((match) { + // DateTime? startDate = DateTime.tryParse(match.group(1)!); + // DateTime? endDate = DateTime.tryParse(match.group(2)!); + // return PickerDateRange(startDate, endDate); + // })); + +// Custom function -----+++++---- + + List> customParse(String dataString) { + List> result = []; + + // Remove square brackets and curly braces + String contentString = dataString + .replaceAll('[', '') + .replaceAll(']', '') + .replaceAll('{', '') + .replaceAll('}', ''); + + // Split the content into individual key-value pairs + List keyValuePairs = contentString.split(', '); + + // Initialize variables to store the current key and value + String currentKey = ''; + DateTime currentValue = + DateTime(2000); // Replace with a default date if needed + + for (String pair in keyValuePairs) { + // Split each key-value pair into key and value + List parts = pair.split(':'); + + // Extract key and value (removing any leading or trailing whitespaces) + String key = parts[0].trim(); + DateTime value = DateTime.parse(parts[1].trim()); + + // Check if the current key is empty + // If empty, set the current key and value + // If not empty, create a map with the current key and value, and add it to the result list + if (currentKey.isEmpty) { + currentKey = key; + currentValue = value; + } else { + result.add({currentKey: currentValue, key: value}); + currentKey = ''; + } + } + + return result; + } + + List convertToPickerDateRanges( + List> dateMapList) { + List pickerDateRanges = []; + + for (Map dateMap in dateMapList) { + DateTime start = dateMap['start']!; + DateTime end = dateMap['end']!; + + pickerDateRanges.add(PickerDateRange(start, end)); + } + + return pickerDateRanges; + } + +//-----+++++------ +//New logic --------+++++++------ + List> myList = customParse(pickerdateRangeString); + List pickerDateRanges = convertToPickerDateRanges(myList); + + print("converted range is $pickerDateRanges"); + pickerdateRange.value = pickerDateRanges; + helperController.pickerdateRange.value = pickerDateRanges; + +//--------+++++++++++++---------- + // Parse predictedDates + + String predictedDatesString = response.data['result']['predictedDates']; + + predictedDatesString = + predictedDatesString.replaceAll(RegExp(r'[\[\]"]'), ''); + + List dateStrings = predictedDatesString.split(', '); + await helperController.storePredictedDateFromApi(dateStrings); + await helperController + .storePeriodCycles(response.data['result']['period_cycle_length']); + DateTime todayMidnight = + DateTime.now().toLocal(); // Get the current date and time + todayMidnight = DateTime(todayMidnight.year, todayMidnight.month, + todayMidnight.day); // Set time to midnight + + await helperController.calculateCurrentPositionInCycle(todayMidnight); + await helperController.calculateOutOfDays(); + +//--------+++++++++++++---------- + // Parse ovulation dates + + // Get the string representation of predictedDates from the response + String ovulatingDatesString = response.data['result']['ovulatingDates']; + +// Remove square brackets and quotes + ovulatingDatesString = + ovulatingDatesString.replaceAll(RegExp(r'[\[\]"]'), ''); + +// Split the date string into a List of strings + List dateStringsO = ovulatingDatesString.split(', '); + + await helperController.storeOvulatingDateFromApi(dateStringsO); + +//--------+++++++++++++---------- + + await helperController.storeFirstPeriodDate(); + helperController.getLast5PeriodDates(); + return response; + } +} diff --git a/gsf/lib/views/pages/StepCount/HealthApp.dart b/gsf/lib/views/pages/StepCount/HealthApp.dart new file mode 100644 index 0000000..2afe9c6 --- /dev/null +++ b/gsf/lib/views/pages/StepCount/HealthApp.dart @@ -0,0 +1,132 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter/src/widgets/framework.dart'; +// import 'package:flutter/src/widgets/placeholder.dart'; +// import 'package:health/health.dart'; + +// class HealthApp extends StatefulWidget { +// const HealthApp({super.key}); + +// @override +// State createState() => _HealthAppState(); +// } + +// class _HealthAppState extends State { +// List _healthDataList = []; + +// int _nofSteps = 0; + +// /// Fetch steps from the health plugin and show them in the app. +// Future fetchStepData() async { +// int? steps; + +// // get steps for today (i.e., since midnight) +// final now = DateTime.now(); +// final midnight = DateTime(now.year, now.month, now.day); +// // create a HealthFactory for use in the app +// HealthFactory health = HealthFactory(useHealthConnectIfAvailable: true); + +// bool requested = await health.requestAuthorization([HealthDataType.STEPS]); + +// if (requested) { +// try { +// steps = await health.getTotalStepsInInterval(midnight, now); +// } catch (error) { +// print("Caught exception in getTotalStepsInInterval: $error"); +// } + +// print('Total number of steps: $steps'); + +// setState(() { +// // _nofSteps = (steps == null) ? 0 : steps; +// // _state = (steps == null) ? AppState.NO_DATA : AppState.STEPS_READY; +// }); +// } else { +// print("Authorization not granted - error in authorization"); +// // setState(() => _state = AppState.DATA_NOT_FETCHED); +// } +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text("Health"), +// ), +// body: Column( +// children: [ +// TextButton( +// onPressed: () { +// fetchStepData(); +// }, +// child: Text("Fetch steps")) +// ], +// ), +// ); +// } +// } + +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/Stepcounts.dart'; +import 'package:health/health.dart'; + +class calculateStepsFromHealthApp extends GetxController { + RxString finalSteps = RxString(""); // Initialize as an empty string + + Future fetchStepData() async { + int? steps; + + // get steps for today (i.e., since midnight) + final now = DateTime.now(); + final midnight = DateTime(now.year, now.month, now.day); + // create a HealthFactory for use in the app + HealthFactory health = HealthFactory(useHealthConnectIfAvailable: true); + + bool requested = await health.requestAuthorization([HealthDataType.STEPS]); + + if (requested) { + try { + steps = await health.getTotalStepsInInterval(midnight, now); + finalSteps.value = steps?.toString() ?? "0"; + } catch (error) { + print("Caught exception in getTotalStepsInInterval: $error"); + } + + print('Total number of steps: $steps'); + } else { + print("Authorization not granted - error in authorization"); + } + } + + Future storeStepsInDB() async { + Map updata = {"step_count": finalSteps.value}; + StepCounts().storeSteps(updata); + } + + Future fetchStepDataForAndroid() async { + int? steps; + + // get steps for today (i.e., since midnight) + final now = DateTime.now(); + final midnight = DateTime(now.year, now.month, now.day); + // create a HealthFactory for use in the app + HealthFactory health = HealthFactory(useHealthConnectIfAvailable: true); + + bool requested = await health.requestAuthorization([HealthDataType.STEPS]); + // fetch health data from the last 24 hours + List healthData = await health.getHealthDataFromTypes( + now.subtract(Duration(days: 1)), now, [HealthDataType.STEPS]); + + if (requested) { + try { + steps = await health.getTotalStepsInInterval(midnight, now); + finalSteps.value = steps?.toString() ?? "0"; + } catch (error) { + print("Caught exception in getTotalStepsInInterval: $error"); + } + + print('Total number of steps: $steps'); + } else { + print("Authorization not granted - error in authorization"); + } + } +} diff --git a/gsf/lib/views/pages/audio/models/models.dart b/gsf/lib/views/pages/audio/models/models.dart new file mode 100644 index 0000000..b2f00cc --- /dev/null +++ b/gsf/lib/views/pages/audio/models/models.dart @@ -0,0 +1,14 @@ +// Copyright 2023 atulp +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + diff --git a/gsf/lib/views/pages/audio/models/playlist_modal.dart b/gsf/lib/views/pages/audio/models/playlist_modal.dart new file mode 100644 index 0000000..576cf30 --- /dev/null +++ b/gsf/lib/views/pages/audio/models/playlist_modal.dart @@ -0,0 +1,61 @@ +import 'song_modal.dart'; + +class PlayList { + final String titel; + final List songs; + final String imgUrl; + + PlayList({ + required this.titel, + required this.songs, + required this.imgUrl, + }); + + static List playlist = [ + PlayList( + titel: 'Hip-Hop', + songs: Song.songs, + imgUrl: 'assets/image/1.png', + ), + PlayList( + titel: 'Rock-Roll', + songs: Song.songs, + imgUrl: 'assets/image/2.png', + ), + PlayList( + titel: 'Hip1-Hop1', + songs: Song.songs, + imgUrl: 'assets/image/3.png', + ), + PlayList( + titel: 'Hip-Hop', + songs: Song.songs, + imgUrl: 'assets/image/1.png', + ), + PlayList( + titel: 'Rock-Roll', + songs: Song.songs, + imgUrl: 'assets/image/2.png', + ), + PlayList( + titel: 'Hip1-Hop1', + songs: Song.songs, + imgUrl: 'assets/image/3.png', + ), + PlayList( + titel: 'Hip-Hop', + songs: Song.songs, + imgUrl: 'assets/image/1.png', + ), + PlayList( + titel: 'Rock-Roll', + songs: Song.songs, + imgUrl: 'assets/image/2.png', + ), + PlayList( + titel: 'Hip1-Hop1', + songs: Song.songs, + imgUrl: 'assets/image/3.png', + ), + ]; +} diff --git a/gsf/lib/views/pages/audio/models/song_modal.dart b/gsf/lib/views/pages/audio/models/song_modal.dart new file mode 100644 index 0000000..0faed25 --- /dev/null +++ b/gsf/lib/views/pages/audio/models/song_modal.dart @@ -0,0 +1,34 @@ +class Song { + final String title; + final String description; + final String url; + final String coverUrl; + + Song({ + required this.title, + required this.description, + required this.url, + required this.coverUrl, + }); + + static List songs = [ + Song( + title: 'Glass', + description: 'Glass', + url: 'assets/audio/nature.mp3', + coverUrl: 'assets/audio/audio_bg.jpg', + ), + Song( + title: 'Glass1', + description: 'Glass1', + url: 'assets/audio/nature.mp3', + coverUrl: 'assets/audio/audio_bg.jpg', + ), + Song( + title: 'Glass', + description: 'Glass', + url: 'assets/audio/nature.mp3', + coverUrl: 'assets/audio/audio_bg.jpg', + ), + ]; +} diff --git a/gsf/lib/views/pages/audio/screen/home_screen.dart b/gsf/lib/views/pages/audio/screen/home_screen.dart new file mode 100644 index 0000000..432d96b --- /dev/null +++ b/gsf/lib/views/pages/audio/screen/home_screen.dart @@ -0,0 +1,93 @@ +// ignore_for_file: prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/pages/audio/models/playlist_modal.dart'; + +import '../models/song_modal.dart'; +import '../widget/playlist_card.dart'; +import '../widget/song_card.dart'; + +class TestAudioPlayer extends StatefulWidget { + const TestAudioPlayer({Key? key}) : super(key: key); + + @override + State createState() => _TestAudioPlayerState(); +} + +class _TestAudioPlayerState extends State { + @override + Widget build(BuildContext context) { + List songs = Song.songs; + List playlists = PlayList.playlist; + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.deepPurple.shade800.withOpacity(0.8), + Colors.deepPurple.shade200.withOpacity(0.8), + ])), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + elevation: 0, + backgroundColor: Colors.transparent, + ), + body: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Welcome', + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox(height: 5), + Text( + 'Enjoy You\'r Favorite Music', + style: Theme.of(context).textTheme.headline6!, + ), + const SizedBox(height: 20), + SizedBox( + height: 200, + child: ListView.builder( + itemCount: songs.length, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => SongsCard( + song: songs[index], + ), + ), + ), + const SizedBox(height: 20), + Row( + children: [ + Text( + 'Trending Music', + style: Theme.of(context).textTheme.headline6, + ) + ], + ), + ListView.builder( + itemCount: playlists.length, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only( + top: 20, + ), + shrinkWrap: true, + itemBuilder: (context, index) => + PlaylistCard(playlistss: playlists[index]), + ) + ], + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/audio/screen/playlist_screen.dart b/gsf/lib/views/pages/audio/screen/playlist_screen.dart new file mode 100644 index 0000000..b2f00cc --- /dev/null +++ b/gsf/lib/views/pages/audio/screen/playlist_screen.dart @@ -0,0 +1,14 @@ +// Copyright 2023 atulp +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + diff --git a/gsf/lib/views/pages/audio/screen/screens.dart b/gsf/lib/views/pages/audio/screen/screens.dart new file mode 100644 index 0000000..b2f00cc --- /dev/null +++ b/gsf/lib/views/pages/audio/screen/screens.dart @@ -0,0 +1,14 @@ +// Copyright 2023 atulp +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + diff --git a/gsf/lib/views/pages/audio/screen/song_screen.dart b/gsf/lib/views/pages/audio/screen/song_screen.dart new file mode 100644 index 0000000..dc2e522 --- /dev/null +++ b/gsf/lib/views/pages/audio/screen/song_screen.dart @@ -0,0 +1,120 @@ +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/pages/audio/models/song_modal.dart'; +import 'package:gsp_app/views/pages/audio/widget/seekbar.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:rxdart/rxdart.dart' as rxdart; + +class SongsScreen extends StatefulWidget { + const SongsScreen({Key? key}) : super(key: key); + + @override + State createState() => _SongsScreenState(); +} + +class _SongsScreenState extends State { + AudioPlayer audioPlayer = AudioPlayer(); + Song song = Song.songs[0]; + @override + void initState() { + super.initState(); + audioPlayer.setAudioSource( + ConcatenatingAudioSource( + children: [ + AudioSource.uri( + Uri.parse('assets:///${song.url}'), + ), + ], + ), + ); + } + + @override + void dispose() { + audioPlayer.dispose(); + super.dispose(); + } + + Stream get _seekBarDataStream => + rxdart.Rx.combineLatest2( + audioPlayer.positionStream, + audioPlayer.durationStream, + (Duration position, Duration? duration) { + return SeekBarData( + position, + duration ?? Duration.zero, + ); + }, + ); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + ), + extendBodyBehindAppBar: true, + body: Stack( + fit: StackFit.expand, + children: [ + Image.asset( + song.coverUrl, + fit: BoxFit.cover, + ), + const _BackgroundFilter(), + StreamBuilder( + stream: _seekBarDataStream, + builder: (context, snapdata) { + final positionData = snapdata.data; + return SeekBar( + position: positionData?.duration ?? Duration.zero, + duration: positionData?.duration ?? Duration.zero, + onChangedEnd: audioPlayer.seek, + ); + }) + ], + ), + ); + } +} + +class _BackgroundFilter extends StatelessWidget { + const _BackgroundFilter({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return ShaderMask( + shaderCallback: (rect) { + return LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.white, + Colors.white.withOpacity(0.5), + Colors.white.withOpacity(0.0), + ], + stops: const [ + 0.0, + 0.4, + 0.6 + ]).createShader(rect); + }, + blendMode: BlendMode.dstOut, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.deepPurple.shade200, + Colors.deepPurple.shade800, + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/audio/widget/playlist_card.dart b/gsf/lib/views/pages/audio/widget/playlist_card.dart new file mode 100644 index 0000000..4696a53 --- /dev/null +++ b/gsf/lib/views/pages/audio/widget/playlist_card.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../models/playlist_modal.dart'; + +class PlaylistCard extends StatelessWidget { + const PlaylistCard({ + Key? key, + required this.playlistss, + }) : super(key: key); + + final PlayList playlistss; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + Get.toNamed('/', arguments: playlistss); + }, + child: Padding( + padding: const EdgeInsets.only(bottom: 10.0), + child: Container( + height: 70, + decoration: BoxDecoration( + color: Colors.deepPurple.shade800.withOpacity(0.5), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset(playlistss.imgUrl)), + const SizedBox(width: 10), + Text( + playlistss.titel, + ), + const Spacer(), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.play_circle, + size: 30, + color: Colors.white, + )), + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/audio/widget/seekbar.dart b/gsf/lib/views/pages/audio/widget/seekbar.dart new file mode 100644 index 0000000..ae4575b --- /dev/null +++ b/gsf/lib/views/pages/audio/widget/seekbar.dart @@ -0,0 +1,89 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class SeekBarData { + final Duration position; + final Duration duration; + + SeekBarData( + this.position, + this.duration, + ); +} + +class SeekBar extends StatefulWidget { + const SeekBar({ + Key? key, + required this.position, + required this.duration, + this.onChanged, + this.onChangedEnd, + }) : super(key: key); + + final Duration position; + final Duration duration; + final ValueChanged? onChanged; + final ValueChanged? onChangedEnd; + + @override + State createState() => _SeekBarState(); +} + +class _SeekBarState extends State { + double? _dragValue; + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: SliderTheme( + data: SliderTheme.of(context).copyWith( + trackHeight: 4, + thumbShape: const RoundSliderThumbShape( + disabledThumbRadius: 4, + enabledThumbRadius: 4, + ), + overlayShape: const RoundSliderOverlayShape( + overlayRadius: 10, + ), + activeTrackColor: Colors.white, + inactiveTrackColor: Colors.white.withOpacity(0.3), + thumbColor: Colors.white, + overlayColor: Colors.white, + ), + child: Slider( + min: 0.0, + max: widget.duration.inMilliseconds.toDouble(), + value: min( + _dragValue ?? widget.position.inMilliseconds.toDouble(), + widget.position.inMilliseconds.toDouble(), + ), + onChanged: (value) { + setState(() { + _dragValue = value; + }); + if (widget.onChanged != null) { + widget.onChanged!( + Duration( + milliseconds: value.round(), + ), + ); + } + }, + onChangeEnd: (value) { + if (widget.onChanged != null) { + widget.onChanged!( + Duration( + milliseconds: value.round(), + ), + ); + } + }, + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/audio/widget/song_card.dart b/gsf/lib/views/pages/audio/widget/song_card.dart new file mode 100644 index 0000000..c5c8895 --- /dev/null +++ b/gsf/lib/views/pages/audio/widget/song_card.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../models/song_modal.dart'; + +class SongsCard extends StatelessWidget { + const SongsCard({ + Key? key, + required this.song, + }) : super(key: key); + + final Song song; + + @override + Widget build(BuildContext context) { + return Container( + width: Get.size.width, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + song.coverUrl, + ), + fit: BoxFit.cover, + )), + ); + } +} diff --git a/gsf/lib/views/pages/audio_player/audio_plyer_with_url.dart b/gsf/lib/views/pages/audio_player/audio_plyer_with_url.dart new file mode 100644 index 0000000..6ad74e4 --- /dev/null +++ b/gsf/lib/views/pages/audio_player/audio_plyer_with_url.dart @@ -0,0 +1,171 @@ +// ignore_for_file: prefer_const_constructors + +import 'dart:ui'; + +import 'package:audioplayers/audioplayers.dart'; +import 'package:flutter/material.dart'; + +import '../../theme.dart'; + +class AudioPlayersS extends StatefulWidget { + const AudioPlayersS({Key? key}) : super(key: key); + + @override + State createState() => _AudioPlayersSState(); +} + +class _AudioPlayersSState extends State { + bool isplaying = false; + double value = 0; + + // late AudioPlayer audioPlayer; + final player = AudioPlayer(); + Duration? duration = Duration(seconds: 0); + + void initPlayer() async { + // await player.setSource( + // AssetSource("nature.mp3"), + // ); + await player.setSourceUrl( + "https://dl.espressif.com/dl/audio/ff-16b-2c-44100hz.mp3"); + duration = await player.getDuration(); + } + + @override + void initState() { + super.initState(); + initPlayer(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: Stack( + children: [ + Container( + constraints: const BoxConstraints.expand(), + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/cardio.jpg'), + fit: BoxFit.cover, + ), + ), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 28, sigmaY: 28), + child: Container( + color: ColorConstants.kBlack.withOpacity(0.3), + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Image.asset( + 'assets/image/cardio.jpg', + width: 200, + height: 200, + fit: BoxFit.cover, + alignment: Alignment.topLeft, + ), + ), + SizedBox(height: 20), + Text( + 'Summer Vibes', + style: TextStyle( + fontSize: 35, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 50), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '${(value / 60).floor()}:${(value % 60).floor()}', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + Slider.adaptive( + min: 0, + max: duration!.inSeconds.toDouble(), + value: value, + onChanged: (v) { + setState(() { + value = v; + }); + }, + activeColor: Colors.white, + onChangeEnd: (newValue) async { + setState(() { + value = newValue; + print(newValue); + }); + player.pause(); + await player.seek(Duration(seconds: newValue.toInt())); + // await player.resume(); + }, + ), + Text( + '${duration!.inMinutes}:${duration!.inSeconds % 60}', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ], + ), + SizedBox(height: 50), + Container( + width: 64, + height: 64, + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.circular(100), + border: + Border.all(color: Color.fromARGB(255, 184, 195, 100)), + ), + child: InkWell( + onTap: () async { + if (isplaying) { + await player.pause(); + setState(() { + isplaying = false; + }); + } else { + await player.resume(); + player.onPositionChanged.listen((position) { + setState(() { + value = position.inSeconds.toDouble(); + }); + }); + setState(() { + isplaying = true; + }); + } + }, + child: Icon( + isplaying ? Icons.pause : Icons.play_arrow_rounded, + size: 40, + color: ColorConstants.kWhite, + ), + ), + ) + ], + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/bioMaker/add_scale.dart b/gsf/lib/views/pages/bioMaker/add_scale.dart new file mode 100644 index 0000000..5c345e7 --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/add_scale.dart @@ -0,0 +1,468 @@ +// ignore_for_file: must_be_immutable, prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:lottie/lottie.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import '../../../scale/model/device_type.dart'; +import '../../../scale/page/device_scan_page.dart'; +import '../../../view_model/global_controller.dart'; +import '../../../view_model/home_controller.dart'; +import '../../../view_model/home_page_controller.dart'; +import '../../components/bottom_navigation.dart'; +import '../../components/notification_icon.dart'; +import '../../theme.dart'; +import '../sidebar.dart'; +import '../signIn/sign_in.dart'; +import 'overview_guide.dart'; + +class AddScale extends StatefulWidget { + const AddScale({Key? key}) : super(key: key); + + @override + State createState() => _AddScaleState(); +} + +class _AddScaleState extends State { + final TabsController controller = TabsController(); + HomePageController homePageController = Get.put(HomePageController()); + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + GlobalController globalContoller = Get.find(); + // final brightness = Get.theme.brightness; + return Scaffold( + key: controller.scaffoldKey, + drawer: const AppDrawer(), + appBar: AppBar( + // backgroundColor: ColorConstants.kBlack, + leading: InkWell( + onTap: controller.openDrawer, + child: Padding( + padding: const EdgeInsets.all(8), + child: Obx( + () => Image.asset( + 'assets/image/${!globalContoller.darkMode.value ? 'menu_dark' : 'menu'}.png', + ), + ), + ), + ), + actions: [ + SizedBox( + child: (controller.isLoggedIn) + ? Row( + children: [ + const Padding( + padding: EdgeInsets.all(4.0), + child: NotificationIcon(), + ), + const SizedBox(width: 10), + // Padding( + // padding: const EdgeInsets.all(4), + // child: InkWell( + // splashColor: Colors.transparent, + // onTap: () => Get.to( + // () => const Settings(), + // ), + // child: Icon( + // Icons.settings_outlined, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + // ), + // ), + // const SizedBox(width: 20), + ], + ) + : GestureDetector( + onTap: () => Get.off( + () => const SignIn(), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Image.asset( + 'assets/image/logout.png', + width: 30, + ), + ), + ), + ) + ], + ), + body: StreamBuilder( + stream: FlutterBluePlus.adapterState, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.active && + snapshot.hasData) { + BluetoothAdapterState bluetoothState = snapshot.data!; + if (bluetoothState == BluetoothAdapterState.on || + bluetoothState == BluetoothAdapterState.turningOff) { + return AddScaleScreen(homePageController); + } + if (bluetoothState == BluetoothAdapterState.off || + bluetoothState == BluetoothAdapterState.turningOn) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.bluetooth_disabled, + color: ColorConstants.kPrimaryColor, + size: 82, + ), + const Text( + "Bluetooth is off", + style: TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 18, + fontFamily: "Poppins", + fontWeight: FontWeight.w600, + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Text( + "Bluetooth is need to be turned \non to connect your scale", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + ), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: ColorConstants.kPrimaryColor, + textStyle: const TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + ), + ), + // onPressed: () => const MethodChannel('bluetooth_enable') + // .invokeMethod('customEnable'), + // onPressed: ()async{ + // try { + // if(Platform.isAndroid){ + // await FlutterBluePlus.turnOn(); + // } + // } catch (e) { + // final snackBar = SnackBar(content: Text(prettyException("Error Turning On:", e))); + // GlobalKey().currentState?.showSnackBar(snackBar); + // } + // }, + onPressed: () { + FlutterBluePlus.turnOn(); + }, + child: const Text("Turn On"), + ) + ]), + ); + } + } + return const Center(child: CircularProgressIndicator()); + }, + ), + bottomNavigationBar: const BottomNavigation(), + ); + } + + @override + void dispose() { + super.dispose(); + controller.dispose(); + } +} + +class AddScaleScreen extends StatefulWidget { + const AddScaleScreen(this.homePageController, {Key? key}) : super(key: key); + + final HomePageController homePageController; + + @override + State createState() => _AddScaleScreenState(); +} + +class _AddScaleScreenState extends State { + @override + void initState() { + Future.delayed(Duration.zero, () { + GetStorage().read('showOverviewGuidModal') ?? true + ? overViewModel() + : null; + }); + super.initState(); + } + + overViewModel() { + return showDialog( + barrierDismissible: false, + context: context, + builder: (context) { + return Center( + child: Container( + width: Get.size.width * 0.85, + height: Get.size.height * 0.6, + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.all(Radius.circular(5))), + child: OverViewGuideModal(), + ), + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + + GlobalController globalContoller = Get.find(); + + return Stack( + children: [ + Positioned( + top: 10, + left: 0, + right: 0, + child: Center( + child: FutureBuilder( + future: Geolocator.isLocationServiceEnabled(), + builder: (context, snapshot) { + print('isLocationServiceEnabled ${snapshot.data}'); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + bool isLocationOn = snapshot.data!; + return StreamBuilder( + stream: Geolocator.getServiceStatusStream(), + builder: (context, snapshot) { + debugPrint("SS $snapshot"); + if (snapshot.connectionState == ConnectionState.waiting) { + return isLocationOn + ? SizedBox() + : Obx( + () => Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0), + child: Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.1), + spreadRadius: 2, + blurRadius: 15) + ]), + child: DefaultTextStyle( + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Location is off", + style: TextStyle( + color: !globalContoller + .darkMode.value + ? ColorConstants + .kBlack + : ColorConstants + .kPrimaryColor, + fontSize: 15, + fontFamily: "Poppins", + fontWeight: + FontWeight.w600, + ), + ), + Text( + "Please turn on the Location to connect\n your scale", + style: TextStyle( + color: !globalContoller + .darkMode.value + ? ColorConstants + .kBlack + : ColorConstants + .kWhite, + fontSize: 12), + // textAlign: TextAlign.justify, + ) + ], + ), + ), + SizedBox(width: 6), + TextButton( + style: TextButton.styleFrom( + foregroundColor: + ColorConstants + .kPrimaryColor, + textStyle: TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + )), + onPressed: () { + Geolocator.getCurrentPosition( + desiredAccuracy: + LocationAccuracy.high, + ); + }, + child: Text("Turn On"), + ) + ]), + ), + ), + ), + ); + } + + if (snapshot.connectionState == ConnectionState.active && + snapshot.hasData) { + print('getServiceStatusStream ${snapshot.data}'); + ServiceStatus locationService = snapshot.data!; + if (locationService == ServiceStatus.enabled) { + return SizedBox(); + } + if (locationService == ServiceStatus.disabled) { + return Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(12), + ), + child: DefaultTextStyle( + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Obx( + () => Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Location is off", + style: TextStyle( + color: ColorConstants + .kPrimaryColor, + fontSize: 15, + fontFamily: "Poppins", + fontWeight: FontWeight.w600, + ), + ), + Text( + "Please turn on the Location to connect\n your scale", + // textAlign: TextAlign.justify, + ) + ], + ), + ), + ), + SizedBox(width: 6), + TextButton( + style: TextButton.styleFrom( + foregroundColor: + ColorConstants.kPrimaryColor, + textStyle: TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + )), + onPressed: () { + Geolocator.getCurrentPosition( + desiredAccuracy: + LocationAccuracy.high); + }, + child: Text("Turn On"), + ) + ]), + ), + ); + } + } + + return const CircularProgressIndicator(); + }, + ); + } + return SizedBox(); + }, + ), + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center( + child: GestureDetector( + onTap: () { + showBarModalBottomSheet( + expand: false, + context: context, + barrierColor: !globalContoller.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xff000000).withOpacity(0.6), + backgroundColor: const Color(0xff1C1C1C), + builder: (context) => SizedBox( + height: context.height * 0.7, + child: DeviceScanPage( + devType: DeviceType.scale, + ), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(30), + ), + ), + ); + }, + child: Column( + children: [ + SizedBox( + width: 200, + height: 200, + child: Lottie.asset('assets/lottie/add.json'), + ), + const Text( + 'Add Scale', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/bioMaker/calendar.dart b/gsf/lib/views/pages/bioMaker/calendar.dart new file mode 100644 index 0000000..a37d2f7 --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/calendar.dart @@ -0,0 +1,216 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; +import 'controller.dart'; +import 'date_utils.dart' as date_util; +import '../../theme.dart'; + +class HorizontalCalendar extends StatefulWidget { + const HorizontalCalendar({Key? key}) : super(key: key); + + @override + State createState() => _HorizontalCalendarState(); +} + +class _HorizontalCalendarState extends State { + late ScrollController scrollController; + List currentMonthList = List.empty(); + DateTime currentDateTime = DateTime.now(); + Map scrollOffsets = { + 1: 0.0, + 2: 0.0, + 3: 0.0, + 4: 11.0, + 5: 70.0, + 6: 121.5, + 7: 177.11, + 8: 231.39, + 9: 291.38, + 10: 347.10, + 11: 404.24, + 12: 459.53, + 13: 513.83, + 14: 570.97, + 15: 626.68, + 16: 680.97, + 17: 738.10, + 18: 793.81, + 19: 848.10, + 20: 905.24, + 21: 962.37, + 22: 1018.09, + 23: 1075.23, + 24: 1128.09, + 25: 1186.67, + 26: 1240.96, + 27: 1298.10, + 28: 1353.82, + 29: 1373.57, + 30: 1373.57, + 31: 1373.57, + }; + + // final scaleOverviewController = Get.put(ScaleOverviewController()); + + final AController aController = Get.put(AController()); + @override + void initState() { + currentMonthList = date_util.DateUtils.daysInMonth(currentDateTime); + currentMonthList.sort((a, b) => a.day.compareTo(b.day)); + currentMonthList = currentMonthList.toSet().toList(); + scrollController = ScrollController( + initialScrollOffset: scrollOffsets[currentDateTime.day] ?? 0.0, + ); + super.initState(); + } + + Widget monthView() { + final brightness = Get.theme.brightness; + return Text( + date_util.DateUtils.months[currentDateTime.month - 1] + + ' ' + + currentDateTime.year.toString(), + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.6) + : Colors.white.withOpacity(0.6), + fontWeight: FontWeight.w500, + fontFamily: 'SFPRO', + fontSize: 18, + ), + ); + } + + Widget hrizontalCapsuleListView() { + return SizedBox( + width: Get.size.width, + height: 75, + child: ListView.builder( + controller: scrollController, + scrollDirection: Axis.horizontal, + physics: const BouncingScrollPhysics(), + shrinkWrap: true, + itemCount: currentMonthList.length, + itemBuilder: (BuildContext context, int index) { + return capsuleView(index); + }, + ), + ); + } + + Widget capsuleView(int index) { + final brightness = Get.theme.brightness; + final isCurrentDate = currentMonthList[index].day != currentDateTime.day; + final currentDate = DateTime.now(); + final currentDatetimeFormate = DateFormat('d').format(currentDate); + final tapDateTimeFormated = + DateFormat('y-M-d').format(currentMonthList[index]); + final currentDatetimeInInt = int.parse(currentDatetimeFormate); + + // check tapped date and current date are same or not + DateFormat dateFormat = DateFormat('y-M-d'); + String formateedDate = dateFormat.format(currentDate); + // aController.getDAte.value = formateedDate; + + return Padding( + padding: isCurrentDate + ? const EdgeInsets.fromLTRB(10, 5, 10, 5) + : const EdgeInsets.fromLTRB(10, 0, 10, 0), + child: GestureDetector( + onTap: () { + currentMonthList[index].day <= currentDatetimeInInt + ? setState(() { + currentDateTime = currentMonthList[index]; + aController.getDAte.value = tapDateTimeFormated; + }) + : null; + print('FORMATEDDATE $formateedDate'); + print('FORMATEDDATE CLICKED DATE ${aController.getDAte.value}'); + if (formateedDate != aController.getDAte.value) { + aController.checDate.value = false; + print('True Ones ${aController.checDate.value}'); + } else { + aController.checDate.value = true; + print('false Ones ${aController.checDate.value}'); + } + }, + child: Container( + width: isCurrentDate ? 36 : 45, + decoration: BoxDecoration( + color: isCurrentDate + ? (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff242423) + : ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.circular(40), + border: currentMonthList[index].day != currentDatetimeInInt + ? Border.all( + color: const Color(0xff707070).withOpacity(0.5), + ) + : Border.all( + color: ColorConstants.kPrimaryColor.withOpacity(1), + width: 2, + ), + boxShadow: [ + BoxShadow( + // offset: Offset(1, 1), + blurRadius: 4, + spreadRadius: 2, + color: Colors.black12, + ), + ], + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + currentMonthList[index].day.toString(), + style: TextStyle( + fontSize: isCurrentDate ? 12 : 20, + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + height: 1, + color: isCurrentDate + ? currentMonthList[index].day == currentDatetimeInInt + ? Color(0xffffffff) + : const Color(0xff474747) + : ColorConstants.kBlack, + ), + ), + const SizedBox(height: 5), + Text( + date_util + .DateUtils.weekdays[currentMonthList[index].weekday - 1], + style: TextStyle( + fontSize: isCurrentDate ? 12 : 14, + fontWeight: FontWeight.bold, + fontFamily: 'SFPRO', + color: isCurrentDate + ? currentMonthList[index].day == currentDatetimeInInt + ? Color(0xffffffff) + : const Color(0xff474747) + : ColorConstants.kBlack, + ), + ) + ], + ), + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + monthView(), + const SizedBox(height: 10), + hrizontalCapsuleListView(), + ], + ); + } +} diff --git a/gsf/lib/views/pages/bioMaker/controller.dart b/gsf/lib/views/pages/bioMaker/controller.dart new file mode 100644 index 0000000..d09cdfd --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/controller.dart @@ -0,0 +1,28 @@ +import 'package:get/get.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; + +import '../../../repository/services/cj/overview_service.dart'; + +class AController extends GetxController { + var getDAte = ''.obs; + RxBool checDate = true.obs; + RxBool isScaleDataStable = false.obs; + RxBool dataNull = false.obs; + Rx scaleData = ICWeightData().obs; + Rx dateWiseData = ICWeightData().obs; + + // localStorage parameters observerable variables + + RxString localWeight = '0.0'.obs; + RxString localMusclerate = '0.0'.obs; + RxString localbodyFat = '0.0'.obs; + RxString localSkeletalRate = '0.0'.obs; + RxString localProtein = '0.0'.obs; + RxString localBmr = '0'.obs; + RxString localWater = '0.0'.obs; + RxString localAge = '0.0'.obs; + + fetchOverViewData() { + return OverViewServices().getSuerOverviewData(getDAte.value); + } +} diff --git a/gsf/lib/views/pages/bioMaker/date_utils.dart b/gsf/lib/views/pages/bioMaker/date_utils.dart new file mode 100644 index 0000000..1c87a47 --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/date_utils.dart @@ -0,0 +1,185 @@ +// ignore_for_file: prefer_const_constructors + +library utils; + +import 'package:intl/intl.dart'; + +class DateUtils { + static final DateFormat _monthFormat = DateFormat('MMMM yyyy'); + static final DateFormat _dayFormat = DateFormat('dd'); + static final DateFormat _firstDayFormat = DateFormat('MMM dd'); + static final DateFormat _fullDayFormat = DateFormat('EEE MMM dd, yyyy'); + static final DateFormat _apiDayFormat = DateFormat('yyyy-MM-dd'); + + static String formatMonth(DateTime d) => _monthFormat.format(d); + + static String formatDay(DateTime d) => _dayFormat.format(d); + + static String formatFirstDay(DateTime d) => _firstDayFormat.format(d); + + static String fullDayFormat(DateTime d) => _fullDayFormat.format(d); + + static String apiDayFormat(DateTime d) => _apiDayFormat.format(d); + + static const List weekdays = [ + 'Mon', + 'Tue', + 'Wed', + 'Thu', + 'Fri', + 'Sat', + 'Sun' + ]; + + static const List months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ]; + + /// The list of days in a given month + static List daysInMonth(DateTime month) { + var first = firstDayOfMonth(month); + var last = DateUtils.lastDayOfMonth(month); + + var daysAfter = 7 - last.weekday; + + // If the last day is sunday (7) the entire week must be rendered + if (daysAfter == 0) { + daysAfter = 7; + } + + // var lastToDisplay = last.add(Duration(days: daysAfter)); + return daysRange(first, last).toList(); + } + + static Iterable daysRange(DateTime first, DateTime last) { + var listOfDates = List.generate( + last.day, (i) => DateTime(first.year, first.month, i + 1)); + return listOfDates; + } + + static bool isFirstDayOfMonth(DateTime day) { + return isSameDay(firstDayOfMonth(day), day); + } + + static bool isLastDayOfMonth(DateTime day) { + return isSameDay(lastDayOfMonth(day), day); + } + + static DateTime firstDayOfMonth(DateTime month) { + return DateTime(month.year, month.month); + } + + static DateTime firstDayOfWeek(DateTime day) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + day = DateTime.utc(day.year, day.month, day.day, 12); + + /// Weekday is on a 1-7 scale Monday - Sunday, + /// This Calendar works from Sunday - Monday + var decreaseNum = day.weekday % 7; + return day.subtract(Duration(days: decreaseNum)); + } + + static DateTime lastDayOfWeek(DateTime day) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + day = DateTime.utc(day.year, day.month, day.day, 12); + + /// Weekday is on a 1-7 scale Monday - Sunday, + /// This Calendar's Week starts on Sunday + var increaseNum = day.weekday % 7; + return day.add(Duration(days: 7 - increaseNum)); + } + + /// The last day of a given month + static DateTime lastDayOfMonth(DateTime month) { + var beginningNextMonth = (month.month < 12) + ? DateTime(month.year, month.month + 1, 1) + : DateTime(month.year + 1, 1, 1); + return beginningNextMonth.subtract(Duration(days: 1)); + } + + /// Returns a [DateTime] for each day the given range. + /// + /// [start] inclusive + /// [end] exclusive + static Iterable daysInRange(DateTime start, DateTime end) sync* { + var i = start; + var offset = start.timeZoneOffset; + while (i.day <= end.day) { + yield i; + i = i.add(Duration(days: 1)); + var timeZoneDiff = i.timeZoneOffset - offset; + if (timeZoneDiff.inSeconds != 0) { + offset = i.timeZoneOffset; + i = i.subtract(Duration(seconds: timeZoneDiff.inSeconds)); + } + } + } + + /// Whether or not two times are on the same day. + static bool isSameDay(DateTime a, DateTime b) { + return a.year == b.year && a.month == b.month && a.day == b.day; + } + + static bool isSameWeek(DateTime a, DateTime b) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + a = DateTime.utc(a.year, a.month, a.day); + b = DateTime.utc(b.year, b.month, b.day); + + var diff = a.toUtc().difference(b.toUtc()).inDays; + if (diff.abs() >= 7) { + return false; + } + + var min = a.isBefore(b) ? a : b; + var max = a.isBefore(b) ? b : a; + var result = max.weekday % 7 - min.weekday % 7 >= 0; + return result; + } + + static DateTime previousMonth(DateTime m) { + var year = m.year; + var month = m.month; + if (month == 1) { + year--; + month = 12; + } else { + month--; + } + return DateTime(year, month); + } + + static DateTime nextMonth(DateTime m) { + var year = m.year; + var month = m.month; + + if (month == 12) { + year++; + month = 1; + } else { + month++; + } + return DateTime(year, month); + } + + static DateTime previousWeek(DateTime w) { + return w.subtract(Duration(days: 7)); + } + + static DateTime nextWeek(DateTime w) { + return w.add(Duration(days: 7)); + } +} diff --git a/gsf/lib/views/pages/bioMaker/overview.dart b/gsf/lib/views/pages/bioMaker/overview.dart new file mode 100644 index 0000000..864d20b --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/overview.dart @@ -0,0 +1,2374 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, must_be_immutable + +import 'dart:async'; +import 'dart:developer'; +import 'dart:io'; +import 'date_utils.dart' as date_util; +import 'package:animated_horizontal_calendar/animated_horizontal_calendar.dart'; +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:intl/intl.dart'; +import 'package:lottie/lottie.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:percent_indicator/percent_indicator.dart'; +import '../../../modals/overview_scaledata_model.dart'; +import '../../../repository/services/cj/overview_service.dart'; +import '../../../scale/model/device_type.dart'; +import '../../../scale/page/device_scan_page.dart'; +import '../../../scale/utils/NavigatorUtils.dart'; +import '../../../scale/utils/debug_logger.dart'; +import '../../../scale/utils/local_storage.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../../view_model/global_controller.dart'; +import '../../../view_model/profile_slider_controller.dart'; +import '../../components/appbar.dart'; +import '../../components/bottom_navigation.dart'; +import '../../theme.dart'; +import '../diet_plan/diet_chart_preview.dart'; +import '../profile/profile_slider.dart'; +import 'calendar.dart'; +import 'controller.dart'; +import 'overview_guide.dart'; + +List overviewDataReturnglobal = []; +// List overviewReturnScaleglobal = []; + +class Overview extends StatefulWidget { + const Overview({Key? key}) : super(key: key); + + @override + State createState() => _OverviewState(); +} + +class _OverviewState extends State + with TickerProviderStateMixin + implements ICDeviceManagerDelegate { + late AnimationController _animationController; + var scaleStreamcontroller = StreamController(); + late AnimationController scaleAnimationController; + + RxBool isVisible = true.obs; + late ScrollController scrollController; + ScrollController listScrollController = ScrollController(); + void hideShowcontainer() => isVisible.toggle(); + var connectState = "Not Connect"; + DateTime dateTtime = DateTime.now(); + String? mac; + String? age; + String? height; + String? weight; + String? imp; + var result = "Result:"; + var menuScan = "Scan"; + var menuUserList = "UserList"; + var menuConnect = "Connect"; + var menuDisConnect = "DisConnect"; + var menuOTA = "OTA"; + var menuLog = "Log"; + ICUserInfo user = ICUserInfo(); + AppDataController appDataController = Get.find(); + + onclickDelayed() { + if (listScrollController.hasClients) { + final position = listScrollController.position.maxScrollExtent; + listScrollController.animateTo( + position, + duration: const Duration(milliseconds: 500), + curve: Curves.easeOut, + ); + } + } + + void updateUser() { + // double feetToCm = 30.48; // 1 foot = 30.48 centimeters + // double inchToCm = 2.54; // 1 inch = 2.54 centimeters + + // var spilitHeight = + // appDataController.height.toDouble().toString().split("."); + // print('Split Height ${spilitHeight}'); + + // var newValueOfFt = spilitHeight[0]; + // var newValueOfInch = spilitHeight[1]; + + // double totalHeightCm = (double.parse(newValueOfFt) * feetToCm) + + // (double.parse(newValueOfInch) * + // inchToCm); //formula of convert foot to cm + + // print("totalCm $totalHeightCm"); + // if (height != null && height!.isNotEmpty) { + // final heightInCm = appDataController.height.toDouble(); + // print('heightInCm $heightInCm'); + user.height = appDataController.height + .toDouble(); //appDataController.height.toDouble(); + // print("Split Height User Height ${totalHeightCm}"); + //DataPareUtil.stringToInt(height!); + // } + // if (age != null && age!.isNotEmpty) { + user.age = appDataController.age.toInt(); //DataPareUtil.stringToInt(age!); + user.peopleType = ICPeopleType.ICPeopleTypeSportman; + // } + // if (weight != null && weight!.isNotEmpty) { + // user.weight = DataPareUtil.stringToDouble(weight!); + // } + // user.sex = ICSexType.ICSexTypeFemale; + final String gender = appDataController.gender.toString(); + + ICSexType scaleGender = + gender == 'male' ? ICSexType.ICSexTypeMale : ICSexType.ICSexTypeFemale; + + user.sex = scaleGender; + + DebugLogger.instance.logText("updateUserInfo --> $user"); + + IcBluetoothSdk.instance.updateUserInfo(user); + debugPrint("IcBluetoothSdk ${user.age}"); + } + + var circularIndicator = 80.2; + final ProfileSliderController slidercontroller = + Get.put(ProfileSliderController()); + late AnimationController progressAnimationController; + late Animation progressAnimation; + late String currentDatetimeFormate; + final aControllerFind = Get.put(AController()); + + @override + void initState() { + // Future.delayed(Duration.zero, () { + // GetStorage().read('showOverviewGuidModal') ?? true + // ? overViewModel() + // : null; + // }); + + progressAnimationController = + AnimationController(vsync: this, duration: const Duration(seconds: 10)); + progressAnimation = Tween(begin: 0.0, end: 1.0) + .animate(progressAnimationController); + progressAnimationController.forward(); + + IcBluetoothSdk.instance.setDeviceManagerDelegate(this); + _animationController = AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 600), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + ); + scaleAnimationController = AnimationController( + vsync: this, + value: 0.0, + duration: Duration(seconds: 3), + ); + updateUser(); + + final currentDate = DateTime.now(); + currentDatetimeFormate = DateFormat('y-M-d').format(currentDate); + var dateWhennotSet = DateFormat('y-M-d').format(DateTime.now()); + aControllerFind.getDAte.value = dateWhennotSet; + super.initState(); + // var updata = {"created_at": "", "data": "year"}; + // BioScaleOverview().dataForallDAtes(updata); + } + + // overViewModel() { + // return showDialog( + // barrierDismissible: false, + // context: context, + // builder: (context) { + // return Center( + // child: Container( + // width: Get.size.width * 0.85, + // height: Get.size.height * 0.6, + // decoration: BoxDecoration( + // color: ColorConstants.kBlack, + // borderRadius: BorderRadius.all(Radius.circular(5))), + // child: OverViewGuideModal(), + // ), + // ); + // }, + // ); + // } + + final ProfileSliderController slidercontrollers = + Get.put(ProfileSliderController()); + + @override + Widget build(BuildContext context) { + // print('DATETIME OF SCALE UPDATED ${dateTtime}'); + String? mrangeTxt; + String? smrangeTxt; + String? prangeTxt; + String? wrangeTxt; + String? ageTxt; + String? bFatTxt; + int? mcolorNew; + int? smcolorNew; + int? pcolorNew; + int? wcolorNew; + int? ageColorNew; + int? bFatColorNew; + String gender = appDataController.gender.toString(); + String actualAge = appDataController.age.toString(); + aControllerFind.localWeight.value = + GetStorage().read('localWeight') ?? '- -'; + aControllerFind.localMusclerate.value = + GetStorage().read('localMusclerate') ?? '- -'; + aControllerFind.localbodyFat.value = + GetStorage().read('localbodyFat') ?? '- -'; + aControllerFind.localSkeletalRate.value = + GetStorage().read('localSkeletalRate') ?? '- -'; + aControllerFind.localProtein.value = + GetStorage().read('localProtein') ?? '- -'; + + aControllerFind.localBmr.value = GetStorage().read('localBmr') ?? '- -'; + + aControllerFind.localWater.value = GetStorage().read('localWater') ?? '- -'; + aControllerFind.localAge.value = GetStorage().read('localAge') ?? '- -'; + + final newMucle = (aControllerFind.localMusclerate.value == '- -') + ? '0.0' + : aControllerFind.localMusclerate.value; + + final newSkeletalmuscle = (aControllerFind.localSkeletalRate.value == '- -') + ? '0.0' + : aControllerFind.localSkeletalRate.value; + + final newprotien = (aControllerFind.localProtein.value == '- -') + ? '0.0' + : aControllerFind.localProtein.value; + + final newWater = (aControllerFind.localWater.value == '- -') + ? '0.0' + : aControllerFind.localWater.value; + + final newAge = (aControllerFind.localAge.value == '- -') + ? '0.0' + : aControllerFind.localAge.value; + + final newBFat = (aControllerFind.localbodyFat.value == '- -') + ? '0.0' + : aControllerFind.localbodyFat.value; + + // muscle rate range calculation + if (gender == 'male') { + if (double.parse(newMucle) >= 0 && double.parse(newMucle) <= 60) { + mrangeTxt = + (aControllerFind.localMusclerate.value == '- -') ? '- -' : 'Low'; + mcolorNew = 0xffE90000; + } else if (double.parse(newMucle) > 60 && double.parse(newMucle) <= 74) { + mrangeTxt = 'Standard'; + mcolorNew = 0xffFFFE00; + } else if (double.parse(newMucle) > 74 && double.parse(newMucle) <= 100) { + mrangeTxt = 'Excellent'; + mcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(newMucle) >= 0 && double.parse(newMucle) <= 56) { + mrangeTxt = + (aControllerFind.localMusclerate.value == '- -') ? '- -' : 'Low'; + mcolorNew = 0xffE90000; + } else if (double.parse(newMucle) > 56 && double.parse(newMucle) <= 70) { + mrangeTxt = 'Standard'; + mcolorNew = 0xffFFFE00; + } else if (double.parse(newMucle) > 70 && double.parse(newMucle) <= 100) { + mrangeTxt = 'Excellent'; + mcolorNew = 0xff8FD155; + } + } + + // skeletal Muscle range calculation + if (gender == 'male') { + if (double.parse(newSkeletalmuscle) >= 0 && + double.parse(newSkeletalmuscle) <= 40.00) { + smrangeTxt = + (aControllerFind.localSkeletalRate.value == '- -') ? '- -' : 'Low'; + smcolorNew = 0xffE90000; + } else if (double.parse(newSkeletalmuscle) > 40.00 && + double.parse(newSkeletalmuscle) <= 60.00) { + smrangeTxt = 'Standard'; + smcolorNew = 0xffFFFE00; + } else if (double.parse(newSkeletalmuscle) > 60.00 && + double.parse(newSkeletalmuscle) <= 100) { + smrangeTxt = 'Excellent'; + smcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(newSkeletalmuscle) >= 0 && + double.parse(newSkeletalmuscle) <= 30.00) { + smrangeTxt = + (aControllerFind.localSkeletalRate.value == '- -') ? '- -' : 'Low'; + smcolorNew = 0xffE90000; + } else if (double.parse(newSkeletalmuscle) > 30.00 && + double.parse(newSkeletalmuscle) <= 50.00) { + smrangeTxt = 'Standard'; + smcolorNew = 0xffFFFE00; + } else if (double.parse(newSkeletalmuscle) > 50.00 && + double.parse(newSkeletalmuscle) <= 100) { + smrangeTxt = 'Excellent'; + smcolorNew = 0xff8FD155; + } + } + + // Protein range calculation + if (gender == 'male') { + if (double.parse(newprotien) >= 0 && double.parse(newprotien) <= 16.00) { + prangeTxt = + (aControllerFind.localProtein.value == '- -') ? '- -' : 'Low'; + pcolorNew = 0xffE90000; + } else if (double.parse(newprotien) > 16.00 && + double.parse(newprotien) <= 18.00) { + prangeTxt = 'Standard'; + pcolorNew = 0xffFFFE00; + } else if (double.parse(newprotien) > 18.00 && + double.parse(newprotien) <= 100) { + prangeTxt = 'Excellent'; + pcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(newprotien) >= 0 && double.parse(newprotien) <= 14.00) { + prangeTxt = + (aControllerFind.localProtein.value == '- -') ? '- -' : 'Low'; + pcolorNew = 0xffE90000; + } else if (double.parse(newprotien) > 14.00 && + double.parse(newprotien) <= 16.00) { + prangeTxt = 'Standard'; + pcolorNew = 0xffFFFE00; + } else if (double.parse(newprotien) > 16.00 && + double.parse(newprotien) <= 100) { + prangeTxt = 'Excellent'; + pcolorNew = 0xff8FD155; + } + } + + // Water range calculation + if (gender == 'male') { + if (double.parse(newWater) >= 0 && double.parse(newWater) <= 55.00) { + wrangeTxt = (aControllerFind.localWater.value == '- -') ? '- -' : 'Low'; + wcolorNew = 0xffE90000; + } else if (double.parse(newWater) > 55.00 && + double.parse(newWater) <= 65.00) { + wrangeTxt = 'Standard'; + wcolorNew = 0xffFFFE00; + } else if (double.parse(newWater) > 65.00 && + double.parse(newWater) <= 100) { + wrangeTxt = 'Excellent'; + wcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(newWater) >= 0 && double.parse(newWater) <= 46.00) { + wrangeTxt = (aControllerFind.localWater.value == '- -') ? '- -' : 'Low'; + wcolorNew = 0xffE90000; + } else if (double.parse(newWater) > 46.00 && + double.parse(newWater) <= 60.00) { + wrangeTxt = 'Standard'; + wcolorNew = 0xffFFFE00; + } else if (double.parse(newWater) > 60.00 && + double.parse(newWater) <= 100) { + wrangeTxt = 'Excellent'; + wcolorNew = 0xff8FD155; + } + } + // body age calculation + if (double.parse(newAge) <= double.parse(actualAge)) { + ageTxt = (aControllerFind.localAge.value == '- -') ? '- -' : 'Standard'; + ageColorNew = 0xff8FD155; + } else if (double.parse(actualAge) >= double.parse(actualAge.toString())) { + ageTxt = 'Over'; + ageColorNew = 0xFFF44336; + } + + // body fat calculation + if (gender == 'male') { + if (double.parse(newBFat) >= 0 && double.parse(newBFat) <= 10.00) { + bFatTxt = (aControllerFind.localbodyFat.value == '- -') ? '- -' : 'Low'; + bFatColorNew = 0xFFFE0000; + } else if (double.parse(newBFat) > 10.00 && + double.parse(newBFat) <= 21.00) { + bFatTxt = 'Standard'; + bFatColorNew = 0xffFFFE03; + } else if (double.parse(newBFat) > 21.00 && double.parse(newBFat) <= 26) { + bFatTxt = 'High'; + bFatColorNew = 0xffFEC100; + } else if (double.parse(newBFat) > 26.00 && + double.parse(newBFat) <= 100) { + bFatTxt = 'Too High'; + bFatColorNew = 0xffFE0000; + } + } else if (gender == 'female') { + if (double.parse(newBFat) >= 0 && double.parse(newBFat) <= 16.00) { + bFatTxt = (aControllerFind.localWater.value == '- -') ? '- -' : 'Low'; + bFatColorNew = 0xFFFE0000; + } else if (double.parse(newBFat) > 16.00 && + double.parse(newBFat) <= 24.00) { + bFatTxt = 'Standard'; + bFatColorNew = 0xffFFFE03; + } else if (double.parse(newBFat) > 25.00 && double.parse(newBFat) <= 30) { + bFatTxt = 'High'; + bFatColorNew = 0xffFEC100; + } else if (double.parse(newBFat) > 30.00 && + double.parse(newBFat) <= 100) { + bFatTxt = 'Too High'; + bFatColorNew = 0xffFE0000; + } + } + + print( + 'aControllerFind.localProtein.value ${aControllerFind.localProtein.value}'); + + // scalebale data of scale + List overviewData = [ + { + 'titletxt': 'Muscle Rate', + 'intValue': aControllerFind.localMusclerate.value, + 'chip': mcolorNew, + 'chipTxt': mrangeTxt, + }, + { + 'titletxt': 'Body Fat', + 'intValue': aControllerFind.localbodyFat.value, + 'chip': bFatColorNew, + 'chipTxt': bFatTxt, + }, + { + 'titletxt': 'Skeletal Muscle', + 'intValue': aControllerFind.localSkeletalRate.value, + 'chip': smcolorNew, + 'chipTxt': smrangeTxt, + }, + { + 'titletxt': 'Protein', + 'intValue': aControllerFind.localProtein.value, + 'chip': pcolorNew, + 'chipTxt': prangeTxt, + }, + { + 'titletxt': 'Water', + 'intValue': aControllerFind.localWater.value, + 'chip': wcolorNew, + 'chipTxt': wrangeTxt, + }, + { + 'titletxt': 'Age', + 'intValue': aControllerFind.localAge.value, + 'chip': ageColorNew, + 'chipTxt': ageTxt, + }, + ]; + final brightness = Get.theme.brightness; + _animationController.forward(); + GlobalController globalContoller = Get.find(); + print('object New Ones'); + + DateFormat dateFormat = DateFormat('y-M-d'); + + String formateedDate = dateFormat.format(DateTime.now()); + + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + showLeading: false, + titleHead: 'Overview', + rightAction: + // IconButton(onPressed: () {}, icon: Icon(Icons.sync_outlined)), + IconButton( + onPressed: () { + showBarModalBottomSheet( + expand: false, + context: context, + barrierColor: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xff000000).withOpacity(0.6), + backgroundColor: const Color(0xff1C1C1C), + builder: (context) => SizedBox( + height: context.height * 0.7, + child: DeviceScanPage( + devType: DeviceType.scale, + ), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(30), + ), + ), + ); + }, + icon: Icon(Icons.sync_outlined), + ), + ), + ), + body: AnimatedBuilder( + animation: _animationController, + builder: (context, child) => FadeScaleTransition( + animation: _animationController, + child: child, + ), + child: SingleChildScrollView( + controller: listScrollController, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 10), + // Bluetooth On and Off start + StreamBuilder( + stream: FlutterBluePlus.adapterState, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.active && + snapshot.hasData) { + BluetoothAdapterState bluetoothState = snapshot.data!; + if (bluetoothState == BluetoothAdapterState.off || + bluetoothState == BluetoothAdapterState.turningOn) { + return Obx(() => Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.1), + spreadRadius: 2, + blurRadius: 15, + ) + ]), + child: DefaultTextStyle( + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + child: Row(children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Bluetooth is off", + style: TextStyle( + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontSize: 15, + fontFamily: "Poppins", + fontWeight: FontWeight.w600, + ), + ), + Text( + "Please turn on the bluetooth to connect your scale", + style: TextStyle( + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 12), + // textAlign: TextAlign.justify, + ) + ], + ), + ), + SizedBox(width: 6), + TextButton( + style: TextButton.styleFrom( + foregroundColor: + ColorConstants.kPrimaryColor, + textStyle: TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + ), + ), + onPressed: () => FlutterBluePlus.turnOn(), + child: Text("Turn On"), + ) + ]), + ), + )); + } + } + return SizedBox(); + }, + ), + SizedBox(height: 10), + // Location On and Off start + Platform.isAndroid + ? FutureBuilder( + future: Geolocator.isLocationServiceEnabled(), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + bool isLocationOn = snapshot.data!; + return StreamBuilder( + stream: Geolocator.getServiceStatusStream(), + builder: (context, snapshot) { + debugPrint("SS $snapshot"); + if (snapshot.connectionState == + ConnectionState.waiting) { + return isLocationOn + ? SizedBox() + : Obx( + () => Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: !globalContoller + .darkMode.value + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: + BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: ColorConstants + .kBlack + .withOpacity(0.1), + spreadRadius: 2, + blurRadius: 15) + ]), + child: DefaultTextStyle( + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Location is off", + style: TextStyle( + color: !globalContoller + .darkMode + .value + ? ColorConstants + .kBlack + : ColorConstants + .kPrimaryColor, + fontSize: 15, + fontFamily: + "Poppins", + fontWeight: + FontWeight + .w600, + ), + ), + Text( + "Please turn on the Location to connect\n your scale", + style: TextStyle( + color: !globalContoller + .darkMode + .value + ? ColorConstants + .kBlack + : ColorConstants + .kWhite, + fontSize: 12), + // textAlign: TextAlign.justify, + ) + ], + ), + ), + SizedBox(width: 6), + TextButton( + style: + TextButton.styleFrom( + foregroundColor: + ColorConstants + .kPrimaryColor, + textStyle: + TextStyle( + fontFamily: + "Poppins", + fontWeight: + FontWeight + .w500, + )), + onPressed: () { + Geolocator + .getCurrentPosition( + desiredAccuracy: + LocationAccuracy + .high, + ); + }, + child: Text("Turn On"), + ) + ]), + ), + ), + ); + } + + if (snapshot.connectionState == + ConnectionState.active && + snapshot.hasData) { + ServiceStatus locationService = + snapshot.data!; + if (locationService == + ServiceStatus.enabled) { + return SizedBox(); + } + if (locationService == + ServiceStatus.disabled) { + return Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(12), + ), + child: DefaultTextStyle( + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + ), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Location is off", + style: TextStyle( + color: ColorConstants + .kPrimaryColor, + fontSize: 15, + fontFamily: "Poppins", + fontWeight: + FontWeight.w600, + ), + ), + Text( + "Please turn on the Location to connect\n your scale", + // textAlign: TextAlign.justify, + ) + ], + ), + ), + SizedBox(width: 6), + TextButton( + style: TextButton.styleFrom( + foregroundColor: + ColorConstants + .kPrimaryColor, + textStyle: TextStyle( + fontFamily: "Poppins", + fontWeight: FontWeight.w500, + )), + onPressed: () { + Geolocator.getCurrentPosition( + desiredAccuracy: + LocationAccuracy.high); + }, + child: Text("Turn On"), + ) + ], + ), + ), + ); + } + } + return const CircularProgressIndicator(); + }, + ); + } + return SizedBox(); + }, + ) + : SizedBox(), + // + Obx( + () => Column( + children: [ + SizedBox(height: 0), + // HorizontalCalendar(), + + monthView(dateSelected: aControllerFind.getDAte.value), + const SizedBox(height: 10), + SizedBox( + // width: 350, + // padding: EdgeInsets.all(10), + height: 138.09, + child: Container( + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: + ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + // elevation: 2, + child: Padding( + padding: const EdgeInsets.all(15), + child: AnimatedHorizontalCalendar( + initialDate: DateTime.now() + .subtract(Duration(days: 365)), + lastDate: DateTime.now(), + colorOfWeek: Colors.white, + colorOfMonth: Colors.white, + tableCalenderButtonColor: + ColorConstants.kPrimaryColor, + unSelectedBoxShadow: + const BoxShadow(color: Colors.amber), + selectedBoxShadow: + const BoxShadow(color: Colors.black12), + // curve: Curves.easeInOutCirc, + tableCalenderIcon: const Icon( + Icons.calendar_today, + color: Colors.black, + ), + date: DateTime.now(), + textColor: Colors.black, + backgroundColor: Colors.black12, + tableCalenderThemeData: + ThemeData.light().copyWith( + primaryColor: ColorConstants.kPrimaryColor, + buttonTheme: const ButtonThemeData( + textTheme: ButtonTextTheme.primary), + colorScheme: const ColorScheme.light( + primary: Color.fromARGB(255, 132, 191, 5), + ).copyWith(background: Colors.black), + ), + selectedColor: ColorConstants.kPrimaryColor, + onDateSelected: (date) { + final tapDateTimeFormated = + DateFormat('y-M-d') + .format(DateTime.parse(date)); + aControllerFind.getDAte.value = + tapDateTimeFormated; + if (formateedDate != + aControllerFind.getDAte.value) { + aControllerFind.checDate.value = false; + print( + 'True Ones ${aControllerFind.checDate.value}'); + } else { + aControllerFind.checDate.value = true; + print( + 'false Ones ${aControllerFind.checDate.value}'); + } + }), + ), + ), + ), + SizedBox(height: 20), + + // check today days + aControllerFind.checDate.value + ? Column( + children: [ + Container( + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 22.0, + vertical: 28, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text(connectState), + SizedBox(height: 10), + Text( + 'Last Update Time', + style: TextStyle( + fontSize: 16, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 10), + Text( + // '07 June 2023 | 19:35', + DateFormat( + 'dd MMM yyyy | hh:mm a') + .format(dateTtime), + style: TextStyle( + fontSize: 14, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w300, + ), + ), + ], + ), + AnimatedBuilder( + animation: + progressAnimationController, + builder: (context, child) { + return CircularPercentIndicator( + percent: progressAnimation.value, + radius: 54.0, + lineWidth: 10.0, + // animation: true, + center: Text( + "${aControllerFind.scaleData.value!.weight_kg.toStringAsFixed(2)} \n KG", + style: TextStyle( + fontWeight: FontWeight.w500, + fontFamily: 'SFPRO', + fontSize: 20.0, + height: 1, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : Color(0xffFFFFFF), + ), + textAlign: TextAlign.center, + ), + circularStrokeCap: + CircularStrokeCap.round, + progressColor: + ColorConstants.kPrimaryColor, + backgroundColor: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : Color(0xff707070), + ); + }, + ) + ], + ), + ), + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset( + 'assets/image/muscle_rate.svg', + color: + ColorConstants.kPrimaryColor, + width: 35, + ), + SizedBox(height: 5), + Text( + aControllerFind + .localMusclerate.value, + style: TextStyle( + fontSize: 18, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + SizedBox(width: 5), + Text( + 'Muscle Rate', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ) + ], + ), + ), + ), + Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: + (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: + BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset( + 'assets/image/fat_icon.svg'), + SizedBox(height: 5), + Text( + aControllerFind + .localbodyFat.value, + style: TextStyle( + fontSize: 18, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + 'Body Fat', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + // ProfileSlider(); + Get.to( + // () => BasalMetaBolism( + // // apiBmr: bmr ?? '0', + // ), + Get.to(() => DietChartPlan())); + }, + child: Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: + (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: + BorderRadius.circular(20), + border: Border.all( + color: ColorConstants + .kPrimaryColor), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset( + 'assets/image/nutrition.svg', + width: 32, + color: ColorConstants + .kPrimaryColor, + ), + SizedBox(height: 5), + Text( + aControllerFind.localBmr.value, + style: TextStyle( + fontSize: 18, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + 'BMR', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ), + ), + ], + ), + // SizedBox(height: 10), + SizedBox( + height: 25, + ), + Divider( + color: Color(0xff707070).withOpacity(0.6), + thickness: 1, + ), + SizedBox(height: 25), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Body Composition', + style: TextStyle( + fontSize: 18, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.8) + : Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w700, + letterSpacing: 0.5, + height: 1, + ), + ), + // Obx( + // () => + // ), + AnimatedRotation( + turns: isVisible.isTrue ? 0.5 : 0, + duration: + const Duration(milliseconds: 500), + child: InkWell( + splashColor: Colors.transparent, + onTap: () { + hideShowcontainer(); + Future.delayed( + Duration(milliseconds: 500), + () { + onclickDelayed(); + }); + }, + child: Icon( + Icons.keyboard_arrow_down_rounded, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + size: 40, + ), + ), + ), + ], + ), + SizedBox(height: 20), + AnimatedSize( + duration: Duration(milliseconds: 400), + child: AnimatedContainer( + duration: Duration(seconds: 1), + height: isVisible.isTrue ? null : 0, + decoration: BoxDecoration( + color: + (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: + BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20.0), + child: Column( + children: [ + SizedBox(height: 15), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: overviewData.length, + physics: ScrollPhysics(), + itemBuilder: (context, index) => + IndexRows( + ontap: () { + Get.to( + () => ProfileSlider(), + arguments: index, + ); + }, + titletxt: overviewData[index] + ['titletxt'], + intValue: overviewData[index] + ['intValue'], + chip: (overviewData[index] + ['chip'] == + '') + ? SizedBox() + : GestureDetector( + onTap: () { + Get.to( + () => + ProfileSlider(), + arguments: index, + ); + }, + child: bagdeChip( + overviewData[index] + ['chipTxt'], + Color( + overviewData[ + index] + ['chip'], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + SizedBox(height: 16), + ], + ) + : dateWiseScaleData(brightness), + ], + ), + ), + ], + ), + ), + ), + ), + bottomNavigationBar: BottomNavigation(), + ); + } + + formateDateWithLeadingZero(String dateSelected) { + // Split the date string into year, month, and day + + List dateParts = dateSelected.split('-'); + +// Ensure month has two digits by adding a leading zero if necessary + String paddedMonth = + dateParts[1].length == 1 ? '0${dateParts[1]}' : dateParts[1]; + +// Ensure day has two digits by adding a leading zero if necessary + String paddedDay = + dateParts[2].length == 1 ? '0${dateParts[2]}' : dateParts[2]; + +// Create a new date string with padded month and day + String formattedDateString = "${dateParts[0]}-$paddedMonth-$paddedDay"; + +// Parse the formatted date string + DateTime properDateTime = DateTime.parse(formattedDateString); + return properDateTime; + } + + Widget monthView({required String dateSelected}) { + final brightness = Get.theme.brightness; + DateTime dateTimeConverted = formateDateWithLeadingZero(dateSelected); + + return Text( + date_util.DateUtils.months[dateTimeConverted.month - 1] + + ' ' + + dateTimeConverted.year.toString(), + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.6) + : Colors.white.withOpacity(0.6), + fontWeight: FontWeight.w500, + fontFamily: 'SFPRO', + fontSize: 18, + ), + ); + } + + // when scale data get from api design + Column dateWiseScaleData(Brightness brightness) { + print('object of scale of apis'); + String gender = appDataController.gender.toString(); + return Column( + children: [ + Obx( + () => FutureBuilder( + future: aControllerFind.fetchOverViewData(), + builder: (context, snapshot) { + if (aControllerFind.dataNull.value == false) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + UserOverviewModelData data = snapshot.data!.data; + String mrangeTxt = ''; + String smrangeTxt = ''; + String prangeTxt = ''; + String wrangeTxt = ''; + String bFatangeTxt = ''; + int mcolorNew = 0; + int? smcolorNew = 0; + int? pcolorNew = 0; + int? wcolorNew = 0; + int? bFatcolorNew = 0; + // muscle rate range calculation + // print('object muscle rate ${data.muscleRate.runtimeType}'); + if (gender == 'male') { + if (double.parse(data.muscleRate) >= 0 && + double.parse(data.muscleRate) <= 60.00) { + mrangeTxt = 'Low'; + mcolorNew = 0xffE90000; + } else if (double.parse(data.muscleRate) > 60.00 && + double.parse(data.muscleRate) <= 74.00) { + mrangeTxt = 'Standard'; + mcolorNew = 0xffFFFE00; + } else if (double.parse(data.muscleRate) > 74.00 && + double.parse(data.muscleRate) <= 100.00) { + mrangeTxt = 'Excellent'; + mcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(data.muscleRate) >= 0.00 && + double.parse(data.muscleRate) <= 56.00) { + mrangeTxt = 'Low'; + mcolorNew = 0xffE90000; + } else if (double.parse(data.muscleRate) > 56.00 && + double.parse(data.muscleRate) <= 70.00) { + mrangeTxt = 'Standard'; + mcolorNew = 0xffFFFE00; + } else if (double.parse(data.muscleRate) > 70.00 && + double.parse(data.muscleRate) <= 100) { + mrangeTxt = 'Excellent'; + mcolorNew = 0xff8FD155; + } + } + // skeletal Muscle range calculation + if (gender == 'male') { + if (double.parse(data.skeletalMuscle) >= 0.00 && + double.parse(data.skeletalMuscle) <= 40.00) { + smrangeTxt = 'Low'; + smcolorNew = 0xffE90000; + } else if (double.parse(data.skeletalMuscle) > 40.00 && + double.parse(data.skeletalMuscle) <= 60.00) { + smrangeTxt = 'Standard'; + smcolorNew = 0xffFFFE00; + } else if (double.parse(data.skeletalMuscle) > 60.00 && + double.parse(data.skeletalMuscle) <= 100) { + smrangeTxt = 'Excellent'; + smcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(data.skeletalMuscle) >= 0.00 && + double.parse(data.skeletalMuscle) <= 30.00) { + smrangeTxt = 'Low'; + smcolorNew = 0xffE90000; + } else if (double.parse(data.skeletalMuscle) > 30.00 && + double.parse(data.skeletalMuscle) <= 50.00) { + smrangeTxt = 'Standard'; + smcolorNew = 0xffFFFE00; + } else if (double.parse(data.skeletalMuscle) > 50.00 && + double.parse(data.skeletalMuscle) <= 100.00) { + smrangeTxt = 'Excellent'; + smcolorNew = 0xff8FD155; + } + } + + // Protein range calculation + if (gender == 'male') { + if (double.parse(data.protein) >= 0.00 && + double.parse(data.protein) <= 16.00) { + prangeTxt = 'Low'; + pcolorNew = 0xffE90000; + } else if (double.parse(data.protein) > 16.00 && + double.parse(data.protein) <= 18.00) { + prangeTxt = 'Standard'; + pcolorNew = 0xffFFFE00; + } else if (double.parse(data.protein) > 18.00 && + double.parse(data.protein) <= 100.00) { + prangeTxt = 'Excellent'; + pcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(data.protein) >= 0.00 && + double.parse(data.protein) <= 14.00) { + prangeTxt = 'Low'; + pcolorNew = 0xffE90000; + } else if (double.parse(data.protein) > 14.00 && + double.parse(data.protein) <= 16.00) { + prangeTxt = 'Standard'; + pcolorNew = 0xffFFFE00; + } else if (double.parse(data.protein) > 16.00 && + double.parse(data.protein) <= 100.00) { + prangeTxt = 'Excellent'; + pcolorNew = 0xff8FD155; + } + } + + // Water range calculation + print('api data of water ${data.water}'); + if (gender == 'male') { + if (double.parse(data.water) >= 0.00 && + double.parse(data.water) <= 55.00) { + wrangeTxt = 'Low'; + wcolorNew = 0xffE90000; + } else if (double.parse(data.water) > 55.00 && + double.parse(data.water) <= 65.00) { + wrangeTxt = 'Standard'; + wcolorNew = 0xffFFFE00; + } else if (double.parse(data.water) > 65.00 && + double.parse(data.water) <= 100) { + wrangeTxt = 'Excellent'; + wcolorNew = 0xff8FD155; + } + } else if (gender == 'female') { + if (double.parse(data.water) >= 0.00 && + double.parse(data.water) <= 46.00) { + wrangeTxt = 'Low'; + wcolorNew = 0xffE90000; + } else if (double.parse(data.water) > 46.00 && + double.parse(data.water) <= 60.00) { + wrangeTxt = 'Standard'; + wcolorNew = 0xffFFFE00; + } else if (double.parse(data.water) > 60.00 && + double.parse(data.water) <= 100) { + wrangeTxt = 'Excellent'; + wcolorNew = 0xff8FD155; + } + } + // body fat calculation + if (gender == 'male') { + log('aControllerFind.localbodyFat.value ${aControllerFind.localbodyFat.value}'); + if (double.parse(data.bodyFat) >= 0 && + double.parse(data.bodyFat) <= 10.00) { + bFatangeTxt = 'Low'; + bFatcolorNew = 0xFFFE0000; + } else if (double.parse(data.bodyFat) > 10.00 && + double.parse(data.bodyFat) <= 21.00) { + bFatangeTxt = 'Standard'; + bFatcolorNew = 0xffFFEB21; + } else if (double.parse(data.bodyFat) > 21.00 && + double.parse(data.bodyFat) <= 26) { + bFatangeTxt = 'High'; + bFatcolorNew = 0xff3F701F; + } else if (double.parse(data.bodyFat) > 26.00 && + double.parse(data.bodyFat) <= 100) { + bFatangeTxt = 'Too High'; + bFatcolorNew = 0xFFFE0000; + } + } else if (gender == 'female') { + log('aControllerFind.localbodyFat.value ${aControllerFind.localbodyFat.value}'); + if (double.parse(data.bodyFat) >= 0 && + double.parse(data.bodyFat) <= 16.00) { + bFatangeTxt = 'Low'; + bFatcolorNew = 0xFFFE0000; + } else if (double.parse(data.bodyFat) > 16.00 && + double.parse(data.bodyFat) <= 24.00) { + bFatangeTxt = 'Standard'; + bFatcolorNew = 0xffFFEB21; + } else if (double.parse(data.bodyFat) > 25.00 && + double.parse(data.bodyFat) <= 30) { + bFatangeTxt = 'High'; + bFatcolorNew = 0xff3F701F; + } else if (double.parse(data.bodyFat) > 30.00 && + double.parse(data.bodyFat) <= 100) { + bFatangeTxt = 'Too High'; + bFatcolorNew = 0xFFFE0000; + } + } + + // print('API NULL DATA ${snapshot.hasData}'); + List overviewDataReturn = [ + { + 'titletxt': 'Muscle Rate', + 'intValue': '${data.muscleRate}', + 'chip': mcolorNew, + 'chipTxt': mrangeTxt, + }, + { + 'titletxt': 'Body Fat', + 'intValue': '${data.bodyFat}', + 'chip': bFatcolorNew, + 'chipTxt': bFatangeTxt, + }, + { + 'titletxt': 'Skeletal Muscle', + 'intValue': '${data.skeletalMuscle}', + 'chip': smcolorNew, + 'chipTxt': smrangeTxt, + }, + { + 'titletxt': 'Protein', + 'intValue': '${data.protein}', + 'chip': pcolorNew, + 'chipTxt': prangeTxt, + }, + // { + // 'titletxt': 'BMR', + // 'intValue': '${data.bmr}kcal', + // 'chip': 0xff10D49A, + // 'chipTxt': 'Standard', + // }, + { + 'titletxt': 'Water', + 'intValue': '${data.water}', + 'chip': wcolorNew, + 'chipTxt': wrangeTxt, + }, + { + 'titletxt': 'Age', + 'intValue': '${data.age}', + 'chip': smcolorNew, + 'chipTxt': 'Standard', + }, + ]; + overviewDataReturnglobal = overviewDataReturn; + + updatedTimeConvert(String updatedDateTime) { + String inputTime = updatedDateTime; + DateFormat inputFormat = DateFormat('dd-MM-yyyy HH:mm:ss'); + DateTime dateTime = inputFormat.parse(inputTime); + + String formattedTime = + DateFormat('dd MMM yyyy | hh:mm a').format(dateTime); + return formattedTime; + } + + return Column( + children: [ + // Text(data.age), + Container( + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 22.0, + vertical: 28, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text(connectState), + ], + ), + SizedBox(height: 10), + Text( + 'Last Update TIme', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 10), + Text( + // // '07 June 2023 | 19:35', + // DateFormat('dd MMMM yyyy | kk:mm') + // .format(dateTtime), + updatedTimeConvert(data.updatedTime), + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w300, + ), + ), + ], + ), + AnimatedBuilder( + animation: progressAnimationController, + builder: (context, child) { + return CircularPercentIndicator( + percent: (data.weight == '') ? 0 : 1, + radius: 54.0, + lineWidth: 10.0, + // animation: true, + center: Text( + "${(data.weight == '') ? '--' : data.weight} \n KG", + style: TextStyle( + fontWeight: FontWeight.w500, + fontFamily: 'SFPRO', + fontSize: 20.0, + height: 1, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffFFFFFF), + ), + textAlign: TextAlign.center, + ), + circularStrokeCap: CircularStrokeCap.round, + progressColor: ColorConstants.kPrimaryColor, + backgroundColor: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xff707070), + ); + }, + ) + ], + ), + ), + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: + ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset( + 'assets/image/muscle_rate.svg', + color: ColorConstants.kPrimaryColor, + width: 35, + ), + SizedBox(height: 5), + Text( + // '${data.weight}', + data.muscleRate, + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + 'Muscle Rate', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ) + ], + ), + ), + ), + Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: + ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset('assets/image/fat_icon.svg'), + SizedBox(height: 5), + Text( + // data.bodyFat, + "${data.bodyFat}%", + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + 'Body Fat', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Get.to( + // () =>, BasalMetaBolism( + // // apiBmr: bmr ?? '0', + // ), + () => DietChartPlan(), + ); + }, + child: Container( + width: Get.size.width * 0.28, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: ColorConstants.kPrimaryColor), + boxShadow: [ + BoxShadow( + color: + ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + SvgPicture.asset( + 'assets/image/nutrition.svg', + width: 32, + color: ColorConstants.kPrimaryColor, + ), + // Image.asset( + // 'assets/image/nutrition.png', + // width: 40, + // ), + SizedBox(height: 5), + Text( + data.bmr, + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + 'BMR', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + .withOpacity(0.6) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ), + ), + ], + ), + // SizedBox(height: 10), + SizedBox( + height: 25, + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Row( + // children: [ + // SvgPicture.asset( + // 'assets/image/personal_details.svg'), + // SizedBox(width: 10), + // Text( + // 'Details', + // style: TextStyle( + // fontSize: 18, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack.withOpacity(0.7) + // : Color(0xffd9d9d9), + // ), + // ) + // ], + // ), + // SvgPicture.asset( + // 'assets/image/${brightness == Brightness.light ? 'share_black' : 'share'}.svg'), + // ], + // ), + // SizedBox(height: 2), + Divider( + color: Color(0xff707070).withOpacity(0.6), + thickness: 1, + ), + SizedBox(height: 25), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Body Composition', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w700, + letterSpacing: 0.5, + height: 1, + ), + ), + AnimatedRotation( + turns: isVisible.isTrue ? 0.5 : 0, + duration: const Duration(milliseconds: 500), + child: InkWell( + splashColor: Colors.transparent, + onTap: () { + hideShowcontainer(); + Future.delayed(Duration(milliseconds: 500), + () { + onclickDelayed(); + }); + }, + child: Icon( + Icons.keyboard_arrow_down_rounded, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + size: 40, + ), + ), + ), + ], + ), + // Text( + // 'Weighed 3 Days ago', + // style: TextStyle( + // fontSize: 14, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack.withOpacity(0.7) + // : Color(0xffD9D9D9), + // fontFamily: 'SFPRO', + // height: 1, + // fontWeight: FontWeight.w500, + // ), + // ), + SizedBox(height: 20), + AnimatedSize( + duration: Duration(milliseconds: 400), + child: AnimatedContainer( + duration: Duration(seconds: 1), + height: isVisible.isTrue ? null : 0, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20.0), + child: Column( + children: [ + SizedBox(height: 15), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: overviewDataReturn.length, + physics: ScrollPhysics(), + itemBuilder: (context, index) => + IndexRows( + ontap: () { + // print('object'); + slidercontrollers.setValues(); + Get.to( + () => ProfileSlider(), + arguments: index, + ); + }, + titletxt: overviewDataReturn[index] + ['titletxt'], + intValue: overviewDataReturn[index] + ['intValue'], + chip: (overviewDataReturn[index] + ['chip'] == + '') + ? SizedBox() + : bagdeChip( + overviewDataReturn[index] + ['chipTxt'], + Color( + overviewDataReturn[index] + ['chip'], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + SizedBox(height: 16), + ], + ); + } + } else { + return SizedBox( + height: Get.size.height - 320, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 400, + height: 400, + child: Lottie.asset('assets/lottie/no-data-found.json'), + ), + Text( + 'No Data Found', + style: TextStyle(color: ColorConstants.kPrimaryColor), + ), + ], + ), + ); + } + return CircularProgressIndicator(); + }, + ), + ) + ], + ); + } + + @override + void dispose() { + super.dispose(); + _animationController.dispose(); + } + + void menuSelectValue(value) { + if (value == menuScan) { + NavigatorUtils.goScaleScanPage(context, DeviceType.scale); + } else if (value == menuLog) { + NavigatorUtils.goLogPage(context); + } else if (value == menuUserList) { + NavigatorUtils.goUserListPage(context); + } else if (value == menuDisConnect) { + if (mac != null) { + IcBluetoothSdk.instance.removeDevice( + ICDevice(mac), + ICRemoveDeviceCallBack( + callBack: + (ICDevice icDevice, ICRemoveDeviceCallBackCode code) {})); + } + } else if (value == menuConnect) { + if (mac != null) { + IcBluetoothSdk.instance.addDevice( + ICDevice(mac), + ICAddDeviceCallBack( + callBack: (ICDevice icDevice, ICAddDeviceCallBackCode code) {}, + ), + ); + } + } else if (value == menuOTA) { + if (mac != null) { + NavigatorUtils.goOTAPage(context, mac!); + } + } + } + + @override + void onBleState(ICBleState state) { + if (state == ICBleState.ICBleStatePoweredOff) { + setState( + () { + connectState = "Not Connect"; + }, + ); + } + } + + @override + void onDeviceConnectionChanged(ICDevice device, ICDeviceConnectState state) { + DebugLogger.instance + .logText("onDeviceConnectionChanged: ${device.macAddr!} ->$state"); + setState(() { + mac = device.macAddr; + connectState = state == ICDeviceConnectState.ICDeviceConnectStateConnected + ? "Connected" + : "Not Connect"; + }); + } + + @override + void onInitFinish(bool bSuccess) {} + + @override + void onNodeConnectionChanged( + ICDevice device, int nodeId, ICDeviceConnectState state) {} + + @override + void onReceiveBattery(ICDevice device, int battery, Object ext) {} + + @override + void onReceiveConfigWifiResult(ICDevice device, ICConfigWifiState state) {} + + @override + void onReceiveCoordData(ICDevice device, ICCoordData data) {} + + @override + void onReceiveDebugData(ICDevice device, int type, Object obj) {} + + @override + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo) {} + + @override + void onReceiveHR(ICDevice device, int hr) {} + + @override + void onReceiveHistorySkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data) {} + + @override + void onReceiveKitchenScaleUnitChanged( + ICDevice device, ICKitchenScaleUnit unit) {} + + @override + void onReceiveMeasureStepData( + ICDevice device, ICMeasureStep step, Object data) { + DebugLogger.instance.logText("onReceiveMeasureStepData:步骤 $step"); + if (step == ICMeasureStep.ICMeasureStepMeasureOver) { + var icWeight = data as ICWeightData; + user.weight = icWeight.weight_kg; + user.lastImp = icWeight.imp.toInt(); + DebugLogger.instance + .logText("ICMeasureStepMeasureOver ${device.macAddr!} ->$data"); + } + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\nstep:$step\n$data"; + }); + } + + @override + void onReceiveRulerData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data) {} + + @override + void onReceiveRulerMeasureModeChanged( + ICDevice device, ICRulerMeasureMode mode) {} + + @override + void onReceiveRulerUnitChanged(ICDevice device, ICRulerUnit unit) {} + + @override + void onReceiveSkipData(ICDevice device, ICSkipData data) {} + + @override + void onReceiveUpgradePercent( + ICDevice device, ICUpgradeStatus status, int percent) {} + + @override + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data) { + // print('object onReceiveWeightCenterData $data'); + if (data.isStabilized) { + // print('object stableeed'); + DebugLogger.instance + .logText("onReceiveWeightCenterData: ${device.macAddr!} ->$data"); + } + mac = device.macAddr; + setState(() { + connectState = "Connected"; + result = "Result:\n$data"; + }); + } + + @override + void onReceiveWeightData(ICDevice device, ICWeightData data) { + mac = device.macAddr; + aControllerFind.scaleData.value = data; + // scaleStreamcontroller.sink.add(data); + // print('scale local storage data ${GetStorage().read('ScaleDataRecent')}'); + + print('onReceiveWeightData setstates $data'); + if (progressAnimationController.isCompleted || + progressAnimationController.isDismissed) { + progressAnimationController.forward(from: 0.0); + } + setState(() { + aControllerFind.isScaleDataStable.value = false; + connectState = "Connected"; + result = "Result:\nWeightData$data"; + }); + + if (data.isStabilized) { + // print('data is streamining'); + // print('object data isStabilized bmr ${data.bmr}'); + + GetStorage().write('localWeight', data.weight_kg.toStringAsFixed(1)); + GetStorage() + .write('localMusclerate', data.musclePercent.toStringAsFixed(1)); + GetStorage() + .write('localbodyFat', data.bodyFatPercent.toStringAsFixed(1)); + GetStorage() + .write('localSkeletalRate', data.smPercent.toStringAsFixed(1)); + GetStorage() + .write('localProtein', data.proteinPercent.toStringAsFixed(1)); + GetStorage().write('localBmr', data.bmr.toString()); + GetStorage().write('localWater', data.moisturePercent.toStringAsFixed(1)); + GetStorage().write('localAge', data.physicalAge.toStringAsFixed(0)); + GetStorage().write('scaleStablized', true); + + DebugLogger.instance + .logText("onReceiveWeightData: ${device.macAddr!} ->$data"); + OverViewServices().addUserOverviewData( + bodyFat: data.bodyFatPercent.toStringAsFixed(1), + muscleRate: data.musclePercent.toStringAsFixed(2), + skeletalMuscle: data.smPercent.toStringAsFixed(2), + protein: data.proteinPercent.toStringAsFixed(2), + bmr: '${data.bmr}', + water: data.moisturePercent.toStringAsFixed(2), + age: '${data.physicalAge.round()}', + weight: data.weight_kg.toStringAsFixed(1), + ); + setState(() { + dateTtime = DateTime.now(); + scaleAnimationController.animateTo(0.9); + aControllerFind.isScaleDataStable.value = true; + // user.weight = data.weight_kg; + user.lastImp = data.imp as int; + aControllerFind.localWeight.value = GetStorage().read('localWeight'); + }); + print('stable local weight ${GetStorage().read('localWeight')}'); + } + } + + @override + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data) { + DebugLogger.instance + .logText("onReceiveWeightHistoryData: ${device.macAddr!} ->$data"); + setState(() { + mac = device.macAddr; + connectState = "Connected"; + result = "Result:\nHistoryData$data"; + }); + } + + @override + void onReceiveWeightUnitChanged(ICDevice device, ICWeightUnit unit) { + var value = LocalStorage.getData("communicationType:${device.macAddr}"); + log("onReceiveWeightUnitChanged " + value); + if (value != null) { + if (value == 0) { + return; + } + } + } +} + +bagdeChip(String chiptxt, Color bgcolor) { + // final brightness = Get.theme.brightness; + return Container( + decoration: BoxDecoration( + color: bgcolor, + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 2), + child: Text( + chiptxt, + style: TextStyle( + fontSize: 12, + color: ColorConstants.kBlack, + ), + ), + ), + ); +} + +class IndexRows extends StatelessWidget { + IndexRows( + {Key? key, + required this.titletxt, + required this.intValue, + this.chip, + required this.ontap}) + : super(key: key); + + String titletxt; + String intValue; + Widget? chip; + VoidCallback ontap; + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Padding( + padding: const EdgeInsets.only(bottom: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + titletxt, + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffd9d9d9), + fontFamily: 'SFPRO', + ), + ), + Row( + children: [ + Text( + intValue, + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.7) + : Color(0xffd9d9d9), + fontFamily: 'SFPRO', + ), + ), + Spacer(), + if (chip != null) chip!, + GestureDetector( + onTap: ontap, + child: Icon( + Icons.keyboard_arrow_right_outlined, + size: 30, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/bioMaker/overview_guide.dart b/gsf/lib/views/pages/bioMaker/overview_guide.dart new file mode 100644 index 0000000..24c4864 --- /dev/null +++ b/gsf/lib/views/pages/bioMaker/overview_guide.dart @@ -0,0 +1,192 @@ +// ignore_for_file: unrelated_type_equality_checks, prefer_const_literals_to_create_immutables, prefer_const_constructors + +import 'dart:io'; + +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; + +import '../../theme.dart'; + +class OverViewGuideModal extends StatelessWidget { + const OverViewGuideModal({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + GlobalController globalController = Get.put(GlobalController()); + RxInt _current = 0.obs; + final CarouselController _controller = CarouselController(); + List list = [topBar(), addScale(), stepOnScale(), scaleList(), ]; + return SafeArea( + child: Scaffold( + body: Padding( + padding: const EdgeInsets.only(top: 20, left: 20, right: 20), + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: 5, + child: Text( + 'User Guide', + style: TextStyle(fontSize: 17), + textAlign: TextAlign.center, + ), + ), + Expanded( + flex: 0, + child: GestureDetector( + onTap: () { + Get.back(); + GetStorage().write('showOverviewGuidModal', false); + }, + child: Icon( + Icons.close, + color: !globalController.darkMode.value? ColorConstants.kBlack:ColorConstants.kWhite, + size: 20, + ), + ), + ), + ], + ), + SizedBox(height: 30), + CarouselSlider( + carouselController: _controller, + options: CarouselOptions( + height: 320, + // viewportFraction: 1.0, + // autoPlay: true, + enableInfiniteScroll: false, + viewportFraction: 1, + // padEnds: false, + // enlargeCenterPage: false, + // autoPlayCurve: Curves.linear, + scrollPhysics: const BouncingScrollPhysics(), + autoPlayInterval: const Duration(seconds: 3), + onPageChanged: (index, reason) { + _current.value = index; + }), + items: list.toList(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: list.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => _controller.animateToPage(entry.key), + child: Column( + children: [ + Obx( + () => Container( + width: 10, + height: 10, + margin: const EdgeInsets.symmetric( + vertical: 6.0, horizontal: 2.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: (_current == entry.key + ? ColorConstants.kPrimaryColor + : const Color(0xff858585)), + ), + ), + ) + ], + ), + ); + }).toList(), + ), + + // topBar(), + // addScale(), + // scaleList(), + // stepOnScale() + ], + ), + ), + ), + ); + } + + Column stepOnScale() { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Step on the scale', + style: TextStyle(fontSize: 20), + ), + SizedBox(height: 20), + Image.asset( + 'assets/image/overview_guide/step-on-scale.png', + width: 200, + ), + SizedBox(height: 30), + Text( + 'The scale should be placed on a flat, hard surface. Avoid carpeting or uneven tile foraccuracy.', + style: TextStyle( + fontSize: 16, + ), + ) + ], + ); + } + + Column scaleList() { + return Column( + children: [ + Text( + 'Select your scale', + style: TextStyle(fontSize: 20), + ), + SizedBox(height: 20), + Image.asset( + 'assets/image/overview_guide/list-scale.png', + width: 300, + ), + ], + ); + } + + Column addScale() { + return Column( + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 30), + Image.asset( + 'assets/image/overview_guide/scale.png', + width: 200, + ), + SizedBox(height: 30), + Text( + 'Add Scale', + style: TextStyle(fontSize: 20), + ) + ], + ); + } + + Column topBar() { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 30), + Text( + 'Please turn on Bluetooth', + style: TextStyle(fontSize: 20), + ), + SizedBox(height: 20), + Image.asset('assets/image/overview_guide/${ Platform.isAndroid?'topbar':'topbar_ios'}.png'), + SizedBox(height: 30), + Text( + Platform.isAndroid?'For Android users, make sure your location is turned on for Android 6.0 or later.':'For iOS users, make sure your Bluetooth is turned on.', + style: TextStyle( + fontSize: 16, + ), + ) + ], + ); + } +} diff --git a/gsf/lib/views/pages/biomateric.dart/account_controller.dart b/gsf/lib/views/pages/biomateric.dart/account_controller.dart new file mode 100644 index 0000000..819a64f --- /dev/null +++ b/gsf/lib/views/pages/biomateric.dart/account_controller.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +class AccountController extends GetxController { + // final box = GetStorage(); + // bool get fingerPrintStore => box.read("fingerPrint"); + RxBool switchValue1 = false.obs; + // RxBool authenticated = false.obs; +} diff --git a/gsf/lib/views/pages/biomateric.dart/face_id.dart b/gsf/lib/views/pages/biomateric.dart/face_id.dart new file mode 100644 index 0000000..7ebf35e --- /dev/null +++ b/gsf/lib/views/pages/biomateric.dart/face_id.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:local_auth/local_auth.dart'; + +class LocalAuth { + static final _auth = LocalAuthentication(); + + static Future _canAthenticate() async => + await _auth.canCheckBiometrics || await _auth.isDeviceSupported(); + + static Future authenticate() async { + try { + if (!await _canAthenticate()) return false; + return await _auth.authenticate( + localizedReason: 'Use Fingerprint or Face Id to authenticate', + options: const AuthenticationOptions( + biometricOnly: true, + useErrorDialogs: true, + stickyAuth: true, + ), + // authMessages: [ + // AndroidAuthMessages( + // signInTitle: 'Oops! Biometric authentication required!', + // cancelButton: 'No thanks', + // ), + // IOSAuthMessages( + // cancelButton: 'No thanks', + // ), + // ], + ); + // final bool didAuthenticate = await _auth.authenticate( + // localizedReason: 'Please authenticate to show account balance', + // authMessages: const [ + // AndroidAuthMessages( + // signInTitle: 'Oops! Biometric authentication required!', + // cancelButton: 'No thanks', + // ), + // IOSAuthMessages( + // cancelButton: 'No thanks', + // ), + // ]); + } catch (e) { + debugPrint('error $e'); + return false; + } + } +} diff --git a/gsf/lib/views/pages/biomateric.dart/fingerprint.dart b/gsf/lib/views/pages/biomateric.dart/fingerprint.dart new file mode 100644 index 0000000..ce3d322 --- /dev/null +++ b/gsf/lib/views/pages/biomateric.dart/fingerprint.dart @@ -0,0 +1,186 @@ +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/components/btn.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:local_auth/local_auth.dart'; + +import '../../components/btn.dart'; +// import 'dart:async'; + +class AuthApp extends StatefulWidget { + const AuthApp({Key? key}) : super(key: key); + + @override + State createState() => _AuthAppState(); +} + +class _AuthAppState extends State { + bool? _hasBioSensor; + LocalAuthentication authentication = LocalAuthentication(); + + Future _checkBio() async { + try { + _hasBioSensor = await authentication.canCheckBiometrics; + // print(_hasBioSensor); + if (_hasBioSensor!) { + _getAuth(); + } + // ignore: empty_catches + } catch (e) {} + } + + Future _getAuth() async { + bool isAuth = false; + try { + isAuth = await authentication.authenticate( + localizedReason: 'localizedReason', + options: const AuthenticationOptions( + // biometricOnly: true, + useErrorDialogs: true, + stickyAuth: true, + ), + ); + // if (isAuth) { + // Navigator.pushReplacement( + // context, + // MaterialPageRoute( + // builder: (builder) => const HomePage(), + // ), + // ); + // } + print(isAuth); + // ignore: empty_catches + } catch (e) {} + } + + @override + void initState() { + super.initState(); + _getAuth(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return SafeArea( + child: Scaffold( + backgroundColor: ColorConstants.kBlack, + body: CustomScrollView( + // shrinkWrap: true, + slivers: [ + SliverAppBar( + automaticallyImplyLeading: false, + flexibleSpace: Container( + decoration: const BoxDecoration(), + ), + pinned: true, + titleSpacing: 0, + // centerTitle: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: const Icon( + Icons.arrow_back_ios, + ), + iconSize: 22, + color: const Color(0xffCC9900), + ), + title: const Text( + 'Touch ID', + style: TextStyle( + fontFamily: 'Helvetica', + color: Color(0xffffffff), + fontSize: 28, + fontWeight: FontWeight.normal, + ), + ), + backgroundColor: ColorConstants.kBlack, + elevation: 0, + ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + SizedBox( + height: screenSize.height * 0.01, + ), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text( + 'Login smoothly without the use of any password for faster transactions.', + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 14, + color: Color(0xffffffff), + ), + ), + ), + SizedBox( + height: screenSize.height * 0.85, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 176, + height: 176, + decoration: BoxDecoration( + color: + const Color(0xff1C1C1C).withOpacity(0.66), + borderRadius: BorderRadius.circular(100), + ), + child: Center( + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + borderRadius: BorderRadius.circular(100)), + child: const Center( + child: Text( + 'check', + style: TextStyle( + fontSize: 20, + color: ColorConstants.kBlack, + ), + ), + ), + )), + ), + const SizedBox( + height: 140, + ), + // FullWidthBtn( + // btnText: 'Enable Touch ID', + // onTap: () { + // _checkBio(); + // }, + // ), + FullWdtBtn( + btnText: 'Enable Touch ID', + onTap: () { + _checkBio(); + }, + ) + // TextButton( + // onPressed: () => _checkBio(), + // child: const Text('Enable Touch ID'), + // ) + ], + ), + ), + ) + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/biomateric.dart/text_auth.dart b/gsf/lib/views/pages/biomateric.dart/text_auth.dart new file mode 100644 index 0000000..dbda280 --- /dev/null +++ b/gsf/lib/views/pages/biomateric.dart/text_auth.dart @@ -0,0 +1,58 @@ +// ignore_for_file: prefer_const_literals_to_create_immutables, prefer_const_constructors + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/biomateric.dart/face_id.dart'; + +import '../../theme.dart'; +import 'account_controller.dart'; +// import 'dart:io' show Platform; + +class AuthTest extends StatefulWidget { + const AuthTest({Key? key}) : super(key: key); + + @override + State createState() => _AuthTestState(); +} + +class _AuthTestState extends State { + AccountController accountController = Get.put(AccountController()); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Auth Test')), + body: Center( + child: Obx( + () => Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () async { + final authentic = await LocalAuth.authenticate(); + setState(() { + accountController.switchValue1.value = authentic; + }); + }, + child: const Text('Authenticate'), + ), + if (accountController.switchValue1.value) + const Text('You are authentictaed'), + if (accountController.switchValue1.value) + ElevatedButton( + onPressed: () { + setState(() { + accountController.switchValue1.value = false; + }); + }, + child: const Text('Log Out'), + ) + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/blog/blog_inner.dart b/gsf/lib/views/pages/blog/blog_inner.dart new file mode 100644 index 0000000..a18ce65 --- /dev/null +++ b/gsf/lib/views/pages/blog/blog_inner.dart @@ -0,0 +1,156 @@ +// ignore_for_file: prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class BlogDetails extends StatelessWidget { + const BlogDetails({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Blog'), + ), + body: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0), + child: Row( + children: const [ + Text( + 'Philosophy', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + Spacer(), + Text( + '2 days ago', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + const SizedBox(height: 10), + Image.asset( + 'assets/image/blog/philosophyCard.jpg', + width: Get.size.width, + fit: BoxFit.fitWidth, + ), + const SizedBox(height: 30), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: ListView.builder( + shrinkWrap: true, + itemCount: 8, + itemBuilder: (context, index) { + if (index == 7) { + return Padding( + padding: const EdgeInsets.only(bottom: 20.0), + child: Row( + children: [ + InkWell( + onTap: () { + print('Previous'); + }, + child: Row( + children: [ + Icon( + Icons.keyboard_arrow_left_rounded, + size: 25, + color: ColorConstants.kPrimaryColor, + ), + SizedBox(width: 8), + Text( + 'Previous', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kPrimaryColor), + ), + ], + ), + ), + Spacer(), + InkWell( + onTap: () { + print('Next'); + }, + child: Row( + children: [ + Text( + 'Next', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kPrimaryColor), + ), + SizedBox(width: 8), + Icon( + Icons.keyboard_arrow_right_rounded, + size: 25, + color: ColorConstants.kPrimaryColor, + ), + ], + ), + ), + ], + ), + ); + } + return Padding( + padding: const EdgeInsets.only(bottom: 22.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: const BoxDecoration( + color: ColorConstants.kPrimaryColor, + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + '${index + 1}', + style: const TextStyle( + fontSize: 16, + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + ), + ), + ), + ), + const SizedBox(width: 10), + Expanded( + child: Text( + 'The next time you find yourself continuously running things over in your mind, take note of how it affects your mood.', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ), + ], + ), + ); + }), + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/blog/blog_main.dart b/gsf/lib/views/pages/blog/blog_main.dart new file mode 100644 index 0000000..274e0b7 --- /dev/null +++ b/gsf/lib/views/pages/blog/blog_main.dart @@ -0,0 +1,293 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; +import 'blog_inner.dart'; + +class BlogMain extends StatefulWidget { + const BlogMain({Key? key}) : super(key: key); + + @override + State createState() => _BlogMainState(); +} + +class _BlogMainState extends State with TickerProviderStateMixin { + @override + Widget build(BuildContext context) { + TabController tabController = TabController(length: 4, vsync: this); + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Blog'), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0), + child: Column( + children: [ + SizedBox( + height: 35, + child: TabBar( + isScrollable: true, + labelPadding: + const EdgeInsets.symmetric(horizontal: 20, vertical: 0), + labelColor: ColorConstants.kBlack, + unselectedLabelColor: Colors.white, + labelStyle: const TextStyle( + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontSize: 16, + ), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + ), + indicator: BoxDecoration( + color: ColorConstants.kWhite, + borderRadius: BorderRadius.circular(50), + ), + controller: tabController, + tabs: const [ + Tab( + text: 'All', + ), + Tab( + text: 'About Getsetfit', + ), + Tab( + text: 'Workout', + ), + Tab( + text: 'Functional Training', + ), + ], + ), + ), + SizedBox(height: 15), + CupertinoSearchTextField( + decoration: BoxDecoration( + color: Color(0xff212121), + borderRadius: BorderRadius.circular(30), + ), + padding: EdgeInsetsDirectional.fromSTEB(10, 15, 10, 15), + // prefixInsets + prefixInsets: EdgeInsetsDirectional.fromSTEB(10, 10, 0, 10), + itemSize: 25, + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + SizedBox(height: 30), + Expanded( + // height: Get.size.height - 230, + child: TabBarView( + controller: tabController, + children: [ + allWidgetTab(), + allWidgetTab(), + allWidgetTab(), + allWidgetTab(), + ], + ), + ), + ], + ), + ), + ); + } + + allWidgetTab() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Top News', + style: TextStyle( + fontSize: 22, + color: Color(0xff858585), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w700, + ), + ), + SizedBox(height: 15), + SizedBox( + height: 280, + child: ListView.builder( + itemCount: 2, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => philosophyCard(), + ), + ), + SizedBox(height: 10), + Expanded( + child: ListView.builder( + itemCount: 10, + physics: ScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) => cardList(), + ), + ) + ], + ); + } + + philosophyCard() { + return OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.only(right: 20.0), + child: SizedBox( + width: Get.size.width * 0.8, + child: Column( + children: [ + Container( + height: 190, + // width: Get.size.width * 0.8, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/blog/philosophyCard.jpg'), + fit: BoxFit.fitWidth, + alignment: Alignment.topCenter, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Align( + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.circular(15), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, vertical: 7), + child: Text( + 'Philosophy', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ), + ), + ), + ), + ), + ), + SizedBox(height: 10), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + children: [ + Row( + children: const [ + Text( + 'Trending', + style: TextStyle( + fontSize: 14, + color: Color(0xff919191), + fontFamily: 'SFPRO', + ), + ), + Spacer(), + Text( + '2 days ago', + style: TextStyle( + fontSize: 14, + color: Color(0xff919191), + fontFamily: 'SFPRO', + ), + ), + ], + ), + SizedBox(height: 10), + Text( + '8 Steps To Help You Stop Overthinking Everything', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ) + ], + ), + ), + ), + openBuild: BlogDetails()); + } + + cardList() { + return OpenContainerWrappers( + closeBuild: Container( + color: ColorConstants.kBlack, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + child: InkWell( + // onTap: (() => Get.to(() => BlogDetails())), + child: Row( + children: [ + Expanded( + flex: 0, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: const Color(0xff707070), + ), + borderRadius: BorderRadius.circular(100), + ), + child: Image.asset( + 'assets/image/avatar.png', + ), + ), + ), + const SizedBox(width: 10), + Expanded( + // flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + 'What is the difference between fat loss and weight loss? What is it you want?', + style: TextStyle( + fontSize: 16, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + SizedBox(height: 8), + Text( + 'May 03, 2022 11:33 AM IST', + style: TextStyle( + fontSize: 14, + color: Color(0xff858585), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ], + ), + ), + ), + ), + openBuild: BlogDetails()); + } +} diff --git a/gsf/lib/views/pages/community/community.dart b/gsf/lib/views/pages/community/community.dart new file mode 100644 index 0000000..1ccedef --- /dev/null +++ b/gsf/lib/views/pages/community/community.dart @@ -0,0 +1,485 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../components/appbar.dart'; +import '../../../modals/member_modal.dart'; +import '../../theme.dart'; + +class CommunityMember extends StatefulWidget { + final List communityModel; + const CommunityMember({required this.communityModel, Key? key}) + : super(key: key); + + @override + State createState() => _CommunityMemberState(); +} + +class _CommunityMemberState extends State { + // bool fullDesc = false; + final CarouselController carouselController = CarouselController(); + var sliderPage = 0.obs; + + @override + Widget build(BuildContext context) { + final screenSize = Get.mediaQuery.size; + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Community'), + ), + body: ListView.builder( + // physics: const BouncingScrollPhysics(), + itemCount: widget.communityModel.length, + itemBuilder: (context, index) => Container( + margin: const EdgeInsets.all(10), + width: screenSize.width * 0.8, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff191919), + borderRadius: BorderRadius.circular(11), + boxShadow: [ + BoxShadow( + spreadRadius: 2, + blurRadius: 10, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.2) + : ColorConstants.kWhite.withOpacity(0)) + ]), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: GestureDetector( + onTap: () => bottomSheetDesc(widget.communityModel[index]), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 3, + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.network( + "https://thegsf.co/public/uploads/testimonial/${widget.communityModel[index].testimonialData!.first.images}", + width: 100, + height: 150, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + flex: 6, + child: Padding( + padding: const EdgeInsets.only(left: 20.0), + child: Column( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${widget.communityModel[index].title}', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor), + ), + // SizedBox( + // height: 20, + // child: ListView.builder( + // itemCount: 5, + // scrollDirection: Axis.horizontal, + // itemBuilder: (context, index1) { + // if (index1 < + // widget.communityModel[index].rating!) { + // return Icon( + // Icons.star, + // size: 18, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kPrimaryColor, + // ); + // } else { + // return const Icon( + // Icons.star_outline, + // size: 18, + // color: Color(0xff8D8D8D), + // ); + // } + // }, + // ), + // ), + const SizedBox(height: 10), + StatefulBuilder( + builder: (BuildContext context, setState) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //!widget.communityModel[index].isExpanded + (widget.communityModel[index].description! + .length > + 40) + ? GestureDetector( + // onTap: () => bottomSheetDesc( + // widget.communityModel[index]), + child: Text( + '${widget.communityModel[index].description}', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + height: 1.3, + ), + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + ) + : Text( + '${widget.communityModel[index].description}', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + height: 1.3, + ), + ), + const SizedBox(height: 5), + ], + ); + }, + ), + // RichText( + // text: TextSpan( + // children: [ + // TextSpan( + // text: '${communityModel[index].desc}', + // style: const TextStyle( + // fontSize: 12, + // color: Color(0xffD9D9D9), + // height: 1.3, + // overflow: TextOverflow.ellipsis, + // ), + // ), + + // ], + // ), + // maxLines: 4, + // ), + const SizedBox(height: 5), + Text( + '${widget.communityModel[index].userName}', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // const Expanded( + // child: SizedBox(), + // flex: 2, + // ), + // Expanded( + // flex: 6, + // child: Padding( + // padding: const EdgeInsets.only(left: 20.0), + // child: Column( + // // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // '${communityModel[index].title}', + // style: const TextStyle( + // fontSize: 12, + // color: ColorConstants.kPrimaryColor), + // ), + // SizedBox( + // height: 20, + // child: ListView.builder( + // itemCount: 5, + // scrollDirection: Axis.horizontal, + // itemBuilder: (context, index1) { + // if (index1 < communityModel[index].rating!) { + // return const Icon( + // Icons.star, + // size: 18, + // color: ColorConstants.kPrimaryColor, + // ); + // } else { + // return const Icon( + // Icons.star_outline, + // size: 18, + // color: Color(0xff8D8D8D), + // ); + // } + // }, + // ), + // ), + // const SizedBox(height: 10), + // Text( + // '${communityModel[index].desc}', + // style: const TextStyle( + // fontSize: 12, + // color: Color(0xffD9D9D9), + // height: 1.3), + // ), + // const SizedBox(height: 5), + // Text( + // '${communityModel[index].memberName}', + // style: const TextStyle( + // fontSize: 12, + // color: ColorConstants.kWhite, + // fontWeight: FontWeight.w600, + // ), + // ) + // ], + // ), + // ), + // ), + // ], + // ), + ], + ), + ), + ), + ), + ), + ); + } + + bottomSheetDesc(User data) { + // return Get.bottomSheet( + // Container( + // color: ColorConstants.kBlack, + // height: Get.height, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Image.network( + // '${data.img}', + // fit: BoxFit.cover, + // height: 250, + // width: Get.width, + // ), + // const SizedBox(height: 20), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 20.0), + // child: Text( + // '${data.title}', + // style: const TextStyle( + // fontSize: 16, color: ColorConstants.kPrimaryColor), + // ), + // ), + // const SizedBox(height: 10), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 20.0), + // child: SizedBox( + // height: 20, + // child: ListView.builder( + // itemCount: 5, + // scrollDirection: Axis.horizontal, + // itemBuilder: (context, index1) { + // if (index1 < data.rating!) { + // return const Icon( + // Icons.star, + // size: 18, + // color: ColorConstants.kPrimaryColor, + // ); + // } else { + // return const Icon( + // Icons.star_outline, + // size: 18, + // color: Color(0xff8D8D8D), + // ); + // } + // }, + // ), + // ), + // ), + // const SizedBox(height: 10), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 20.0), + // child: Text( + // data.desc, + // style: const TextStyle( + // fontSize: 14, + // color: Color(0xffD9D9D9), + // height: 1.3, + // ), + // ), + // ), + // ], + // ), + // ), + // backgroundColor: ColorConstants.kBlack, + // ); + return showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) { + // print(data.img); + + return StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + child: Container( + decoration: const BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25.0), + topRight: Radius.circular(25.0), + ), + ), + height: Get.height * 0.85, + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Image.network( + // '${data.img}', + // fit: BoxFit.cover, + // height: 250, + // width: Get.width, + // ), + Stack( + children: [ + CarouselSlider.builder( + carouselController: CarouselController(), + itemCount: data.testimonialData!.length, + itemBuilder: (context, index, realIndex) { + return Image.network( + 'https://thegsf.co/public/uploads/testimonial/${data.testimonialData![index].images}', + fit: BoxFit.cover, + // height: 400, + width: Get.width, + alignment: Alignment.topCenter, + ); + }, + options: CarouselOptions( + autoPlay: true, + height: 300, + autoPlayAnimationDuration: + const Duration(seconds: 3), + viewportFraction: 0.8, + enableInfiniteScroll:false, + onPageChanged: (index, reason) { + setState(() { + sliderPage.value = index; + }); + }), + ), + + // Icon(Icons.arrow_circle_right_outlined) + ], + ), + const SizedBox( + height: 5, + ), + data.testimonialData!.length>1?Row( + mainAxisAlignment: MainAxisAlignment.center, + children: List.generate( + data.testimonialData!.length, + (index) => GestureDetector( + onTap: () => + carouselController.animateToPage(index), + child: Container( + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.circular(25)), + width: 12, + height: sliderPage.value == index ? 4 : 2, + margin: const EdgeInsets.symmetric( + horizontal: 3.0, + ), + ), + ), + ), + ):const SizedBox(), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + '${data.title}', + style: const TextStyle( + fontSize: 16, + color: ColorConstants.kPrimaryColor), + ), + ), + const SizedBox(height: 10), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 20.0), + // child: SizedBox( + // height: 20, + // child: ListView.builder( + // itemCount: 5, + // scrollDirection: Axis.horizontal, + // itemBuilder: (context, index1) { + // if (index1 < data.rating!) { + // return const Icon( + // Icons.star, + // size: 18, + // color: ColorConstants.kPrimaryColor, + // ); + // } else { + // return const Icon( + // Icons.star_outline, + // size: 18, + // color: Color(0xff8D8D8D), + // ); + // } + // }, + // ), + // ), + // ), + // const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + data.description!, + style: const TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + height: 1.3, + ), + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + '${data.userName}', + style: const TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ) + ], + ), + ), + ), + ); + }); + }); + } +} diff --git a/gsf/lib/views/pages/contact_us.dart b/gsf/lib/views/pages/contact_us.dart new file mode 100644 index 0000000..c5c7f73 --- /dev/null +++ b/gsf/lib/views/pages/contact_us.dart @@ -0,0 +1,1222 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/services/contact_us_service.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../view_model/home_page_controller.dart'; +import '../components/appbar.dart'; +import '../components/btn.dart'; +import '../theme.dart'; + +class ContactUs extends StatefulWidget { + const ContactUs({Key? key}) : super(key: key); + + @override + State createState() => _ContactUsState(); +} + +class _ContactUsState extends State { + final brightness = Get.theme.brightness; + var _formKey = GlobalKey(); + final TextEditingController _fullName = TextEditingController(); + final TextEditingController _email = TextEditingController(); + final TextEditingController _phone = TextEditingController(); + final TextEditingController _subject = TextEditingController(); + final TextEditingController _message = TextEditingController(); + final RoundedLoadingButtonController _btnController = + RoundedLoadingButtonController(); + HomePageController homePageController = Get.put(HomePageController()); + + @override + void initState() { + super.initState(); + _fullName.clear(); + _email.clear(); + _phone.clear(); + _subject.clear(); + _message.clear(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Contact Us'), + ), + body: GestureDetector( + onTap: () { + Get.focusScope?.unfocus(); + }, + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Form( + key: _formKey, + child: Column( + children: [ + const SizedBox(height: 20), + TextFormField( + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Name", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _fullName, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your name'; + } + return null; + }, + ), + customSpace(), + TextFormField( + keyboardType: TextInputType.emailAddress, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Email ID", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _email, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email id'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + customSpace(), + TextFormField( + keyboardType: TextInputType.phone, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Contact Number", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _phone, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your contact number'; + } + if (!RegExp(r"^[0-9]{10,12}$").hasMatch(value)) { + return 'Number allowed between 10-12 digits'; + } + return null; + }, + onSaved: (name) {}, + ), + customSpace(), + TextFormField( + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Subject", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _subject, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your subject'; + } + return null; + }, + ), + customSpace(), + TextFormField( + maxLines: 8, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Type you're message", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _message, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your message'; + } + return null; + }, + ), + customSpace(), + StreamBuilder( + stream: _btnController.stateStream, + builder: (context, snapshot) { + return RoundedLoadingButton( + color: ColorConstants.kPrimaryColor, + valueColor: ColorConstants.kBlack, + successColor: ColorConstants.kPrimaryColor, + successIcon: Icons.done_all_rounded, + errorColor: ColorConstants.kErroColor, + loaderStrokeWidth: 2.4, + child: const Text( + 'Submit', + style: TextStyle(fontWeight: FontWeight.bold), + ), + controller: _btnController, + onPressed: () { + if (_formKey.currentState!.validate()) { + ContactUsService() + .uploadDetails( + _fullName.text, + _email.text, + _phone.text, + _subject.text, + _message.text, + ) + .then((response) { + try { + if (jsonDecode(response.body)['status'] == + "Success") { + _btnController.success(); + thanksModalBottomsheet(); + } else { + _btnController.error(); + } + } catch (e) { + _btnController.error(); + Timer.periodic(const Duration(seconds: 2), + (timer) { + _btnController.reset(); + }); + } + }); + } else { + _btnController.reset(); + } + }, + ); + }, + ), + + /* + StatefulBuilder( + builder: (context, setBtnState) { + return Column( + children: [ + Visibility( + visible: !isSubmitBtnPressed, + child: FullWdtBtn( + btnText: 'Submit', + onTap: () { + if (_formKey.currentState!.validate()) { + setBtnState(() { + isSubmitBtnPressed = !isSubmitBtnPressed; + }); + debugPrint("Name: ${_fullName.text}"); + debugPrint("Email: ${_email.text}"); + debugPrint("Contact: ${_phone.text}"); + debugPrint("Subject: ${_subject.text}"); + debugPrint("Message: ${_message.text}"); + ContactUsService() + .uploadDetails( + _fullName.text, + _email.text, + _phone.text, + _subject.text, + _message.text, + ) + .then((value) { + setBtnState(() { + isSubmitBtnPressed = !isSubmitBtnPressed; + }); + if (value.statusCode == 200) { + _fullName.clear(); + _email.clear(); + _phone.clear(); + _subject.clear(); + _message.clear(); + thanksModalBottomsheet(); + } + }); + } + }, + ), + ), + Visibility( + visible: isSubmitBtnPressed, + child: const CircularProgressIndicator( + color: ColorConstants.kPrimaryColor, + ), + ) + ], + ); + }, + ), + */ + + customSpace(), + ], + ), + ), + ), + ), + ); + } + + thanksModalBottomsheet() { + return Get.bottomSheet( + + SizedBox( + height: 300, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + Image.asset('assets/image/thanksContact.png'), + const SizedBox(height: 10), + const Text( + "'Thank You For Contacting GSF. Keep Shredding'", + style: TextStyle( + fontSize: 19, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 80.0), + child: FullWdtBtn( + btnText: 'Explore the App', + onTap: () { + Get.back(); + Get.back(); + homePageController.updateBottomNavIndex(0); + },), + ), + const Spacer(), + ], + ), + ), + barrierColor: Colors.black.withOpacity(1), + isDismissible: false, + backgroundColor: const Color(0xff212121), + enableDrag:false, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + ); + } + + customSpace() { + return const SizedBox(height: 30); + } +} + +/* +class ContactUs extends StatelessWidget { + const ContactUs({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + final _formKey = GlobalKey(); + final TextEditingController _fullName = TextEditingController(); + final TextEditingController _email = TextEditingController(); + final TextEditingController _phone = TextEditingController(); + final TextEditingController _subject = TextEditingController(); + final TextEditingController _message = TextEditingController(); + final RoundedLoadingButtonController _btnController = + RoundedLoadingButtonController(); + + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Contact Us'), + ), + body: GestureDetector( + onTap: () { + Get.focusScope?.unfocus(); + }, + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Form( + key: _formKey, + child: Column( + children: [ + const SizedBox(height: 20), + TextFormField( + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Name", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _fullName, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your name'; + } + return null; + }, + ), + customSpace(), + TextFormField( + keyboardType: TextInputType.emailAddress, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Email ID", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _email, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email id'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + customSpace(), + TextFormField( + keyboardType: TextInputType.phone, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Contact Number", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _phone, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your contact number'; + } + if (!RegExp(r"^[0-9]{10,12}$").hasMatch(value)) { + return 'Number allowed between 10-12 digits'; + } + return null; + }, + onSaved: (name) {}, + ), + customSpace(), + TextFormField( + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Subject", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _subject, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your subject'; + } + return null; + }, + ), + customSpace(), + TextFormField( + maxLines: 8, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Type you're message", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + isDense: true, + ), + controller: _message, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your message'; + } + return null; + }, + ), + customSpace(), + StatefulBuilder(builder: (context, setBtnState) { + return RoundedLoadingButton( + color: ColorConstants.kPrimaryColor, + valueColor: ColorConstants.kBlack, + loaderStrokeWidth: 2.4, + child: const Text( + 'Submit', + style: TextStyle(fontWeight: FontWeight.bold), + ), + controller: _btnController, + onPressed: () { + if (_formKey.currentState!.validate()) { + _btnController.reset(); + setBtnState(() { + // _btnController. + }); + } + }, + ); + }), + /* + StatefulBuilder( + builder: (context, setBtnState) { + return Column( + children: [ + Visibility( + visible: !isSubmitBtnPressed, + child: FullWdtBtn( + btnText: 'Submit', + onTap: () { + if (_formKey.currentState!.validate()) { + setBtnState(() { + isSubmitBtnPressed = !isSubmitBtnPressed; + }); + debugPrint("Name: ${_fullName.text}"); + debugPrint("Email: ${_email.text}"); + debugPrint("Contact: ${_phone.text}"); + debugPrint("Subject: ${_subject.text}"); + debugPrint("Message: ${_message.text}"); + ContactUsService() + .uploadDetails( + _fullName.text, + _email.text, + _phone.text, + _subject.text, + _message.text, + ) + .then((value) { + setBtnState(() { + isSubmitBtnPressed = !isSubmitBtnPressed; + }); + if (value.statusCode == 200) { + _fullName.clear(); + _email.clear(); + _phone.clear(); + _subject.clear(); + _message.clear(); + thanksModalBottomsheet(); + } + }); + } + }, + ), + ), + Visibility( + visible: isSubmitBtnPressed, + child: const CircularProgressIndicator( + color: ColorConstants.kPrimaryColor, + ), + ) + ], + ); + }, + ), + */ + customSpace(), + ], + ), + ), + ), + ), + ); + } + + thanksModalBottomsheet() { + return Get.bottomSheet( + SizedBox( + height: 300, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + Image.asset('assets/image/thanksContact.png'), + const SizedBox(height: 10), + const Text( + "'Thank You For Contacting GSF. Keep Shredding'", + style: TextStyle( + fontSize: 19, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 80.0), + child: FullWdtBtn( + btnText: 'Explore the App', + onTap: () { + Get.offAll( + () => const Home(), + ); + }), + ), + const Spacer(), + ], + ), + ), + barrierColor: Colors.black.withOpacity(1), + isDismissible: false, + backgroundColor: const Color(0xff212121), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + // side: BorderSide(width: 5, color: Colors.black), + ), + // enableDrag: false, + ); + } + + customSpace() { + return const SizedBox(height: 30); + } + +} +*/ \ No newline at end of file diff --git a/gsf/lib/views/pages/courses/courses.dart b/gsf/lib/views/pages/courses/courses.dart new file mode 100644 index 0000000..1fc50a9 --- /dev/null +++ b/gsf/lib/views/pages/courses/courses.dart @@ -0,0 +1,102 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:gsp_app/views/pages/courses/courses_overview.dart'; + +import '../../theme.dart'; +import '../vimeo_video_plyaer.dart'; + +class Courses extends StatefulWidget { + const Courses({Key? key}) : super(key: key); + + @override + State createState() => _CoursesState(); +} + +class _CoursesState extends State { + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(70), + child: CustomAppBars(titleHead: 'Courses'), + ), + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: GridView.builder( + shrinkWrap: true, + primary: false, + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 200, + childAspectRatio: 1, + crossAxisSpacing: 20, + mainAxisSpacing: 20, + ), + itemCount: 15, + itemBuilder: (BuildContext context, int index) { + return OpenContainerWrappers( + closeBuild: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(4), + child: Image.asset( + 'assets/image/courses/fitness.jpg', + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Healthy with GSF', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + const SizedBox(height: 2), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Health is a state of complete physical, mental and social well-being and not merely the absence of disease or infirmity.', + style: TextStyle( + fontSize: 15, + color: (brightness == Brightness.light) + ? Colors.grey + : ColorConstants.kWhite, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + openBuild: CoursesOverview(), + ); + }, + ), + ), + SizedBox(height: 20), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/courses/courses_overview.dart b/gsf/lib/views/pages/courses/courses_overview.dart new file mode 100644 index 0000000..21970f8 --- /dev/null +++ b/gsf/lib/views/pages/courses/courses_overview.dart @@ -0,0 +1,166 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/theme.dart'; + +import '../vimeo_video_plyaer.dart'; + +class CoursesOverview extends StatefulWidget { + const CoursesOverview({Key? key}) : super(key: key); + + @override + State createState() => _CoursesOverviewState(); +} + +class _CoursesOverviewState extends State { + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars(titleHead: 'Courses Overview'), + ), + body: Column( + children: [ + Image.asset( + 'assets/image/courses/fitness.jpg', + width: Get.size.width, + fit: BoxFit.fitWidth, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + Text( + 'HIIT - Full Body', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 10), + Text( + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever.', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.7) + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 20), + Text( + 'Videos', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 10), + Expanded( + child: ListView.builder( + shrinkWrap: true, + itemCount: 5, + itemBuilder: (context, index) => VideosList(), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} + +class VideosList extends StatelessWidget { + const VideosList({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + Image.asset( + 'assets/image/courses/fitness.jpg', + width: Get.size.width, + fit: BoxFit.fitWidth, + ), + Positioned( + top: 0, + left: 0, + right: 0, + bottom: 0, + child: Align( + child: Container( + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor.withOpacity(0.5), + shape: BoxShape.circle, + ), + child: GestureDetector( + // onTap: () => Get.to( + // () => const VimeoPlayer(), + // ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow, + color: ColorConstants.kBlack, + size: 35, + ), + ), + ), + ), + ), + ) + ], + ), + SizedBox(height: 5), + const SizedBox(height: 10), + Text( + 'HIIT - Full Body', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 10), + Text( + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.7) + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 30), + ], + ); + } +} diff --git a/gsf/lib/views/pages/diet_plan/basic_consumption_profiling.dart b/gsf/lib/views/pages/diet_plan/basic_consumption_profiling.dart new file mode 100644 index 0000000..f23287f --- /dev/null +++ b/gsf/lib/views/pages/diet_plan/basic_consumption_profiling.dart @@ -0,0 +1,185 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class BasicConsumptionProfiling extends StatelessWidget { + const BasicConsumptionProfiling({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // RxBool isChecked = false.obs; + List primaryGoals = [ + 'Vegan', + 'Vegetarian', + 'Eggs', + 'Chicken', + 'Lamb', + 'Fish', + ]; + List allergy = [ + 'Nuts', + 'Milk', + 'Soya', + 'Gluten', + 'Mention Text Bar', + ]; + List health = [ + 'Diabetes', + 'Cholesterol', + 'High Blood Pressure', + 'Low Blood Pressure', + 'Arthritis', + ]; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Basic Consumption Profiling'), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Primary Goals', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + primaryGoals.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + primaryGoals[index], + ), + ), + ), + ), + SizedBox(height: 40), + const Text( + 'Allergies', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + allergy.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + allergy[index], + ), + ), + ), + ), + SizedBox(height: 40), + const Text( + 'Allergies', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + health.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + health[index], + ), + ), + ), + ), + SizedBox(height: 40), + FullWdtBtn( + btnText: 'Calculate BMR', + onTap: () {}, + ) + ], + ), + ), + ), + ); + } + + checkboxlistTileBox(String listTitle) { + RxBool isChecked = false.obs; + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 19, + height: 19, + decoration: BoxDecoration( + color: Color(0xff212121), + borderRadius: BorderRadius.circular(3), + ), + child: Theme( + data: ThemeData( + backgroundColor: Color(0xff212121), + checkboxTheme: CheckboxThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3), + ), + ), + ), + child: Obx( + () => Checkbox( + side: const BorderSide(color: Colors.transparent), + checkColor: ColorConstants.kBlack, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + activeColor: ColorConstants.kPrimaryColor, + value: isChecked.value, + onChanged: (value) { + isChecked.value = !isChecked.value; + }, + ), + ), + ), + ), + SizedBox(width: 10), + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + listTitle, + style: TextStyle( + fontSize: 16, + fontFamily: 'SFPRO', + color: Color(0xffC8C8C8), + ), + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/diet_plan/diet_chart_preview.dart b/gsf/lib/views/pages/diet_plan/diet_chart_preview.dart new file mode 100644 index 0000000..f5141ac --- /dev/null +++ b/gsf/lib/views/pages/diet_plan/diet_chart_preview.dart @@ -0,0 +1,114 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; +import '../../../modals/diet_chart_model.dart'; +import '../../../repository/services/cj/diet_chart_service.dart'; +import '../../../view_model/diet_chart_controller.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class DietChartPlan extends StatefulWidget { + const DietChartPlan({Key? key}) : super(key: key); + + @override + State createState() => _DietChartPlanState(); +} + +class _DietChartPlanState extends State { + DietChartController dietChartController = Get.put(DietChartController()); + + final List items = ['Veg', 'Non-Veg']; + String? selectedValue; + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Diet Chart Preview', + rightAction: DropdownButtonHideUnderline( + child: DropdownButton2( + isExpanded: true, + hint: const Text('veg'), + items: items + .map( + (item) => DropdownMenuItem( + value: item, + child: Text( + item, + style: const TextStyle( + fontSize: 14, + ), + ), + ), + ) + .toList(), + value: selectedValue, + onChanged: (value) { + setState(() { + dietChartController.vegNveg.value = value as String; + selectedValue = value; + }); + }, + buttonStyleData: const ButtonStyleData( + padding: EdgeInsets.all(0), + height: 40, + width: 80, + ), + dropdownStyleData: const DropdownStyleData( + maxHeight: 100, + ), + ), + ), + ), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + children: [ + // const SizedBox(height: 20), + // SizedBox( + // width: Get.size.width, + // child: Image.asset( + // 'assets/image/diet_chart_plan.png', + // fit: BoxFit.cover, + // ), + // ), + FutureBuilder( + future: DietChartServices().getDietChartPlan(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + DietChartModel chartData = snapshot.data!.data[0]; + + + return Expanded( + child: SizedBox( + width: Get.size.width, + child: SfPdfViewer.network(chartData.image)), + ); + } + return Image.asset("assets/image/placeholder.jpg"); + }, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/diet_plan/loading.dart b/gsf/lib/views/pages/diet_plan/loading.dart new file mode 100644 index 0000000..c19f792 --- /dev/null +++ b/gsf/lib/views/pages/diet_plan/loading.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../theme.dart'; + +class DietLoading extends StatelessWidget { + const DietLoading({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/loadder.svg'), + const SizedBox(height: 40), + const Text( + 'We are Making the Perfect Diet\nChart for you', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 30), + const Text( + 'Please Stand on the scale to Calculate your BMR', + style: TextStyle( + fontSize: 16, + color: Color(0xff858585), + fontFamily: 'SFPRO', + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/diet_plan/my_diet.dart b/gsf/lib/views/pages/diet_plan/my_diet.dart new file mode 100644 index 0000000..62cc708 --- /dev/null +++ b/gsf/lib/views/pages/diet_plan/my_diet.dart @@ -0,0 +1,155 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class MyDietPlan extends StatelessWidget { + const MyDietPlan({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // RxBool isChecked = false.obs; + List primaryGoals = [ + 'Weight Loss', + 'Weight Gain', + 'Muscle Gain', + 'Weight Maintenance', + 'Weight Loss', + 'Weight Loss', + 'Endurance Gain', + ]; + List secondaryGoals = [ + 'Reduce Blood Sugar Level', + 'Reduce Blood Pressure', + 'Reduce Stress', + 'Detox', + 'Endurance Gain', + ]; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'My Diet Plans'), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Primary Goals', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + primaryGoals.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + primaryGoals[index], + ), + ), + ), + ), + SizedBox(height: 40), + const Text( + 'Secondary Goals', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + secondaryGoals.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + secondaryGoals[index], + ), + ), + ), + ), + SizedBox(height: 40), + FullWdtBtn( + btnText: 'Continue!', + onTap: () {}, + ) + ], + ), + ), + ), + ); + } + + checkboxlistTileBox(String listTitle) { + RxBool isChecked = false.obs; + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 19, + height: 19, + decoration: BoxDecoration( + color: Color(0xff212121), + borderRadius: BorderRadius.circular(3), + ), + child: Theme( + data: ThemeData( + backgroundColor: Color(0xff212121), + checkboxTheme: CheckboxThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3), + ), + ), + ), + child: Obx( + () => Checkbox( + side: const BorderSide(color: Colors.transparent), + checkColor: ColorConstants.kBlack, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + activeColor: ColorConstants.kPrimaryColor, + value: isChecked.value, + onChanged: (value) { + isChecked.value = !isChecked.value; + }, + ), + ), + ), + ), + SizedBox(width: 10), + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + listTitle, + style: TextStyle( + fontSize: 16, + fontFamily: 'SFPRO', + color: Color(0xffC8C8C8), + ), + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/diet_plan/my_diet_activity.dart b/gsf/lib/views/pages/diet_plan/my_diet_activity.dart new file mode 100644 index 0000000..99d6166 --- /dev/null +++ b/gsf/lib/views/pages/diet_plan/my_diet_activity.dart @@ -0,0 +1,151 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class MyDietPlanActivity extends StatelessWidget { + const MyDietPlanActivity({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // RxBool isChecked = false.obs; + List activitiyLevel = [ + 'No Activity', + 'Lightly Active [1 - 3 Days a week]', + 'Moderately Active [3 - 5 Days a week]', + 'Very Active [6 - 7 Days a week]' + ]; + List desiredBodyType = [ + 'Basic-Fit', + 'Athletic', + 'Shredded', + 'Bulk' + ]; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'My Diet Plans'), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Activity Level', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + activitiyLevel.length, + (int index) => SizedBox( + width: Get.size.width * 8, + child: checkboxlistTileBox( + activitiyLevel[index], + ), + ), + ), + ), + SizedBox(height: 40), + const Text( + 'Desired Body Type', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 15), + Wrap( + spacing: 0, + runSpacing: 15, + children: List.generate( + desiredBodyType.length, + (int index) => SizedBox( + width: Get.size.width * 0.45, + child: checkboxlistTileBox( + desiredBodyType[index], + ), + ), + ), + ), + SizedBox(height: 40), + FullWdtBtn( + btnText: 'Continue!', + onTap: () {}, + ) + ], + ), + ), + ), + ); + } + + checkboxlistTileBox(String listTitle) { + RxBool isChecked = false.obs; + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 19, + height: 19, + decoration: BoxDecoration( + color: Color(0xff212121), + borderRadius: BorderRadius.circular(3), + ), + child: Theme( + data: ThemeData( + backgroundColor: Color(0xff212121), + checkboxTheme: CheckboxThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3), + ), + ), + ), + child: Obx( + () => Checkbox( + side: const BorderSide(color: Colors.transparent), + checkColor: ColorConstants.kBlack, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + activeColor: ColorConstants.kPrimaryColor, + value: isChecked.value, + onChanged: (value) { + isChecked.value = !isChecked.value; + }, + ), + ), + ), + ), + SizedBox(width: 10), + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 0.0), + child: Text( + listTitle, + style: TextStyle( + fontSize: 16, + fontFamily: 'SFPRO', + color: Color(0xffC8C8C8), + ), + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/faq/Knowledgebase.dart b/gsf/lib/views/pages/faq/Knowledgebase.dart new file mode 100644 index 0000000..28fe85c --- /dev/null +++ b/gsf/lib/views/pages/faq/Knowledgebase.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class KnowledgeBase extends StatelessWidget { + const KnowledgeBase({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/gsf/lib/views/pages/faq/about_gsf.dart b/gsf/lib/views/pages/faq/about_gsf.dart new file mode 100644 index 0000000..97b11c9 --- /dev/null +++ b/gsf/lib/views/pages/faq/about_gsf.dart @@ -0,0 +1,565 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/vimeo_video_plyaer.dart'; +import 'package:gsp_app/repository/services/about_service.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:shimmer/shimmer.dart'; +import 'package:transparent_image/transparent_image.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +import '../../components/appbar.dart'; +import '../../../modals/about_model.dart'; +import '../../theme.dart'; + +class AboutGSF extends StatefulWidget { + const AboutGSF({Key? key}) : super(key: key); + + @override + State createState() => _AboutGSFState(); +} + +class _AboutGSFState extends State { + final brightness = Get.theme.brightness; + // late final PodPlayerController controller; + + @override + void dispose() { + // controller.dispose(); + super.dispose(); + } + + List ItemOfCout = [ + 'Torch those calories with heart-thumping live workouts and recorded workouts that you can do from anywhere.', + 'Get personalized diet plans to fuel you for the day and propel you toward building lean muscle and burning fat.', + 'Access your body stats, such as weight, body fat percentage, heart rate, calories burned, etc., directly from the app.', + 'Connect with other fitness enthusiasts in the GSF community and motivate each other to achieve your fitness goals.', + 'Get amazing rewards for every step you take and increase your rank on the GSF leaderboard.' + ]; + + int listItemCount = 0; + + @override + Widget build(BuildContext context) { + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'About GETSETFIT'), + ), + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + const SizedBox(height: 28), + // FadeInImage.memoryNetwork( + // placeholder: kTransparentImage, + // image: + // 'http://gsf.betadelivery.com/public/uploads/about_us/1679392874.jpg', + // ), + Image.asset('assets/image/about_us.jpeg'), + const SizedBox(height: 24), + // Text( + // 'GetSetFit is abvirtual Fitness.', + // textAlign: TextAlign.justify, + // style: TextStyle( + // fontSize: 18, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : Color(0xffC2C2C2), + // fontFamily: 'SFPRO', + // fontWeight: FontWeight.w400, + // ), + // ), + SizedBox(height: 10), + Align( + alignment: Alignment.centerLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Text('Making Fitness Accessible To All'), + // SizedBox(height: 10), + Text( + 'GETSETFIT is a Global fitness community, simplifying fitness for every individual. With us you discover the best in you each day – be it a beginner or someone who is seasoned. Our BIOSCALE will tell you just enough about your body to help you elevate your fitness. Peoples experience is the HEART of GETSETFIT.'), + SizedBox(height: 10), + + // ListView.builder( + // itemCount: ItemOfCout.length, + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + // itemBuilder: (context, index) { + // return Padding( + // padding: const EdgeInsets.only(bottom: 12), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Container( + // padding: EdgeInsets.all(6), + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor, + // shape: BoxShape.circle, + // ), + // child: Text( + // '${index+1}', + // textAlign: TextAlign.justify, + // style: TextStyle(color: Colors.black), + // ), + // ), + // SizedBox(width: 12), + // Expanded( + // child: Text(ItemOfCout[index]), + // ) + // ], + // ), + // ); + // }, + // ), + // Padding( + // padding: const EdgeInsets.only(bottom: 12), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Container( + // padding: EdgeInsets.all(6), + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor, + // shape: BoxShape.circle, + // ), + // child: Text( + // listItemCount.toString(), + // textAlign: TextAlign.justify, + // style: TextStyle(color: Colors.black), + // ), + // ), + // SizedBox(width: 12), + // Expanded( + // child: Text("No item found"), + // ) + // ], + // ), + // ), + ], + ), + ), + ], + ), + ), + ) + +// FutureBuilder>( +// future: AboutService().fetchAbout(), +// builder: (context, snapshot) { +// if (snapshot.connectionState == ConnectionState.done && +// snapshot.hasData) { +// AboutModel aboutModel = snapshot.data!.first; +// // debugPrint('SNAPSHOT of about ${aboutModel.title}'); +// return SingleChildScrollView( +// physics: const ScrollPhysics(), +// child: Column( +// children: [ +// const SizedBox(height: 28), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 20.0), +// child: FadeInImage.memoryNetwork( +// placeholder: kTransparentImage, +// image: aboutModel.firstImgUrl, +// ), +// ), +// const SizedBox(height: 24), +// Padding( +// padding: EdgeInsets.symmetric(horizontal: 20.0), +// child: Text( +// aboutModel.title, +// textAlign: TextAlign.justify, +// style: TextStyle( +// fontSize: 18, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : Color(0xffC2C2C2), +// fontFamily: 'SFPRO', +// fontWeight: FontWeight.w400, +// ), +// ), +// ), +// const SizedBox(height: 24), +// // PodVideoPlayer(controller: controller), +// // Container( +// // width: Get.size.width, +// // height: 260, +// // color: Colors.red, +// // decoration: const BoxDecoration( +// // image: DecorationImage( +// // image: AssetImage('assets/image/faq/gsfFit.jpg'), +// // fit: BoxFit.cover, +// // ), +// // ), +// // child: Center( +// // child: Container( +// // decoration: const BoxDecoration( +// // color: ColorConstants.kPrimaryColor, +// // shape: BoxShape.circle, +// // ), +// // child: GestureDetector( +// // onTap: () => Get.to(() => VimeoPlayer()), +// // child: Padding( +// // padding: EdgeInsets.all(10), +// // child: Icon( +// // Icons.play_arrow_rounded, +// // size: 40, +// // color: ColorConstants.kBlack, +// // ), +// // ), +// // ), +// // ), +// // ), +// // child: FlutterLogo(), +// // ), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 20), +// child: Html( +// data: aboutModel.description, +// customRenders: { +// (context) => context.tree.element?.localName == 'li': +// CustomRender.widget( +// widget: (context, buildChildren) { +// listItemCount++; +// return Padding( +// padding: const EdgeInsets.only(bottom: 12), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.all(6), +// decoration: BoxDecoration( +// color: ColorConstants.kPrimaryColor, +// shape: BoxShape.circle, +// ), +// child: Text( +// listItemCount.toString(), +// textAlign: TextAlign.justify, +// style: TextStyle(color: Colors.black), +// ), +// ), +// SizedBox(width: 12), +// Expanded( +// child: Text(context.tree.element?.text ?? +// "No item found"), +// ) +// ], +// ), +// ); +// }), +// }, +// ) +// /* +// ListView.builder( +// physics: const ScrollPhysics(), +// shrinkWrap: true, +// itemCount: 5, +// itemBuilder: (context, index) => Padding( +// padding: const EdgeInsets.only(bottom: 22.0), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// decoration: const BoxDecoration( +// color: ColorConstants.kPrimaryColor, +// shape: BoxShape.circle, +// ), +// child: Padding( +// padding: const EdgeInsets.all(8.0), +// child: Text( +// '${index + 1}', +// style: const TextStyle( +// fontSize: 16, +// color: ColorConstants.kBlack, +// fontFamily: 'SFPRO', +// fontWeight: FontWeight.w800, +// ), +// ), +// ), +// ), +// const SizedBox(width: 10), +// Expanded( +// child: Text( +// 'The next time you find yourself continuously running things over in your mind, take note of how it affects your mood.', +// style: TextStyle( +// fontSize: 14, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : Color(0xffD9D9D9), +// ), +// ), +// ), +// ], +// ), +// ), +// ), +// */ +// ), +// const SizedBox(height: 30), +// FadeInImage.memoryNetwork( +// placeholder: kTransparentImage, +// image: aboutModel.secondImgUrl, +// ), +// /* +// Container( +// decoration: BoxDecoration( +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack.withOpacity(0.4) +// : Color(0xff333333), +// ), +// child: Padding( +// padding: const EdgeInsets.symmetric( +// horizontal: 20.0, vertical: 20), +// child: Row( +// children: [ +// Expanded( +// flex: 1, +// child: Column( +// children: [ +// Row( +// children: [ +// SvgPicture.asset( +// 'assets/image/faq/coached.svg'), +// const SizedBox(width: 10), +// Text( +// '6500', +// style: TextStyle( +// fontSize: 35, +// color: ColorConstants.kPrimaryColor, +// fontFamily: 'SFPRO', +// fontWeight: FontWeight.bold, +// ), +// ), +// ], +// ), +// const SizedBox(height: 10), +// Text( +// 'Coached Over 6500 In Last 2 Years', +// style: TextStyle( +// fontSize: 16, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// fontFamily: 'SFPRO', +// ), +// ), +// ], +// ), +// ), +// Expanded( +// flex: 1, +// child: Column( +// children: [ +// Row( +// children: [ +// SvgPicture.asset( +// 'assets/image/faq/transformations.svg'), +// const SizedBox(width: 10), +// Text( +// '6500', +// style: TextStyle( +// fontSize: 35, +// color: ColorConstants.kPrimaryColor, +// fontFamily: 'SFPRO', +// fontWeight: FontWeight.bold, +// ), +// ), +// ], +// ), +// const SizedBox(height: 10), +// Text( +// 'Over 100S Of Lifestyle Transformations', +// style: TextStyle( +// fontSize: 16, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// fontFamily: 'SFPRO', +// ), +// ), +// ], +// ), +// ), +// ], +// ), +// ), +// ), +// */ +// // const SizedBox(height: 20), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 20.0), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// // Text( +// // 'As enabling it is, it also inspires and helps unleash their vulnerable side.', +// // style: TextStyle( +// // fontSize: 18, +// // color: (brightness == Brightness.light) +// // ? ColorConstants.kBlack +// // : Color(0xffD9D9D9), +// // fontFamily: 'SFPRO', +// // ), +// // ), +// // SizedBox(height: 5), +// // Text( +// // 'This is made possible through', +// // style: TextStyle( +// // fontSize: 18, +// // color: ColorConstants.kPrimaryColor, +// // fontFamily: 'SFPRO', +// // ), +// // ), +// SizedBox(height: 20), +// //bottom 2 imgs +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// FadeInImage.memoryNetwork( +// placeholder: kTransparentImage, +// image: aboutModel.leftImgUrl, +// ), +// SizedBox(height: 3), +// Text( +// aboutModel.leftImgLabel, +// textAlign: TextAlign.center, +// style: TextStyle( +// fontSize: 14, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : Color(0xffC2C2C2), +// fontFamily: 'SFPRO', +// ), +// ) +// ], +// ), +// ), + +// SizedBox(width: 8), + +// //right img +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// FadeInImage.memoryNetwork( +// placeholder: kTransparentImage, +// image: aboutModel.rightImgUrl), +// SizedBox(height: 3), +// Text( +// aboutModel.rightImgLabel, +// textAlign: TextAlign.center, +// style: TextStyle( +// fontSize: 14, +// color: (brightness == Brightness.light) +// ? ColorConstants.kBlack +// : Color(0xffC2C2C2), +// fontFamily: 'SFPRO', +// ), +// ) +// ], +// ), +// ), +// ], +// ), +// SizedBox(height: 30), +// ], +// ), +// ), +// ], +// ), +// ); +// } +// return AboutGSFShimmer(); +// }, +// ), + ); + } +} + +class AboutGSFShimmer extends StatelessWidget { + const AboutGSFShimmer({Key? key}) : super(key: key); + + Container skeletonChild({ + required double radius, + required double height, + double? width, + }) => + Container( + width: width, + height: height, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(radius), + ), + ); + + listTileSkeleton() => Row( + children: [ + skeletonChild(radius: 30, height: 60, width: 60), + SizedBox(width: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + skeletonChild(width: Get.size.width - 108, height: 12, radius: 6), + SizedBox(height: 4), + skeletonChild(width: Get.size.width - 108, height: 12, radius: 6), + SizedBox(height: 4), + skeletonChild(width: Get.size.width - 160, height: 12, radius: 6), + ], + ) + ], + ); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Shimmer.fromColors( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + skeletonChild(radius: 12, height: 160), + SizedBox(height: 8), + skeletonChild(radius: 8, height: 18), + SizedBox(height: 4), + skeletonChild(radius: 8, height: 18), + SizedBox(height: 4), + skeletonChild(radius: 8, height: 18), + SizedBox(height: 4), + skeletonChild(radius: 8, height: 18, width: 180), + SizedBox(height: 8), + skeletonChild(radius: 12, height: 180), + SizedBox(height: 8), + listTileSkeleton(), + SizedBox(height: 8), + listTileSkeleton(), + SizedBox(height: 8), + listTileSkeleton(), + ], + ), + ), + baseColor: (brightness == Brightness.light) + ? const Color.fromARGB(255, 216, 214, 214) + : const Color.fromARGB(255, 26, 26, 26), + highlightColor: (brightness == Brightness.light) + ? const Color.fromARGB(255, 202, 201, 201) + : const Color.fromARGB(255, 40, 40, 40), + ); + } +} diff --git a/gsf/lib/views/pages/faq/about_gsf_accordian.dart b/gsf/lib/views/pages/faq/about_gsf_accordian.dart new file mode 100644 index 0000000..8f38a09 --- /dev/null +++ b/gsf/lib/views/pages/faq/about_gsf_accordian.dart @@ -0,0 +1,293 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/shimmer_skeleton_base.dart'; +import 'package:gsp_app/repository/services/faq_service.dart'; +import 'package:shimmer/shimmer.dart'; + +import '../../../view_model/global_controller.dart'; +import '../../components/appbar.dart'; +import '../../../modals/faq_model.dart'; +import '../../theme.dart'; + +class AboutGetSetFit extends StatefulWidget { + const AboutGetSetFit({Key? key}) : super(key: key); + + @override + State createState() => _AboutGetSetFitState(); +} + +class _AboutGetSetFitState extends State { + GlobalController globalController = Get.find(); + AppBar aboutAppBar() => AppBar( + automaticallyImplyLeading: false, + leadingWidth: 70, + // backgroundColor: ColorConstants.kBlack, + leading: Padding( + padding: + const EdgeInsets.only(top: 10, left: 18, right: 15, bottom: 10), + child: InkWell( + splashColor: const Color(0xff313030).withOpacity(0.5), + borderRadius: BorderRadius.circular(7), + onTap: () => Get.back(), + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: const Color(0xff313030), + borderRadius: BorderRadius.circular(7), + ), + child: const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Icon( + Icons.arrow_back_ios, + color: ColorConstants.kWhite, + size: 20, + ), + ), + ), + ), + ), + titleSpacing: 0, + centerTitle: true, + elevation: 0, + title: Text( + 'FAQ\'s', + style: TextStyle( + fontSize: 16, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ); + + var faqList = []; + var topQueList = []; + var aboutGsfList = []; + + @override + Widget build(BuildContext context) { + faqList.clear(); + topQueList.clear(); + aboutGsfList.clear(); + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'FAQ\'s'), + ), + body: FutureBuilder>( + future: FaqService().fetchFaq(), + builder: (context, snapshot) { + print('snapshot of data faq ${snapshot}'); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + List faqModels = snapshot.data!; + for (FaqModel faqModel in faqModels) { + if (faqModel.categoryId == 7) { + topQueList.add(faqModel); + } + if (faqModel.categoryId == 8) { + aboutGsfList.add(faqModel); + } + } + faqList.add( + const Padding( + padding: EdgeInsets.symmetric(vertical: 12), + child: Text( + 'Top Questions', + style: TextStyle( + fontSize: 22, + color: Color(0xff858585), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w900, + ), + ), + ), + ); + faqList.addAll(topQueList.map( + (e) => FaqExpansionTile(question: e.question, answer: e.answer), + )); + faqList.add( + const Padding( + padding: EdgeInsets.symmetric(vertical: 12), + child: Text( + 'About GetSetFit', + style: TextStyle( + fontSize: 22, + color: Color(0xff858585), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w900, + ), + ), + ), + ); + faqList.addAll(aboutGsfList.map((e) => + FaqExpansionTile(question: e.question, answer: e.answer))); + return FaqContent(contentList: faqList); + } + return const ShimmerContent(); + }, + ), + ); + } +} + +class FaqExpansionTile extends StatelessWidget { + const FaqExpansionTile({ + required this.question, + required this.answer, + Key? key, + }) : super(key: key); + + final String question; + final String answer; + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalController = Get.find(); + return Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + spreadRadius: 2, + blurRadius: 10, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.3) + : ColorConstants.kWhite.withOpacity(0), + ) + ], + borderRadius: BorderRadius.circular(10), + ), + margin: const EdgeInsets.only(bottom: 8), + child: ExpansionTile( + iconColor: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + collapsedIconColor: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + title: Text( + question, + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + children: [ + Container( + height: 5, + width: double.infinity, + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + ), + ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + answer, + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + ), + ], + ), + ); + } +} + +class FaqContent extends StatefulWidget { + const FaqContent({ + required this.contentList, + Key? key, + }) : super(key: key); + + final List contentList; + + @override + State createState() => _FaqContentState(); +} + +class _FaqContentState extends State { + @override + Widget build(BuildContext context) { + return ListView.builder( + itemCount: widget.contentList.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: widget.contentList[index], + ); + }, + ); + } +} + +class ShimmerContent extends StatelessWidget { + const ShimmerContent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalController = Get.find(); + return Shimmer.fromColors( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 16), + const ShimmerSkeletonBase( + width: 160, + height: 28, + radius: 8, + ), + for (int i = 0; i < 4; i++) + Column( + children: const [ + SizedBox(height: 8), + ShimmerSkeletonBase( + width: double.infinity, + height: 42, + radius: 8, + ), + ], + ), + const SizedBox(height: 18), + const ShimmerSkeletonBase( + width: 160, + height: 28, + radius: 8, + ), + for (int i = 0; i < 4; i++) + Column( + children: const [ + SizedBox(height: 8), + ShimmerSkeletonBase( + width: double.infinity, + height: 42, + radius: 8, + ), + ], + ) + ], + )), + baseColor: !globalController.darkMode.value + ? const Color.fromARGB(255, 216, 214, 214) + : const Color.fromARGB(255, 26, 26, 26), + highlightColor: !globalController.darkMode.value + ? const Color.fromARGB(255, 202, 201, 201) + : const Color.fromARGB(255, 40, 40, 40), + ); + } +} diff --git a/gsf/lib/views/pages/faq/faq.dart b/gsf/lib/views/pages/faq/faq.dart new file mode 100644 index 0000000..16017cf --- /dev/null +++ b/gsf/lib/views/pages/faq/faq.dart @@ -0,0 +1,214 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; +import 'about_gsf.dart'; +import 'about_gsf_accordian.dart'; + +class FAQ extends StatelessWidget { + const FAQ({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + List faq = [ + { + 'title': 'About\nGetsetfit', + 'img': 'activity', + }, + { + 'title': 'Workout\nTraining', + 'img': 'bmi_nutrition', + }, + { + 'title': 'Activity', + 'img': 'activity', + }, + { + 'title': 'Payment', + 'img': 'secure_payment', + }, + { + 'title': 'Workout\nTraining', + 'img': 'workout', + }, + { + 'title': 'Activity', + 'img': 'activity', + }, + { + 'title': 'BMI + Nutrition\nCalculator', + 'img': 'bmi_nutrition', + }, + { + 'title': 'Referrals &\nVouchers', + 'img': 'voucher', + }, + ]; + final TextEditingController controller = TextEditingController(); + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'FAQ'), + ), + body: SingleChildScrollView( + child: SizedBox( + width: Get.size.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 20), + SvgPicture.asset('assets/image/faq/faq_main_logo.svg'), + const SizedBox(height: 22), + Text( + 'Hi! How can we help you?', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 20), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular( + 25, + ), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + width: Get.size.width * 0.65, + // height: 0, + child: Row( + children: [ + Expanded( + flex: 5, + child: CupertinoSearchTextField( + controller: controller, + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25), + bottomLeft: Radius.circular(25), + ), + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xffffffff).withOpacity(0.11), + ), + itemSize: 25, + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffffffff), + ), + prefixIcon: const SizedBox(), + prefixInsets: + const EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), + placeholder: 'Ask a quotations...', + suffixInsets: + const EdgeInsetsDirectional.fromSTEB(0, 0, 15, 2), + placeholderStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : Color(0xffffffff), + ), + padding: const EdgeInsets.only( + left: 10, top: 15, bottom: 15, right: 15), + ), + ), + Expanded( + flex: 1, + child: Container( + height: 48.5, + decoration: const BoxDecoration( + color: ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.only( + topRight: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + ), + child: Icon( + Icons.search_outlined, + color: ColorConstants.kBlack, + size: 30, + ), + ), + ), + ], + ), + ), + SizedBox(height: 30), + Wrap( + spacing: 20, + runSpacing: 20, + alignment: WrapAlignment.center, + children: List.generate( + faq.length, + (int index) => GestureDetector( + onTap: () { + if (index == 0) { + Get.to(() => AboutGSF()); + } + if (index == 1) { + Get.to(() => AboutGetSetFit()); + } + }, + child: Container( + width: 110, + height: 110, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : Color(0xff212121), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/image/faq/' + faq[index]['img'] + '.svg', + ), + Text( + faq[index]['title'], + style: TextStyle( + fontSize: 13, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + textAlign: TextAlign.center, + ) + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/feedback/feedback.dart b/gsf/lib/views/pages/feedback/feedback.dart new file mode 100644 index 0000000..6ace299 --- /dev/null +++ b/gsf/lib/views/pages/feedback/feedback.dart @@ -0,0 +1,194 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class FeedBack extends StatelessWidget { + const FeedBack({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + RxBool active = false.obs; + RxBool active1 = false.obs; + RxBool feedActive = true.obs; + final TextEditingController _textarea = TextEditingController(); + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Feedback'), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Row( + children: [ + Expanded( + flex: 1, + child: GestureDetector( + onTap: () { + active.value = !active.value; + active1.value = false; + }, + child: Obx( + () => active.value + ? SvgPicture.asset( + 'assets/image/feedback/sad_active.svg', + ) + : SvgPicture.asset( + 'assets/image/feedback/sad_unactive.svg', + ), + ), + ), + ), + Expanded( + flex: 1, + child: GestureDetector( + onTap: () { + active1.value = !active1.value; + active.value = false; + }, + child: Obx( + () => active1.value + ? SvgPicture.asset( + 'assets/image/feedback/happy_active.svg', + ) + : SvgPicture.asset( + 'assets/image/feedback/happy_unactive.svg', + ), + ), + )), + ], + ), + ), + const SizedBox(height: 30), + TextFormField( + style: const TextStyle( + color: Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + maxLines: 12, + decoration: InputDecoration( + fillColor: const Color(0xff212121), + hintText: "Type your feedback...", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + isDense: true, + ), + controller: _textarea, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your feedback'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + InkWell( + onTap: () {}, + child: Container( + width: Get.width * 0.3, + height: 50, + decoration: BoxDecoration( + color: const Color(0xff212121), + borderRadius: BorderRadius.circular(30), + ), + child: const Center( + child: Text( + 'Later', + style: TextStyle( + fontSize: 16, + color: Color(0xff6A6A6A), + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + ), + ), + ), + ), + ), + // const Spacer(), + InkWell( + onTap: () {}, + child: Container( + width: Get.width * 0.3, + height: 50, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.circular(30), + ), + child: const Center( + child: Text( + 'Submit', + style: TextStyle( + fontSize: 16, + color: Color(0xff000000), + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 50), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/forgotPassword/forgot_password.dart b/gsf/lib/views/pages/forgotPassword/forgot_password.dart new file mode 100644 index 0000000..c034d2c --- /dev/null +++ b/gsf/lib/views/pages/forgotPassword/forgot_password.dart @@ -0,0 +1,457 @@ +import 'package:flutter/material.dart'; +// import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/api/base_manager.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; +import '../../../view_model/ResetPassword.dart'; +import '../../components/appbar.dart'; +import '../../theme.dart'; +import 'reset_otp.dart'; + +class ForgotPassword extends StatefulWidget { + const ForgotPassword({Key? key}) : super(key: key); + + @override + State createState() => _ForgotPasswordState(); +} + +class _ForgotPasswordState extends State { + // Country? _selectedCountry; + // final TextEditingController _email = TextEditingController(); + // final ForgotPasswordController forgotPassContoller = + // Get.put(ForgotPasswordController()); + var _formKey = GlobalKey(); + final brightness = Get.theme.brightness; + final emailRegx = RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); + + var submitBtnController = RoundedLoadingButtonController(); + + // void initCountry() async { + // final country = await getDefaultCountry(context); + // setState(() { + // _selectedCountry = country; + // }); + // } + + var focusNode = FocusNode(); + var emailController = TextEditingController(); + + @override + void initState() { + super.initState(); + focusNode.requestFocus(); + } + + _validateDetails() async { + Get.focusScope!.unfocus(); + if (_formKey.currentState!.validate()) { + Map updata = {"email_id": emailController.text}; + await ResetPassword().generateOTP(updata).then((resp) { + switch (resp.status) { + case ResponseStatus.SUCCESS: + Get.to(() => OtpScreen( + userId: resp.data['user_id'], + email: emailController.text, + )); + submitBtnController.reset(); + + break; + case ResponseStatus.PRIVATE: + submitBtnController.error(); + Get.showSnackbar(GetSnackBar( + duration: const Duration(seconds: 4), + title: "Cannot Proceed", + message: resp.message, + )); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => submitBtnController.reset()); + break; + case ResponseStatus.FAILED: + submitBtnController.error(); + Get.showSnackbar(const GetSnackBar( + duration: Duration(seconds: 4), + title: "Cannot Proceed", + message: "Please check your email or try again later", + )); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => submitBtnController.reset()); + break; + } + }); + } else { + submitBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => submitBtnController.reset()); + } + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return GestureDetector( + onTap: () => Get.focusScope!.unfocus(), + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Forgot Password'), + ), + body: Padding( + padding: EdgeInsets.all(screenSize.width * 0.05), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Enter your email address', + style: TextStyle( + fontSize: 22, + color: (brightness == Brightness.light) + ? Colors.grey + : ColorConstants.kPrimaryColor, + fontFamily: "Poppins", + fontWeight: FontWeight.w300, + ), + ), + Text( + 'Will be verified in the next step', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.8) + : const Color(0xffD9D9D9).withOpacity(0.8), + fontFamily: "Poppins", + ), + ), + const SizedBox(height: 10), + formUI(), + const Spacer(), + PrimaryButton( + controller: submitBtnController, + onTap: () { + _validateDetails(); + }, + text: "Proceed", + ), + ], + ), + ), + ), + ); + } + + formUI() { + // final country = _selectedCountry; + return Form( + key: _formKey, + child: Column( + // crossAxisAlignment: CrossAxisAlignment.end, + children: [ + TextFormField( + focusNode: focusNode, + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + controller: emailController, + // controller: forgotPassContoller.emailController.value, + keyboardType: TextInputType.text, + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + hintText: 'Email', + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.5) + : const Color(0xffB7B7B7), + ), + suffixIcon: Padding( + padding: const EdgeInsets.only(left: 20.0, right: 5), + child: Icon( + // Based on passwordVisible state choose the icon + Icons.perm_identity_rounded, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.5) + : const Color(0xffB7B7B7), + size: 30, + ), + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email address'; + } + if (!value.contains(emailRegx)) { + return 'Please enter valid email address'; + } + if (value.length < 4) { + return 'Must be greater than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + // ClipPath( + // clipper: ShapeBorderClipper( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.all( + // Radius.circular(10), + // ), + // ), + // ), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Expanded( + // flex: 2, + // child: (country == null) + // ? Container( + // height: 60, + // width: 80, + // decoration: const BoxDecoration( + // color: Color(0xff212121), + // borderRadius: BorderRadius.only( + // bottomLeft: Radius.circular(10), + // ), + // ), + // child: InkWell( + // onTap: () { + // _onPressedShowBottomSheet(); + // }, + // child: Column( + // children: [ + // Expanded( + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: const [ + // Text( + // '+91', + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // // 'hello', + // // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 16, + // color: Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontWeight: FontWeight.normal, + // ), + // ), + // Icon( + // Icons.keyboard_arrow_down, + // color: Color(0xffffffff), + // size: 18, + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ) + // : Container( + // height: 60, + // width: 80, + // decoration: BoxDecoration( + // color: const Color(0xff212121), + // borderRadius: BorderRadius.circular(0), + // ), + // child: InkWell( + // onTap: () { + // _onPressedShowBottomSheet(); + // }, + // child: Column( + // children: [ + // Expanded( + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text( + // country.callingCode, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // // 'hello', + // // textAlign: TextAlign.center, + // style: const TextStyle( + // fontSize: 16, + // color: Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontWeight: FontWeight.normal, + // ), + // ), + // const Icon( + // Icons.keyboard_arrow_down, + // color: Color(0xffffffff), + // size: 18, + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ), + // ), + // Expanded( + // flex: 0, + // child: Container( + // color: const Color(0xffffffff).withOpacity(0.5), + // width: 1, + // height: 60, + // ), + // ), + // Expanded( + // flex: 7, + // child: Padding( + // padding: const EdgeInsets.only(left: 0, right: 0), + // child: TextFormField( + // style: const TextStyle( + // color: Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontSize: 16, + // fontWeight: FontWeight.w400, + // ), + // autovalidateMode: AutovalidateMode.onUserInteraction, + // decoration: InputDecoration( + // fillColor: const Color(0xff212121), + // errorMaxLines: 3, + // hintText: "Mobile Number*", + // contentPadding: const EdgeInsets.only( + // top: 20, + // bottom: 20, + // left: 20, + // right: 25, + // ), + // hintStyle: TextStyle( + // fontSize: 16, + // color: const Color(0xffffffff).withOpacity(0.6), + // fontFamily: 'Helvetica', + // ), + // filled: true, + // border: const OutlineInputBorder( + // borderRadius: BorderRadius.only( + // bottomRight: Radius.circular(10), + // topRight: Radius.circular(10), + // ), + // borderSide: BorderSide( + // width: 1, + // color: Colors.transparent, + // ), + // ), + // errorBorder: const OutlineInputBorder( + // borderRadius: BorderRadius.only( + // bottomRight: Radius.circular(10), + // topRight: Radius.circular(10), + // ), + // borderSide: BorderSide( + // width: 1, + // color: Colors.transparent, + // ), + // ), + // errorStyle: const TextStyle( + // fontSize: 16.0, + // ), + // enabledBorder: const OutlineInputBorder( + // borderRadius: BorderRadius.only( + // bottomRight: Radius.circular(10), + // topRight: Radius.circular(10), + // ), + // borderSide: BorderSide( + // width: 1, + // color: Colors.transparent, + // ), + // ), + // focusedBorder: const OutlineInputBorder( + // borderRadius: BorderRadius.only( + // bottomRight: Radius.circular(10), + // topRight: Radius.circular(10), + // ), + // borderSide: BorderSide( + // width: 1, + // color: Colors.transparent, + // ), + // ), + // isDense: true, + // ), + // controller: _phone, + // keyboardType: TextInputType.number, + // validator: (value) { + // if (value == null || value.isEmpty) { + // return 'Please enter your number'; + // } + // if (!RegExp(r"^[0-9]{10,12}$").hasMatch(value)) { + // return 'Number allowed between 10-12 digits'; + // } + // return null; + // }, + // onSaved: (name) {}, + // ), + // ), + // ), + // ], + // ), + // ), + // const SizedBox(height: 180), + // Spacer(), + // Align( + // alignment: Alignment.bottomCenter, + // child: FullWdtBtn( + // btnText: 'Proceed', + // onTap: () {}, + // ), + // ), + ], + ), + ); + } + +/* + void _onPressedShowBottomSheet() async { + final brightness = Theme.of(context).brightness; + final country = await showCountryPickerSheet( + context, + // title: Text('Country Codes'), + cancelWidget: Padding( + padding: const EdgeInsets.only(top: 8, right: 25), + child: Align( + alignment: Alignment.centerRight, + child: InkWell( + onTap: () => Navigator.pop(context), + child: Text( + 'Cancel', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : const Color(0xffffffff), + ), + ), + ), + ), + ), + ); + // if (country != null) { + // setState(() { + // _selectedCountry = country; + // }); + // } + } +*/ +} diff --git a/gsf/lib/views/pages/forgotPassword/forgot_password_controller.dart b/gsf/lib/views/pages/forgotPassword/forgot_password_controller.dart new file mode 100644 index 0000000..222c468 --- /dev/null +++ b/gsf/lib/views/pages/forgotPassword/forgot_password_controller.dart @@ -0,0 +1,209 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:http/http.dart'; + +import '../signIn/sign_in.dart'; +import 'reset_otp.dart'; +import 'reset_password.dart'; + +class UserData { + static dynamic userID; + static dynamic userEmail; +} + +class ForgotPasswordController extends GetxController { + final emailController = TextEditingController().obs; + final otpController = TextEditingController().obs; + final passwordController = TextEditingController().obs; + final confirmPasswordController = TextEditingController().obs; + + Timer? timer; + int remainingSeconds = 0; + final times = '00:00:00'.obs; + RxBool hideTime = false.obs; + RxBool loader = false.obs; + + // @override + // void onReady() { + // startTimer(600); + // super.onReady(); + // } + + @override + void onClose() { + if (timer != null) { + timer!.cancel(); + } + super.onClose(); + } + + startTimer(int secondss) { + const duration = Duration(seconds: 1); + remainingSeconds = secondss; + timer = Timer.periodic(duration, (timer) { + if (remainingSeconds == 00) { + timer.cancel(); + hideTime.value = true; + } else { + int hours = remainingSeconds ~/ 60 ~/ 60; + int minute = remainingSeconds ~/ 60; + int seconds = remainingSeconds % 60; + + times.value = hours.toString().padLeft(2, "0") + + ":" + + minute.toString().padLeft(2, "0") + + ":" + + seconds.toString().padLeft(2, "0"); + remainingSeconds--; + } + }); + } + + // void clearForm() { + // emailController.value.clear(); + // otpController.value.clear(); + // } + + // void disposeInputs() { + // emailController.value.dispose(); + // // otpController.value.dispose(); + // } + + // @override + // void dispose() { + // // disposeInputs(); + // clearForm(); + // super.dispose(); + // } + + // timer contorller + // void timer() {} + + // forgot password enter the email id and get the otp================================================================ + Future forgotPassword() async { + loader.value = true; + try { + final response = await post( + Uri.parse('https://gsf.wdipl.com/api/otp/generate'), + // headers: {'token': token, 'content-type': 'application/json'}, + body: { + 'email_id': emailController.value.text, + }, + ); + var data = jsonDecode(response.body); + + print('datas with user id $data'); + + UserData.userID = data['user_id']; + UserData.userEmail = emailController.value.text; + + if (data['status'] == 200) { + Get.snackbar( + 'OTP Send', + 'OTP sent successfully,\nPlease check you\'re email id.', + backgroundColor: ColorConstants.kPrimaryColor, + ); + // Get.to(() => const OtpScreen()); + startTimer(259); + loader.value = false; + } + } catch (e) { + loader.value = false; + Get.snackbar( + 'Error', + 'Please check you\'re email.', + backgroundColor: Colors.red, + snackPosition: SnackPosition.BOTTOM, + ); + } + } + + // enter otp to verify================================================================ + Future optVerify(String otp) async { + loader.value = true; + try { + final response = await post( + Uri.parse('https://gsf.wdipl.com/api/otp/create_new_pass_with_otp'), + body: { + "user_id": UserData.userID.toString(), + "otp": otp, + }, + ); + var data = jsonDecode(response.body); + + // print('status code $data'); + + // UserData.userEmail = emailController.value; + + if (data['status'] == 200) { + loader.value = false; + Get.snackbar( + 'congratulation!', + data['message'], + backgroundColor: ColorConstants.kPrimaryColor, + snackPosition: SnackPosition.BOTTOM, + ); + // Get.offUntil(page, (route) => false) + // Get.off(() => const ResetPassword()); + } else if (data['status'] == 500) { + loader.value = false; + Get.snackbar( + 'Failed', + data['message'], + backgroundColor: ColorConstants.kErroColor, + snackPosition: SnackPosition.BOTTOM, + ); + } else { + loader.value = false; + Get.snackbar( + 'Failed', + 'Please check the otp', + backgroundColor: ColorConstants.kErroColor, + snackPosition: SnackPosition.BOTTOM, + ); + } + } catch (e) { + loader.value = false; + Get.snackbar('Excepetions', e.toString()); + } + } + + // change the password using forgot password ans otp================================================================ + Future updatePassword() async { + loader.value = true; + try { + var response = await put( + Uri.parse('https://gsf.wdipl.com/api/otp/update_password'), + body: { + "user_id": UserData.userID.toString(), + "password": passwordController.value.text, + "password_confirmation": confirmPasswordController.value.text, + }, + ); + var data = jsonDecode(response.body); + // print(data); + if (data['status'] == 200) { + loader.value = false; + Get.snackbar( + 'Congratulation', + data['message'], + backgroundColor: ColorConstants.kPrimaryColor, + snackPosition: SnackPosition.BOTTOM, + ); + Get.offAll( + () => const SignIn(), + ); + } + } catch (e) { + loader.value = false; + Get.snackbar( + 'Exceptions', + e.toString(), + ); + } + } +} diff --git a/gsf/lib/views/pages/forgotPassword/reset_otp.dart b/gsf/lib/views/pages/forgotPassword/reset_otp.dart new file mode 100644 index 0000000..a6004be --- /dev/null +++ b/gsf/lib/views/pages/forgotPassword/reset_otp.dart @@ -0,0 +1,818 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gsp_app/repository/services/cj/generate_otp_service.dart'; +import 'package:gsp_app/repository/services/cj/verify_otp_service.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:gsp_app/views/pages/forgotPassword/reset_password.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; +import 'package:get/get.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../../repository/response_data.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'forgot_password_controller.dart'; + +class OtpScreen extends StatefulWidget { + const OtpScreen({ + Key? key, + required this.userId, + required this.email, + }) : super(key: key); + + final int userId; + final String email; + + @override + State createState() => _OtpScreenState(); +} + +class _OtpScreenState extends State { + // final textEditingController1 = TextEditingController(); + var formKey = GlobalKey(); + // StreamController? errorController; + final otpContoller = Get.put(ForgotPasswordController()); + // final otpTextEditController = TextEditingController(); + // final TextEditingController _newPassword = TextEditingController(); + // final TextEditingController _confirmPassword = TextEditingController(); + // bool _newPasswordVisible = false; + // bool _confirmPasswordVisible = false; + // bool _isPasswordEightCar = false; + // bool _isHasOneNumber = false; + // bool _isHasSymboleOrCaptital = false; + + // onPasswordChnage(String newPassword) { + // setState(() { + // final numricRegex = RegExp(r'[0-9]'); + // final alphaRegex = RegExp(r'[A-Z]|(?=.*[@$!%*#?&])'); + + // _isPasswordEightCar = false; + // if (newPassword.length >= 8) _isPasswordEightCar = true; + + // _isHasOneNumber = false; + // if (numricRegex.hasMatch(newPassword)) _isHasOneNumber = true; + + // _isHasSymboleOrCaptital = false; + // if (alphaRegex.hasMatch(newPassword)) _isHasSymboleOrCaptital = true; + // }); + // } + + // Future initSmsListener() async { + // String? comingSms; + // try { + // comingSms = await AltSmsAutofill().listenForSms; + // } on PlatformException { + // comingSms = 'Failed to get Sms.'; + // } + // if (!mounted) return; + + // setState(() { + // // otpContoller.otpController.value.text = comingSms.toString(); + // otpTextEditController.text = comingSms.toString(); + // }); + // } + + @override + void initState() { + super.initState(); + otpContoller.startTimer(299); + // initSmsListener(); + } + + @override + void dispose() { + // textEditingController1.dispose(); + // otpContoller.otpController.value; + // AltSmsAutofill().unregisterListener(); + // super.dispose(); + otpContoller.onClose(); + } + + String enteredOtp = ""; + int time = 120; + + var submitBtnController = RoundedLoadingButtonController(); + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + final brightness = Get.theme.brightness; + debugPrint("OTP EMAIL: ${widget.email}"); + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Forgot Password')), + body: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Padding( + padding: EdgeInsets.all(screenSize.width * 0.05), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Check your email', + style: TextStyle( + fontSize: 22, + color: (brightness == Brightness.light) + ? Colors.grey + : ColorConstants.kPrimaryColor, + fontFamily: "Poppins", + fontWeight: FontWeight.w300, + ), + ), + Text( + 'OTP is sent at ${widget.email}', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.8) + : const Color(0xffD9D9D9).withOpacity(0.8), + fontFamily: "Poppins", + ), + ), + SizedBox(height: 36), + Text( + 'Enter OTP', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.8) + : const Color(0xffD9D9D9).withOpacity(0.8), + fontFamily: "Poppins", + ), + ), + SizedBox(height: 6), + Form( + key: formKey, + child: PinCodeTextField( + autoFocus: true, + appContext: context, + pastedTextStyle: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + length: 4, + textStyle: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + obscureText: false, + animationType: AnimationType.fade, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp("[0-9]")), + ], + pinTheme: PinTheme( + shape: PinCodeFieldShape.box, + borderRadius: BorderRadius.circular(10), + fieldHeight: 60, + fieldWidth: 60, + inactiveFillColor: Colors.transparent, + inactiveColor: const Color(0xff707070), + selectedColor: ColorConstants.kPrimaryColor, + selectedFillColor: Colors.transparent, + activeFillColor: Colors.transparent, + activeColor: ColorConstants.kPrimaryColor, + ), + cursorColor: (brightness == Brightness.light) + ? Colors.black + : Colors.white, + animationDuration: const Duration(milliseconds: 300), + enableActiveFill: true, + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter otp.'; + } + if (value.length < 4) { + return 'Please enter a valid otp.'; + } + return null; + }, + onCompleted: (value) { + enteredOtp = value; + debugPrint("onCompleted $value"); + }, + onChanged: (value) {}, + ), + ), + SizedBox(height: 28), + Obx(() { + return (!otpContoller.hideTime.value) + ? Align( + alignment: Alignment.center, + child: Column( + children: [ + const Text( + 'Resend OTP in ', + style: TextStyle( + fontSize: 16, + ), + ), + SizedBox(height: 5), + Text( + otpContoller.times.value, + style: const TextStyle( + fontSize: 16, + color: Colors.red, + ), + ), + ], + ), + ) + : Align( + alignment: Alignment.center, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 10.0, bottom: 5), + child: Text( + 'Did\'nt receive the otp ?', + style: TextStyle(color: Colors.white), + ), + ), + // SizedBox(height: 5), + GestureDetector( + onTap: () async { + await GenerateOtpService() + .generateOtp(email: widget.email) + .then((resModel) { + switch (resModel.responseStatus) { + case ResponseStatus.success: + otpContoller.startTimer(299); + otpContoller.hideTime.value = false; + Get.showSnackbar(GetSnackBar( + title: 'OTP Sent', + message: + 'Please check your email ${widget.email}', + duration: Duration(seconds: 4), + )); + break; + case ResponseStatus.failed: + case ResponseStatus.expired: + case ResponseStatus.error: + Get.showSnackbar(GetSnackBar( + title: 'Cannot Send OTP', + message: + 'Please try again after some time', + duration: Duration(seconds: 4), + )); + break; + } + }); + + // print('object'); + }, + child: Text( + 'Resend Otp', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kPrimaryColor), + ), + ), + ], + ), + ); + }), + Spacer(), + PrimaryButton( + controller: submitBtnController, + onTap: () async { + if (formKey.currentState!.validate()) { + await VerifyOtpService() + .verifyOtp(emailId: widget.email, otp: enteredOtp) + .then((responseModel) { + switch (responseModel.responseStatus) { + case ResponseStatus.success: + Get.to(() => ResetPassword(userId: widget.userId)); + submitBtnController.reset(); + break; + case ResponseStatus.failed: + Get.showSnackbar(GetSnackBar( + duration: Duration(seconds: 4), + title: "Incorrect OTP", + message: "Please enter correct otp", + )); + submitBtnController.reset(); + break; + case ResponseStatus.error: + Get.showSnackbar(GetSnackBar( + duration: Duration(seconds: 4), + title: "Cannot verify", + message: "Please try again later", + )); + submitBtnController.reset(); + break; + case ResponseStatus.expired: + Get.showSnackbar(GetSnackBar( + duration: Duration(seconds: 4), + title: "OTP Expired", + message: "Please resend otp", + )); + submitBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => submitBtnController.reset()); + break; + } + }); + } + }, + text: "Submit", + ), + + // Center( + // child: Text( + // 'Didn\'t received an otp ?', + // style: TextStyle( + // fontSize: 14, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.8) + // : const Color(0xffD9D9D9).withOpacity(0.8), + // fontFamily: "Poppins", + // ), + // ), + // ), + // Center( + // child: TextButton( + // onPressed: () {}, + // child: Text("Resend"), + // ), + // ) + + // Align( + // alignment: Alignment.centerRight, + // child: TextButton(onPressed: () {}, child: Text("Resend")), + // ) + // Align( + // alignment: Alignment.centerRight, + // child: StatefulBuilder(builder: (context, setMyState) { + // debugPrint("TIMER START"); + // var duration = Duration(seconds: time); + // int seconds = duration.inSeconds > 60 + // ? duration.inSeconds - 60 + // : duration.inSeconds; + // Timer.periodic(Duration(seconds: 1), (timer) { + // time <= 0 ? timer.cancel() : setState(() => time--); + // }); + // return Text( + // "Resend OTP in ${duration.inMinutes}:$seconds", + // style: TextStyle( + // fontSize: 14, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.8) + // : const Color(0xffD9D9D9).withOpacity(0.8), + // fontFamily: "Poppins", + // ), + // ); + // }), + // ), + /* + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 42), + Text( + 'Enter OTP', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? const Color(0xff000000).withOpacity(0.7) + : const Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + // otpWidget(), + + + const SizedBox(height: 10), + // SizedBox( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // 'New Password', + // style: TextStyle( + // fontSize: 14, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.7) + // : const Color(0xff9F9F9F), + // ), + // ), + // const SizedBox(height: 10), + // TextFormField( + // onChanged: (newPassword) => + // onPasswordChnage(newPassword), + // style: TextStyle( + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.7) + // : const Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontSize: 16, + // fontWeight: FontWeight.w400, + // ), + // autovalidateMode: AutovalidateMode.onUserInteraction, + // controller: _newPassword, + // obscureText: !_newPasswordVisible, + // decoration: InputDecoration( + // fillColor: (brightness == Brightness.light) + // ? Colors.transparent + // : const Color(0xff212121), + // errorMaxLines: 3, + // hintText: "", + // contentPadding: const EdgeInsets.only( + // top: 20, + // bottom: 20, + // left: 25, + // right: 25, + // ), + // hintStyle: TextStyle( + // fontSize: 16, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.8) + // : const Color(0xffffffff).withOpacity(0.8), + // fontFamily: 'Helvetica', + // ), + // // fillColor: Colors.white, + // filled: true, + // suffixIcon: IconButton( + // icon: Icon( + // // Based on passwordVisible state choose the icon + // _newPasswordVisible + // ? Icons.visibility_outlined + // : Icons.visibility_off_outlined, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff).withOpacity(0.5), + // ), + // onPressed: () { + // setState(() { + // _newPasswordVisible = !_newPasswordVisible; + // }); + // }, + // ), + // border: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // errorBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // enabledBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // focusedBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // errorStyle: const TextStyle( + // fontSize: 16.0, + // // color: Color(0xffffffff), + // ), + // isDense: true, + // ), + // keyboardType: TextInputType.visiblePassword, + // validator: (value) { + // if (value!.isEmpty) { + // return 'Please enter your password'; + // } + // if (value.length < 8) { + // return 'Must be less than 8 characters'; + // } + // return null; + // }, + // onSaved: (name) {}, + // ), + // const SizedBox( + // height: 25, + // ), + // Row( + // children: [ + // AnimatedContainer( + // duration: const Duration( + // milliseconds: 500, + // ), + // width: 20, + // height: 20, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(50), + // border: Border.all( + // color: ColorConstants.kPrimaryColor, + // ), + // ), + // child: _isPasswordEightCar + // ? const Icon( + // Icons.check, + // color: ColorConstants.kPrimaryColor, + // size: 15, + // ) + // : const SizedBox(), + // ), + // Padding( + // padding: const EdgeInsets.only(left: 10), + // child: Text( + // 'Has at least 8 characters.', + // style: TextStyle( + // fontFamily: 'Helvetica', + // fontSize: 12, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : const Color(0xffffffff), + // ), + // ), + // ) + // ], + // ), + // const SizedBox( + // height: 10, + // ), + // Row( + // children: [ + // AnimatedContainer( + // duration: const Duration( + // milliseconds: 500, + // ), + // width: 20, + // height: 20, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(50), + // border: Border.all( + // color: ColorConstants.kPrimaryColor, + // ), + // ), + // child: _isHasSymboleOrCaptital + // ? const Icon( + // Icons.check, + // color: ColorConstants.kPrimaryColor, + // size: 15, + // ) + // : const SizedBox(), + // ), + // Padding( + // padding: const EdgeInsets.only(left: 10), + // child: Text( + // 'Has at least 1 uppercase letter or symbol.', + // style: TextStyle( + // fontFamily: 'Helvetica', + // fontSize: 12, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : const Color(0xffffffff), + // ), + // ), + // ) + // ], + // ), + // const SizedBox( + // height: 10, + // ), + // Row( + // children: [ + // AnimatedContainer( + // duration: const Duration( + // milliseconds: 500, + // ), + // width: 20, + // height: 20, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(50), + // border: Border.all( + // color: ColorConstants.kPrimaryColor, + // ), + // ), + // child: _isHasOneNumber + // ? const Icon( + // Icons.check, + // color: ColorConstants.kPrimaryColor, + // size: 15, + // ) + // : const SizedBox(), + // ), + // Padding( + // padding: const EdgeInsets.only(left: 10), + // child: Text( + // 'Has a number', + // style: TextStyle( + // fontFamily: 'Helvetica', + // fontSize: 12, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : const Color(0xffffffff), + // ), + // ), + // ) + // ], + // ), + // const SizedBox(height: 25), + // SizedBox( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // 'Confirm Password', + // style: TextStyle( + // fontSize: 14, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.7) + // : const Color(0xff9F9F9F), + // ), + // ), + // const SizedBox(height: 10), + // TextFormField( + // style: TextStyle( + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.7) + // : const Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontSize: 16, + // fontWeight: FontWeight.w400, + // ), + // autovalidateMode: + // AutovalidateMode.onUserInteraction, + // controller: _confirmPassword, + // obscureText: !_confirmPasswordVisible, + // decoration: InputDecoration( + // fillColor: (brightness == Brightness.light) + // ? Colors.transparent + // : const Color(0xffffffff), + // errorMaxLines: 3, + // hintText: "", + // contentPadding: const EdgeInsets.only( + // top: 20, + // bottom: 20, + // left: 25, + // right: 25, + // ), + // hintStyle: TextStyle( + // fontSize: 16, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000).withOpacity(0.8) + // : const Color(0xffffffff) + // .withOpacity(0.8), + // fontFamily: 'Helvetica', + // ), + // // fillColor: Colors.white, + // filled: true, + // suffixIcon: IconButton( + // icon: Icon( + // // Based on passwordVisible state choose the icon + // _confirmPasswordVisible + // ? Icons.visibility_outlined + // : Icons.visibility_off_outlined, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff) + // .withOpacity(0.5), + // ), + // onPressed: () { + // setState(() { + // _confirmPasswordVisible = + // !_confirmPasswordVisible; + // }); + // }, + // ), + // border: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: const BorderSide( + // width: 1, + // color: Colors.transparent, + // ), + // ), + // errorBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // enabledBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // focusedBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1.5, + // color: (brightness == Brightness.light) + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // errorStyle: const TextStyle( + // fontSize: 16.0, + // // color: Color(0xffffffff), + // ), + // isDense: true, + // ), + // keyboardType: TextInputType.visiblePassword, + // validator: (value) { + // if (value!.isEmpty) { + // return 'Please enter your password'; + // } + // if (value.length < 8) { + // return 'Must be less than 8 characters'; + // } + // return null; + // }, + // onSaved: (name) {}, + // ), + // const SizedBox( + // height: 25, + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // Align( + // alignment: Alignment.center, + // child: RichText( + // text: TextSpan( + // children: [ + // const TextSpan( + // text: 'Don\'t receive your code? ', + // style: + // TextStyle(color: Color(0xffD9D9D9), fontSize: 16), + // ), + // TextSpan( + // text: 'Resend', + // recognizer: TapGestureRecognizer()..onTap = () {}, + // style: const TextStyle( + // color: ColorConstants.kPrimaryColor, + // fontSize: 16, + // decoration: TextDecoration.underline, + // ), + // ), + // ], + // ), + // ), + // ), + const Spacer(flex: 8), + // const SizedBox(height: 150), +/* + Obx( + () => !otpContoller.loader.value + ? FullWdtBtn( + btnText: 'Proceed', + onTap: () { + if (formKey.currentState!.validate()) { + otpContoller + .optVerify(otpTextEditController.text); + } + }) + : FullWdtBtnLoader(onTap: () {}), + ), +*/ + const SizedBox(height: 20), + const Spacer(flex: 1), + ], + ), + ), + */ + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/forgotPassword/reset_password.dart b/gsf/lib/views/pages/forgotPassword/reset_password.dart new file mode 100644 index 0000000..c8caec9 --- /dev/null +++ b/gsf/lib/views/pages/forgotPassword/reset_password.dart @@ -0,0 +1,536 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/services/cj/update_password_service.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../../repository/response_data.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../components/primary_button.dart'; +import '../../theme.dart'; +import 'forgot_password_controller.dart'; + +class ResetPassword extends StatefulWidget { + const ResetPassword({ + Key? key, + required this.userId, + }) : super(key: key); + + final int userId; + + @override + State createState() => _ResetPasswordState(); +} + +class _ResetPasswordState extends State { + // final TextEditingController _newPassword = TextEditingController(); + // final TextEditingController _confirmPassword = TextEditingController(); + var fromKey = GlobalKey(); + bool _newPasswordVisible = false; + bool _confirmPasswordVisible = false; + bool _isPasswordEightCar = false; + bool _isHasOneNumber = false; + bool _isHasSymboleOrCaptital = false; + final forgotPasswordcontroller = Get.put(ForgotPasswordController()); + RegExp numricNumber = RegExp(r'^(?=.*?[0-9])'); + // RegExp uprCaseltr = RegExp(r'^(?=.*[A-Z])'); + RegExp uprCaseltr = RegExp(r'^(?=.*[A-Z])(?=.*?[!@#\$&*~])'); + + var cancelBtnController = RoundedLoadingButtonController(); + var resetBtnController = RoundedLoadingButtonController(); + + var newPasswordTextFieldController = TextEditingController(); + var confirmPasswordTextFieldController = TextEditingController(); + + final numricRegex = RegExp(r'[0-9]'); + final alphaRegex = RegExp(r'[A-Z]|(?=.*[@$!%*#?&])'); + + onPasswordChnage(String newPassword) { + setState(() { + _isPasswordEightCar = false; + if (newPassword.length >= 8) _isPasswordEightCar = true; + + _isHasOneNumber = false; + if (numricRegex.hasMatch(newPassword)) _isHasOneNumber = true; + + _isHasSymboleOrCaptital = false; + if (alphaRegex.hasMatch(newPassword)) _isHasSymboleOrCaptital = true; + }); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return WillPopScope( + onWillPop: () { + Get.offAll(const SignIn()); + return Future.value(false); + }, + child: Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Reset Password', + showLeading: false, + )), + body: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: SingleChildScrollView( + child: Form( + key: fromKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 30), + SizedBox( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'New Password', + style: TextStyle( + fontSize: 14, + color: Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + TextFormField( + onChanged: (newPassword) => + onPasswordChnage(newPassword), + style: const TextStyle( + color: Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: + AutovalidateMode.onUserInteraction, + controller: newPasswordTextFieldController, + obscureText: !_newPasswordVisible, + decoration: InputDecoration( + fillColor: const Color(0xff212121), + errorMaxLines: 3, + hintText: "", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 25, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: const Color(0xffffffff).withOpacity(0.8), + fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + filled: true, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _newPasswordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: + const Color(0xffffffff).withOpacity(0.5), + ), + onPressed: () { + setState(() { + _newPasswordVisible = !_newPasswordVisible; + }); + }, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + isDense: true, + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter password'; + } + if (value.length < 8) { + return 'Must be less than 8 characters'; + } + if (!numricRegex.hasMatch(value)) { + return 'At least one numeric value'; + } + if (!alphaRegex.hasMatch(value)) { + return 'Please enter at least one upper case letter.'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 25), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isPasswordEightCar + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + const Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + 'Has at least 8 characters.', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: Color(0xffffffff), + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isHasSymboleOrCaptital + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + const Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + 'Has at least 1 uppercase letter or symbol.', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: Color(0xffffffff), + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isHasOneNumber + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + const Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + 'Has a number', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: Color(0xffffffff), + ), + ), + ) + ], + ), + ], + ), + ), + const SizedBox(height: 40), + SizedBox( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Confirm Password', + style: TextStyle( + fontSize: 14, + color: Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + TextFormField( + style: const TextStyle( + color: Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: + AutovalidateMode.onUserInteraction, + controller: confirmPasswordTextFieldController, + obscureText: !_confirmPasswordVisible, + decoration: InputDecoration( + fillColor: const Color(0xff212121), + errorMaxLines: 3, + hintText: "", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 25, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: const Color(0xffffffff).withOpacity(0.8), + fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + filled: true, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _confirmPasswordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: + const Color(0xffffffff).withOpacity(0.5), + ), + onPressed: () { + setState(() { + _confirmPasswordVisible = + !_confirmPasswordVisible; + }); + }, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + isDense: true, + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please confirm password'; + } + if (value.length < 8) { + return 'Must be less than 8 characters'; + } + if (value != + newPasswordTextFieldController.text) { + return 'Password does not match'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 25), + ], + ), + ), + const SizedBox(height: 10), + + // const SizedBox(height: 50), + // Obx( + // () => !forgotPasswordcontroller.loader.value + // ? FullWdtBtn( + // btnText: 'Reset', + // onTap: () { + // Get.focusScope!.unfocus(); + // if (fromKey.currentState!.validate()) { + // forgotPasswordcontroller.updatePassword(); + // } + // }) + // : FullWdtBtnLoader(onTap: () {}), + // ), + PrimaryButton( + controller: resetBtnController, + onTap: () { + Get.focusScope!.unfocus(); + if (fromKey.currentState!.validate()) { + UpdatePasswordService() + .updatePassword( + userId: widget.userId.toString(), + password: newPasswordTextFieldController.text, + confirmPassword: + confirmPasswordTextFieldController.text, + ) + .then((responseModel) { + switch (responseModel.responseStatus) { + case ResponseStatus.success: + resetBtnController.success(); + Get.showSnackbar(const GetSnackBar( + duration: Duration(seconds: 4), + title: "Password Changed", + message: + "Please sign in using your new password", + )); + Get.offAll(() => const SignIn()); + break; + case ResponseStatus.failed: + resetBtnController.error(); + Get.showSnackbar(const GetSnackBar( + duration: Duration(seconds: 3), + title: "Password Dosen't Match", + message: "Please try again", + )); + break; + case ResponseStatus.expired: + case ResponseStatus.error: + resetBtnController.error(); + Get.showSnackbar(const GetSnackBar( + duration: Duration(seconds: 3), + title: "Cannot Reset Password", + message: "Please try again later", + )); + break; + } + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => resetBtnController.reset()); + }); + } else { + resetBtnController.reset(); + } + }, + text: "Reset", + ), + const SizedBox(height: 18), + // Container( + // width: screenSize.width * 1, + // height: 50, + // decoration: BoxDecoration( + // color: const Color(0xffD9D9D9), + // borderRadius: BorderRadius.circular(30), + // ), + // child: Center( + // child: InkWell( + // onTap: () => Get.offAll(() => const SignIn()), + // child: const Text( + // 'Cancel', + // style: TextStyle( + // fontSize: 16, + // color: Color(0xff000000), + // fontWeight: FontWeight.w500, + // fontFamily: 'Poppins', + // ), + // ), + // ), + // ), + // ), + + //cancel btn + PrimaryButton( + bgColor: ColorConstants.kWhite, + controller: cancelBtnController, + onTap: () { + Get.focusScope!.unfocus(); + Get.offAll(() => const SignIn()); + cancelBtnController.reset(); + }, + text: "Cancel", + ), + const SizedBox(height: 20), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/home/app_tour_guid.dart b/gsf/lib/views/pages/home/app_tour_guid.dart new file mode 100644 index 0000000..e88a6e2 --- /dev/null +++ b/gsf/lib/views/pages/home/app_tour_guid.dart @@ -0,0 +1,41 @@ +// import 'package:flutter/material.dart'; +// import 'package:gsp_app/views/theme.dart'; + +// class ShowCaseView extends StatelessWidget { +// const ShowCaseView({ +// Key? key, +// required this.globakey, +// required this.title, +// required this.descriptions, +// required this.child, +// // required this.next, +// // this.shapeBorder = const CircleBorder(), +// }) : super(key: key); +// final GlobalKey globakey; +// final String title; +// final String descriptions; +// final Widget child; +// // final Widget next; +// // final ShapeBorder shapeBorder; + +// @override +// Widget build(BuildContext context) { +// return Showcase( +// key: globakey, +// title: title, +// description: descriptions, +// child: child, +// overlayOpacity: 0.8, +// // targetPadding: EdgeInsets.all(2), +// overlayColor: ColorConstants.kPrimaryColor, +// // shapeBorder +// // targetShapeBorder: RoundedRectangleBorder( +// // borderRadius: BorderRadius.all( +// // Radius.circular(8), +// // ), +// // ), +// targetBorderRadius: BorderRadius.circular(100), +// // shapeBorder: shapeBorder, +// ); +// } +// } diff --git a/gsf/lib/views/pages/home/home.dart b/gsf/lib/views/pages/home/home.dart new file mode 100644 index 0000000..4d3fe39 --- /dev/null +++ b/gsf/lib/views/pages/home/home.dart @@ -0,0 +1,3367 @@ +// ignore_for_file: prefer_const_constructors + +import 'dart:async'; +import 'dart:developer'; +import 'dart:io'; +import 'dart:ui'; +// import 'package:flutter_background_service/flutter_background_service.dart'; +// import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:gsp_app/view_model/QuizApis.dart'; +import 'package:gsp_app/views/components/floating_action_btn.dart'; +import 'package:gsp_app/views/pages/podcast/viewModel/PodcastApis.dart'; +import 'package:gsp_app/views/pages/quiz/quiz_home.dart'; +import 'package:gsp_app/views/pages/splash.dart'; +import 'package:workmanager/workmanager.dart'; +// import 'package:flutter_background_service_android/flutter_background_service_android.dart'; + +import '/api/base_manager.dart' as cresponse; + +import 'package:animations/animations.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_background/flutter_background.dart'; +import 'package:get/get.dart'; +// import 'package:gsp_app/pages/blog/blog_inner.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/services/StoreLauncher.dart'; +import 'package:gsp_app/repository/services/cj/manage_banner_service.dart'; +import 'package:gsp_app/view_model/GetMoodometerValue.dart'; +import 'package:gsp_app/view_model/StepcountController.dart'; +import 'package:gsp_app/view_model/Stepcounts.dart'; +import 'package:gsp_app/view_model/VersionControl.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/app_tour_controller.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:gsp_app/views/components/videos_not_found.dart'; +import 'package:gsp_app/views/pages/StepCount/HealthApp.dart'; +import 'package:gsp_app/views/pages/courses/courses_overview.dart'; +import 'package:lottie/lottie.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:pedometer/pedometer.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:skeletons/skeletons.dart'; +import '../../../modals/leaderboard_ranking_model.dart'; +import '../../../modals/rank_position.dart'; +import '../../../modals/share_thoughts.dart'; +import '../../../modals/upcoming_session_model.dart'; +import '../../../repository/response_data.dart'; +import '../../../repository/services/cj/leader_board_ranking.dart'; +import '../../../repository/services/cj/moodOmeter_services.dart'; +import '../../../repository/services/cj/upcoming_activity_service.dart'; +import '../../../repository/services/home_controller.dart'; +import '../../../repository/services/share_thoughts_service.dart'; +import '../../../view_model/common_functions.dart'; +import '../../../view_model/global_controller.dart'; +import '../../../view_model/my_ranking_controller.dart'; +import '../../components/custom_skeleton.dart'; +import '../../components/mood_meter.dart'; +import '../../components/notification_icon.dart'; +import '../../../modals/manage_banner_model.dart'; +import '../../../modals/short_clip_likes_model.dart'; +import '../../../modals/short_clip_model.dart'; +import '../../../repository/services/complete_profile_service.dart'; +import '../../../repository/services/edit_profile_service.dart'; +import '../../../repository/services/meet_community_service.dart'; +import '../../../repository/services/short_clip_service.dart'; +import '../../components/upcoming_session.dart'; +import '../../short_video_player/svp_main.dart'; +import '../bioMaker/controller.dart'; +import '../diet_plan/diet_chart_preview.dart'; +import '../insta/insta_clip_list.dart'; +import '../insta/intsa_overview.dart'; +import '../podcast/podcast.dart'; +import '../podcast/podcast_list.dart'; +import '../podcast/podcast_list_audio.dart'; +import '../Sessions/count_me.dart'; +import '../shareThoutgh/mission_impossible.dart'; +import 'app_tour_guid.dart'; +import '../Sessions/live_session_detail.dart'; +import '../settings/setting_main.dart'; +import '../../components/bottom_navigation.dart'; +import '../../components/btn.dart'; +import '../../../view_model/bottom_navigation_controller.dart'; +import '../../../view_model/home_controller.dart'; +import '../../../view_model/home_page_controller.dart'; +import '../../../modals/member_modal.dart'; +import '../../theme.dart'; +import '../community/community.dart'; +import '../sidebar.dart'; +import '../signIn/sign_in.dart'; +import 'package:async/async.dart'; + +StepCountController stepController = Get.put(StepCountController()); + +String groupLevelNameGlobal = ''; +//int? appStepCountGlobal = 0; +// Define the reactive variable +// @pragma('vm:entry-point') +// void onStart(ServiceInstance service) async { +// // Only available for flutter 3.0.0 and later +// DartPluginRegistrant.ensureInitialized(); + +// // For flutter prior to version 3.0.0 +// // We have to register the plugin manually + +// SharedPreferences preferences = await SharedPreferences.getInstance(); +// await preferences.setString("hello", "world"); + +// /// OPTIONAL when use custom notification +// final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = +// FlutterLocalNotificationsPlugin(); + +// if (service is AndroidServiceInstance) { +// service.on('setAsForeground').listen((event) { +// service.setAsForegroundService(); +// }); + +// service.on('setAsBackground').listen((event) { +// service.setAsBackgroundService(); +// }); +// } + +// service.on('stopService').listen((event) { +// service.stopSelf(); +// }); + +// // bring to foreground +// // Timer.periodic(const Duration(seconds: 1), (timer) async { +// // if (service is AndroidServiceInstance) { +// // if (await service.isForegroundService()) { +// // /// OPTIONAL for use custom notification +// // /// the notification id must be equals with AndroidConfiguration when you call configure() method. +// // flutterLocalNotificationsPlugin.show( +// // 888, +// // 'COOL SERVICE', +// // 'Awesome ${DateTime.now()}', +// // const NotificationDetails( +// // android: AndroidNotificationDetails( +// // 'my_foreground', +// // 'MY FOREGROUND SERVICE', +// // icon: 'ic_bg_service_small', +// // ongoing: true, +// // ), +// // ), +// // ); + +// // // if you don't using custom notification, uncomment this +// // service.setForegroundNotificationInfo( +// // title: "GSF health service", +// // content: +// // "Step count ${stepController.appStepCountGlobal.value.toString()}", +// // ); +// // } +// // } + +// // /// you can see this log in logcat +// // print('FLUTTER BACKGROUND SERVICE: ${DateTime.now()}'); + +// // // // test using external plugin +// // // final deviceInfo = DeviceInfoPlugin(); +// // // String? device; +// // // if (Platform.isAndroid) { +// // // final androidInfo = await deviceInfo.androidInfo; +// // // device = androidInfo.model; +// // // } + +// // // if (Platform.isIOS) { +// // // final iosInfo = await deviceInfo.iosInfo; +// // // device = iosInfo.model; +// // // } + +// // // service.invoke( +// // // 'update', +// // // { +// // // "current_date": DateTime.now().toIso8601String(), +// // // "device": device, +// // // }, +// // // ); +// // }); +// } + +class Home extends StatefulWidget { + const Home({Key? key}) : super(key: key); + + @override + State createState() => _HomeState(); +} + +class _HomeState extends State with SingleTickerProviderStateMixin { + late AnimationController _animationController; + StepCountController stepController = Get.put(StepCountController()); + + FutureGroup futureGroup = FutureGroup(); + int? moodCheckResult; + + ContainerTransitionType transitionType = ContainerTransitionType.fade; + HomeApiController homeApiController = Get.put(HomeApiController()); + + Future showExitPopup() async { + // return Get.aler; + return await showDialog( + //show confirm dialogue + //the return value will be from "Yes" or "No" options + context: context, + builder: (context) => AlertDialog( + elevation: 10, + backgroundColor: Colors.black, + title: const Text( + 'Exit App', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + content: const Text( + 'Do you want to exit an App?', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + actionsAlignment: MainAxisAlignment.spaceAround, + actions: [ + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: ColorConstants.kPrimaryColor, + ), + onPressed: () => Navigator.of(context).pop(false), + //return false when click on "NO" + child: const Text( + 'No', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kBlack, + ), + ), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: ColorConstants.kPrimaryColor, + ), + onPressed: () => Navigator.of(context).pop(true), + //return true when click on "Yes" + child: const Text( + 'Yes', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kBlack, + ), + ), + ), + ], + ), + ) ?? + false; //if showDialouge had returned null, then return false + } + + final TabsController controller = TabsController(); + final NavigationCrontroller navController = Get.put(NavigationCrontroller()); + // int _current = 0; + + final CompleteProfileController completeProfileController = + Get.put(CompleteProfileController(), permanent: true); + + var members = + memberDetails.map((e) => MeetTheCommunityModel.fromJson(e)).toList(); + + // final ManageBanner manageBanners = Get.put(ManageBanner()); + // var homePageApi = FutureGroup(); + double textOpacity = 0.0; + // var shortClipNLikesFutureGrp = FutureGroup(); + final EditProfileController getProfileDatas = + Get.put(EditProfileController()); + AppDataController appDataController = Get.find(); + final StoreLauncher storeLauncher = Get.put(StoreLauncher()); + + var appTourController = Get.put(AppTourController()); + final aControllerFind = Get.put(AController()); + GlobalController globalContoller = Get.put(GlobalController()); + bool? showMoodOMeterAfterAppTour; + + var bannerMoodOMeterFutureGroup = FutureGroup(); + @override + void initState() { + bannerMoodOMeterFutureGroup.add(MoodOMeterService().getMoodOMeter()); + bannerMoodOMeterFutureGroup.add(ManageBannerService().fetchManageBanner()); + QuizeApis().showQuiz(); + bannerMoodOMeterFutureGroup.close(); + + // print('CURRENT POSITION OF USER ${appDataController.selfPosition.value}'); + + _animationController = AnimationController( + duration: const Duration(milliseconds: 600), + vsync: this, + ); + _animationController.forward(); + if (GetStorage().read("showAppTour") ?? false) { + showMoodOMeterAfterAppTour = true; + + Future.delayed(const Duration(seconds: 1), () { + appTourController.startAppTour(context, () { + // Your callback code here + setState(() { + showMoodOMeterAfterAppTour = false; + }); + }); + }); + GetStorage().write("showAppTour", false); + print("tour done"); + } else {} + + initiatePedometerModule(); + if (Platform.isAndroid) initBackgroundProcess(); + _getAppVersion(); + // initializeService(); + super.initState(); + GetMoodometerValue().getmoodValue(); + } + + Future _getAppVersion() async { + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + + // print("current version is ${packageInfo.version}"); + // print("current version is ${packageInfo.appName}"); + // print("current version is ${packageInfo.buildNumber}"); + // print("current version is ${packageInfo.installerStore}"); + + // appUpdateDialog(context); + if (Platform.isAndroid) { + var updata = {"old_version_android": packageInfo.buildNumber}; + final data = await VersionControl().storeCurrentVersion(updata); + if (data.status == cresponse.ResponseStatus.SUCCESS) { + final data1 = await VersionControl().getCurrentVersion(); + if (data1.status == cresponse.ResponseStatus.SUCCESS) { + if (packageInfo.buildNumber != version!.result!.newVersionAndroid!) { + appUpdateDialog(context); + } + } + } + } + if (Platform.isIOS) { + var updata = {"old_version_ios": packageInfo.version}; + final data = await VersionControl().storeCurrentVersion(updata); + if (data.status == cresponse.ResponseStatus.SUCCESS) { + final data1 = await VersionControl().getCurrentVersion(); + if (data1.status == cresponse.ResponseStatus.SUCCESS) { + if (packageInfo.version != version!.result!.newVersionIos!) { + appUpdateDialog(context); + } + } + } + } + } + + appUpdateDialog(BuildContext context) async { + await Future.delayed(Duration(milliseconds: 10)); + + showDialog( + context: context, + barrierDismissible: false, // Disable tapping outside to dismiss + barrierColor: ColorConstants.kBlack.withOpacity(0.9), + builder: (BuildContext context) { + return WillPopScope( + onWillPop: () async { + // Prevent dialog dismissal on back button press + return true; + }, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: context.width * 0.05), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: Color.fromARGB(255, 20, 20, 20), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, + vertical: 25, + ), + child: Column( + children: [ + Text("Update Available"), + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // SizedBox( + // width: 30, + // ), + // Text("Update Available"), + // Spacer(), + // GestureDetector( + // onTap: () { + // Get.back(); + // }, + // child: Icon(Icons.close)) + // ], + // ), + SizedBox(height: 20), + Text("A new version of the app is available"), + SizedBox(height: 25), + FullWdtBtn( + btnText: "Update", + onTap: () { + storeLauncher.launchStore(); + }), + SizedBox(height: 25), + FullWdtBtn( + btnText: "Skip", + onTap: () { + Get.back(); + }), + ], + ), + ), + ), + ], + ), + ), + ); + }, + ); + } + + initBackgroundProcess() async { + final androidConfig = FlutterBackgroundAndroidConfig( + shouldRequestBatteryOptimizationsOff: true, + showBadge: true, + notificationTitle: "GSF", + notificationText: "Recording step counts", + notificationImportance: AndroidNotificationImportance.High, + notificationIcon: + AndroidResource(name: 'background', defType: 'drawable'), + ); + + bool resp = + await FlutterBackground.initialize(androidConfig: androidConfig); + if (resp) { + await FlutterBackground.enableBackgroundExecution(); + } + } + + //pedometer module variables + late Stream _stepCountStream; + String _steps = '?'; + // Initialize a step count variable and a date variable + int _appStepCount = 0; + DateTime _currentDate = DateTime.now(); + Timer? _timer; + final calculateStepsFromHealthApp stepscontroller = + Get.put(calculateStepsFromHealthApp()); + initiatePedometerModule() { + // if (Platform.isAndroid) { + // permissionDialog(); + // getStepCountFromStorage(); + // checkAndUpdateDate(); + // } + if (Platform.isIOS) { + _startTimer(); + } + } + + void _startTimer() { + _timer = Timer.periodic(const Duration(seconds: 5), (timer) { + stepscontroller.fetchStepData(); + }); + _timer = Timer.periodic(const Duration(minutes: 10), (timer) { + stepscontroller.storeStepsInDB(); + }); + } + + // permissionDialog() async { + // Map statuses = await [ + // Permission.activityRecognition, + // ].request(); + // if (statuses[Permission.activityRecognition]!.isGranted) { + // initPlatformState(); + // } + // } + + // void initPlatformState() { + // _stepCountStream = Pedometer.stepCountStream; + // _stepCountStream.listen(onStepCount).onError(onStepCountError); + + // if (!mounted) return; + // } + + // When you receive step count updates from the pedometer package: + + // void onStepCount(StepCount event) { + // _steps = event.steps.toString(); + // _appStepCount = _appStepCount + 1; + // stepController.appStepCountGlobal.value = _appStepCount; + // updateAndPersistStepCount(null); + // print("pedometer value ${event.steps}"); + // // Timer.periodic(Duration(minutes: 7), (timer) { + // // Map updata = {"step_count": _appStepCount}; + // // StepCounts().storeSteps(updata); + // // }); + // // Check if the step count is a multiple of 1000 + // if (_appStepCount % 1000 == 0) { + // // Call the API to store steps + // Map updata = {"step_count": _appStepCount}; + // StepCounts().storeSteps(updata); + // } + // } + + // void onStepCountError(error) { + // print('onStepCountError: $error'); + // setState(() { + // _steps = 'Step Count not available'; + // }); + // } + + // // Function to update and persist the step count + // void updateAndPersistStepCount(int? manualCount) async { + // final prefs = await SharedPreferences.getInstance(); + // final currentDateKey = _currentDate + // .toLocal() + // .toString() + // .split(' ')[0]; // Use the date as the key + // prefs.setInt(currentDateKey, manualCount ?? _appStepCount); + // } + +// // Function to check and update the current date +// void checkAndUpdateDate() { +// final today = DateTime.now(); +// if (today.day != _currentDate.day) { +// // The date has changed, reset the step count and update the current date +// updateAndPersistStepCount(0); +// _currentDate = today; +// } +// } + +// // Function to retrieve the step count from storage during app initialization +// void getStepCountFromStorage() async { +// final currentDateKey = _currentDate.toLocal().toString().split(' ')[0]; +// final prefs = await SharedPreferences.getInstance(); +// final storedCount = prefs.getInt(currentDateKey) ?? 0; +// setState(() { +// _appStepCount = storedCount; +// stepController.appStepCountGlobal.value = _appStepCount; +// }); +// } + + @override + Widget build(BuildContext context) { + // shortClipNLikesFutureGrp.add(shortClipService.fetchShortClips()); + // shortClipNLikesFutureGrp.add(); + // var shortClipService = ShortClipService(); + // shortClipService.fetchShortClipLikes().then((value) => print("KSHAJFHDSJKFHJHFK${value}")); + + // + aControllerFind.localWeight.value = + GetStorage().read('localWeight') ?? '- -'; + aControllerFind.localMusclerate.value = + GetStorage().read('localMusclerate') ?? '- -'; + aControllerFind.localbodyFat.value = + GetStorage().read('localbodyFat') ?? '- -'; + aControllerFind.localSkeletalRate.value = + GetStorage().read('localSkeletalRate') ?? '- -'; + aControllerFind.localProtein.value = + GetStorage().read('localProtein') ?? '- -'; + + aControllerFind.localBmr.value = GetStorage().read('localBmr') ?? '- -'; + aControllerFind.localWater.value = GetStorage().read('localWater') ?? '- -'; + aControllerFind.localAge.value = GetStorage().read('localAge') ?? '- -'; + // ViewFriendsProfileService() + // .fetchFriendsProfile() + // .then((value) => debugPrint("ViewFriendsProfileService $value")); + // debugPrint( + // 'slected image value ${completeProfileController.selectedImagePath.value}'); + // debugPrint("isLoggedIn: ${controller.isLoggedIn}"); + // debugPrint("isScaled ${GetStorage().read("addScale")}"); + // final brightness = Get.theme.brightness; + + return Scaffold( + floatingActionButton: + Visibility(visible: showQuizbool, child: FlotingActionBtn()), + // backgroundColor: + // (brightness == Brightness.light) ? Colors.red : Colors.tealAccent, + key: controller.scaffoldKey, + drawer: AppDrawer(), + appBar: AppBar( + automaticallyImplyLeading: false, + leading: InkWell( + key: appTourController.navDrawer, + onTap: controller.openDrawer, + child: Padding( + padding: const EdgeInsets.all(8), + child: Obx( + () => Image.asset( + 'assets/image/${(globalContoller.darkMode.value == false) ? 'menu_dark' : 'menu'}.png', + ), + )), + ), + // ), + actions: [ + SizedBox( + child: (controller.isLoggedIn) + ? Row( + children: [ + Padding( + key: appTourController.notifications, + padding: EdgeInsets.all(4.0), + child: NotificationIcon(), + ), + + const SizedBox(width: 10), + Padding( + // key: appTourController.settings, + padding: const EdgeInsets.all(4), + child: InkWell( + splashColor: Color.fromARGB(0, 153, 112, 112), + onTap: () { + Get.to( + () => Settings(), + ); + }, + + // + // Get.to( + // () => const Settings(), + // ), + child: Icon( + Icons.settings_outlined, + color: ColorConstants.kWhite, + ), + ), + ), + // ), + const SizedBox(width: 20), + ], + ) + : GestureDetector( + onTap: () => Get.off( + () => const SignIn(), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Image.asset( + 'assets/image/logout.png', + width: 30, + ), + ), + ), + ) + ], + ), + + body: showMoodOMeterAfterAppTour ?? false + ? HomePageSkeleton() + : FutureBuilder( + future: bannerMoodOMeterFutureGroup + .future, //MoodOMeterService().getMoodOMeter(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + // While waiting for the API response, show a loading indicator + return Center(child: HomePageSkeleton()); + } else if (snapshot.hasError) { + // If an error occurred during the API call, display an error message + return Text('Error: ${snapshot.error}'); + } else { + if (homeApiController.moodCheckResult == "1") { + moodOMeterDialog(context); + } + // API call was successful and data is available + // List data = snapshot.data!; + + // // Use the fetched data to build your UI + // return ListView.builder( + // itemCount: data.length, + // itemBuilder: (context, index) { + // return ListTile( + // title: Text(data[index]), + // ); + // }, + // ); + return AnimatedBuilder( + child: GestureDetector( + child: Obx( + () => SingleChildScrollView( + child: BannerContent( + bannerModel: ManageBannerModel( + bannerPath: appDataController.bannerPath.value, + bannerPosition: + appDataController.bannerPosition.value), + ), + ), + ), + ), + animation: _animationController, + builder: (context, child) { + return FadeScaleTransition( + animation: _animationController, + child: child, + ); + }, + ); + } + }), + bottomNavigationBar: BottomNavigation(), + ); + } + + rewardPointDialog(BuildContext context) async { + // AppDataController appDataController = Get.find(); + print( + 'homeApiController.setMoodResponse.progressBar ${homeApiController.setMoodResponse.progressBar}'); + await Future.delayed(Duration(milliseconds: 10)); + showDialog( + context: context, + barrierDismissible: false, + barrierColor: ColorConstants.kBlack.withOpacity(0.9), + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: context.width * 0.05), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: Color.fromARGB(255, 20, 20, 20), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + // Positioned( + // top: -80, + // left: 0, + // right: 0, + // child: Align( + // alignment: Alignment.center, + // child: Container( + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(100), + // ), + // width: 100, + // height: 100, + // child: appDataController.profilePicUrl.value.isEmpty + // ? CircleAvatar( + // backgroundColor: ColorConstants.kPrimaryColor, + // child: const Icon( + // Icons.person_rounded, + // size: 52, + // color: Colors.black, + // ), + // ) + // : CircleAvatar( + // backgroundImage: NetworkImage( + // appDataController.profilePicUrl.value), + // ), + // ), + // ), + // ), + + Column( + children: [ + Align( + alignment: Alignment.centerRight, + child: GestureDetector( + onTap: () { + Get.back(); + }, + child: Icon( + Icons.close, + color: ColorConstants.kPrimaryColor, + size: 25, + ), + ), + ), + // const SizedBox(height: 30), + + LottieBuilder.network( + "https://assets6.lottiefiles.com/packages/lf20_touohxv0.json", + // height: , + height: 250, + width: 200, + ), + + Text( + "Congratulations", + style: TextStyle( + fontSize: 25, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w500, + ), + ), + + SizedBox( + height: 10, + ), + + Text( + // HomeApiController().setMoodResponse, + homeApiController.setMoodResponse.progressBar ?? "", + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + + // TextSpan( + // text: appDataController.name.value, + // style: TextStyle( + // fontSize: 17, + // color: ColorConstants.kPrimaryColor, + // fontWeight: FontWeight.w500, + // ), + // ) + + // const SizedBox(height: 34), + ], + ), + ], + ), + ), + ), + ], + ), + ); + }, + ); + } + + missionPossible(BuildContext context) { + showDialog( + context: context, + barrierDismissible: false, + barrierColor: ColorConstants.kBlack.withOpacity(0.9), + builder: (BuildContext context) { + // print('mission impossible'); + return Padding( + padding: EdgeInsets.symmetric(horizontal: context.width * 0.05), + child: FutureBuilder( + future: GetOurThoughts().getShareThoughtsData(), + builder: (context, snapshot) { + // print("Get thouths dtata news ${snapshot.data!.data}"); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + ShareOurthoutghs shareThoughts = snapshot.data!.data; + final yourThoutghs = shareThoughts.userThoughts.split('-'); + // print('yourThoutghs ${yourThoutghs}'); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -80, + left: 0, + right: 0, + child: Align( + alignment: Alignment.center, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + width: 100, + height: 100, + child: Image.asset( + 'assets/image/feedback_img/power.png', + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + ), + ), + Column( + children: [ + const SizedBox(height: 56), + Text( + yourThoutghs[0], + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + Text( + yourThoutghs[1], + style: TextStyle( + fontSize: 42, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w600, + letterSpacing: 3, + height: 1, + ), + ), + Text( + yourThoutghs[2], + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + height: 1, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + const SizedBox(height: 35), + FullWdtBtn( + btnText: "Let's Go", + onTap: () { + // Get.back(); + Get.back(); + // rewa + rewardPointDialog(context); + // Get.to( + // ); + + // Get.offAll( + // () => ShowCaseWidget( + // builder: Builder( + // builder: (context) => const HomePage(), + // ), + // ), + // () => const HomePage(), + // ); + }, + ) + ], + ), + ], + ), + ), + ), + ], + ); + } + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + CircularProgressIndicator(), + ], + ); + }, + ), + ); + }, + ); + } + + calculateMood(int index) { + switch (index) { + case 0: + MoodOMeterService().uploadMood("Very Happy"); + break; + case 1: + MoodOMeterService().uploadMood("Happy"); + break; + case 2: + MoodOMeterService().uploadMood("Ok"); + break; + case 3: + MoodOMeterService().uploadMood("Whatever"); + break; + case 4: + MoodOMeterService().uploadMood("Sad"); + break; + default: + Get.snackbar( + 'Error', + 'Select something', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + break; + } + } + + moodOMeterDialog(BuildContext context) async { + AppDataController appDataController = Get.find(); + await Future.delayed(Duration(milliseconds: 10)); + showDialog( + context: context, + barrierDismissible: false, + barrierColor: ColorConstants.kBlack.withOpacity(0.9), + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: context.width * 0.05), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: Color.fromARGB(255, 20, 20, 20), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -80, + left: 0, + right: 0, + child: Align( + alignment: Alignment.center, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + width: 100, + height: 100, + child: appDataController.profilePicUrl.value.isEmpty + ? CircleAvatar( + child: const Icon( + Icons.person_rounded, + size: 52, + color: Colors.black, + ), + backgroundColor: Colors.transparent, + ) + : CircleAvatar( + backgroundImage: NetworkImage( + appDataController.profilePicUrl.value, + ), + backgroundColor: Colors.transparent, + ), + ), + ), + ), + Column( + children: [ + const SizedBox(height: 30), + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Hey ', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w500, + ), + ), + TextSpan( + text: appDataController.name.value, + style: TextStyle( + fontSize: 17, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + ), + const Text( + 'How are you feeling?', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 34), + const MoodOMeter(), + const SizedBox(height: 34), + FullWdtBtn( + btnText: 'Share your thoughts!', + onTap: () { + if (activeIndexMoodOMeter == -1) { + Get.snackbar( + 'Error', + 'Select something', + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + } else { + calculateMood(activeIndexMoodOMeter); + box.write('showMoodOmeter', false); + Get.back(); + missionPossible(context); + // Get.to(); + } + }, + ) + ], + ), + ], + ), + ), + ), + ], + ), + ); + }, + ); + } +} + +class BannerContent extends StatefulWidget { + final ManageBannerModel bannerModel; + const BannerContent({required this.bannerModel, Key? key}) : super(key: key); + + @override + State createState() => _BannerContentState(); +} + +class _BannerContentState extends State { + final CarouselController _controller = CarouselController(); + HomePageController homePageController = Get.put(HomePageController()); + final TabsController controller = TabsController(); + AnimationController? _animationController; + double textOpacity = 0.0; + int _current = 0; + late List bannerContent; + var shortClipNLikesFutureGrp = FutureGroup(); + final box = GetStorage(); + RxBool showPodcast = true.obs; + List list = [ + { + 'img': 'assets/image/home_slider_img.png', + 'headTxt': 'Killing Your Way to Achieve', + 'subText': 'Summer Body!', + 'btntxt': 'Start My 7 Days Free Trial', + }, + { + 'img': 'assets/image/home_slider_img.png', + 'headTxt': 'Torch Those', + 'subText': 'Calories', + 'btntxt': 'Start My 7 Days Free Trial', + }, + { + 'img': 'assets/image/home_slider_img.png', + 'headTxt': 'Get Fit', + 'subText': 'With Us', + 'btntxt': 'Start My 7 Days Free Trial', + } + ]; + + var members = + memberDetails.map((e) => MeetTheCommunityModel.fromJson(e)).toList(); + AppDataController appDataController = Get.find(); + + @override + void initState() { + var shortClipService = ShortClipService(); + shortClipNLikesFutureGrp.add(shortClipService.fetchShortClips()); + shortClipNLikesFutureGrp.add(shortClipService.fetchShortClipLikes()); + shortClipNLikesFutureGrp.close(); + + super.initState(); + // readThoutgh(); + // box.read('showMoodOmeter') ?? true ? moodOMeterDialog(context) : null; + } + + // readThoutgh() { + // if (moodOmeter) { + // moodOMeterDialog(context); + // } + // } + + // bool get moodOmeter => box.read('showMoodOmeter') ?? true; + + @override + Widget build(BuildContext context) { + bannerContent = [ + sectionOne(), + sectionTwo(), + // sectionThree(), + sectionFour(), + sectionFive(), + sectionSix(), + sectionSeven(), + sectionPodcasts(), + //sectionEight(), + sectionNine() + ]; + bannerContent.remove(sectionThree(widget.bannerModel.bannerPath)); + bannerContent.insert(widget.bannerModel.bannerPosition, + sectionThree(widget.bannerModel.bannerPath)); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: bannerContent, + ); + } + + Widget sectionOne() { + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 10), + Obx( + () => Padding( + padding: const EdgeInsets.only(left: 20.0), + child: Text( + "Hey, " + appDataController.name.value, + style: TextStyle( + fontSize: 22, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w700, + // letterSpacing: 1, + ), + ), + ), + ), + Obx( + () => Padding( + padding: EdgeInsets.only(left: 20.0, top: 5), + child: Text( + 'Let\'s Get Started!', + style: TextStyle( + fontSize: 22, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400, + // letterSpacing: 1.5, + ), + ), + ), + ), + const SizedBox(height: 20), + // sliderArea(), + ], + ); + } + + Widget sectionTwo() { + // final aControllerFind = Get.put(AController()); + // bool isScaleAdd = GetStorage().read("addScale") ?? false; + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: loggedInSlider(), + ), + const SizedBox(height: 20) + ], + ); + } + + Widget sectionThree(String bannerUrl) { + final screenSize = MediaQuery.of(context).size; + // print('widget.bannerModel.bannerPath ${widget.bannerModel.bannerPath}'); + return Column( + children: [ + SizedBox(height: 20), + FadeInImage.assetNetwork( + placeholder: "assets/image/placeholder.jpg", + image: bannerUrl, + width: screenSize.width * 1, + fit: BoxFit.cover, + ), + SizedBox(height: 20), + ], + ); + } + + Widget sectionFour() { + GlobalController globalContoller = Get.find(); + // final brightness = Get.theme.brightness; + MyRankingController myRankingController = Get.put(MyRankingController()); + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Obx( + () => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 10), + Text( + 'Community', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : Color(0xffffffff), + ), + ), + const SizedBox(height: 5), + Text( + 'Leaderboard', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : Color(0xffB7B7B7), + ), + ), + const SizedBox(height: 40), + FutureBuilder( + future: RankingLeaderboard().getLeaderBoardDataWithoutFilter(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + RnakingModel userRanking = snapshot.data!.data; + myRankingController.defaultGenderStore.value = + userRanking.gender; + myRankingController.defaultGroupLevelStore.value = + userRanking.groupLevel; + + // print('userRanking ${userRanking.groupLevel}'); + String generateGroupLevels() { + if (userRanking.groupLevel == "elites") { + groupLevelNameGlobal = "Swole"; + return "Swole"; + } else if (userRanking.groupLevel == "gameChangers") { + groupLevelNameGlobal = "Up Steppersle"; + return "Up Steppers"; + } else if (userRanking.groupLevel == "underdogs") { + groupLevelNameGlobal = "Rookie"; + return "Rookie"; + } + return "Swole"; + } + + myRankingController.groupLevel.value = + generateGroupLevels(); + } + return SizedBox(); + }), + FutureBuilder( + future: + RankingLeaderboard().getLeaderBoardDataWithoutFilterHome(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + RnakingModel userRanking = snapshot.data!.data; + return Obx(() => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Index 0 + userRanking.userData!.length >= 1 + ? GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(3), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + width: Get.size.width * 0.26, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(10), + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff333333), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.2), + offset: const Offset( + 2.0, + 2.0, + ), + blurRadius: 10.0, + spreadRadius: 2.0, + ) + ], + ), + child: Padding( + padding: const EdgeInsets.only( + top: 12.0, + left: 12, + right: 12, + bottom: 10, + ), + child: Column( + children: [ + // Image.asset( + // 'assets/image/1.png', + // fit: BoxFit.cover, + // ), + ClipRRect( + borderRadius: + BorderRadius.circular(100), + child: (userRanking + .userData![0] + .userData! + .profilePicture != + null && + userRanking + .userData![0] + .userData! + .profilePicture! + .isNotEmpty) + ? Image.network( + correctImgUrl( + '${userRanking.userData![0].userData!.profilePicture}'), + width: 60, + height: 60, + ) + : ClipRRect( + borderRadius: + BorderRadius + .circular(100), + child: Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I=', + width: 60, + height: 60, + ), + ), + ), + SizedBox(height: 10), + Text( + userRanking + .userData![0].user!.fullName + .toUpperCase(), + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + '${userRanking.userData![0].totalScore} Pt', + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + .withOpacity(0.6) + : ColorConstants + .kPrimaryColor, + ), + ) + ], + ), + ), + ), + Positioned( + top: -40, + right: -5, + child: Stack( + children: [ + Positioned( + left: 0, + child: Text( + '1', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + color: !globalContoller + .darkMode.value + ? Colors.white + : ColorConstants + .kBlack), + ), + ), + Text( + '1', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1 + ..color = !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants + .kPrimaryColor, + ), + ), + ], + ), + ), + ], + ), + ) + : SizedBox( + width: Get.size.width * 0.26, + ), + // index 2 + userRanking.userData!.length >= 2 + ? GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(3), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + width: Get.size.width * 0.26, + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff333333), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.2), + offset: const Offset( + 2.0, + 2.0, + ), + blurRadius: 10.0, + spreadRadius: 2.0, + ) + ], + borderRadius: + BorderRadius.circular(10), + ), + child: Padding( + padding: const EdgeInsets.only( + top: 12.0, + left: 12, + right: 12, + bottom: 10, + ), + child: Column( + children: [ + // Image.asset( + // 'assets/image/1.png', + // fit: BoxFit.cover, + // ), + ClipRRect( + borderRadius: + BorderRadius.circular(100), + child: (userRanking + .userData![1] + .userData! + .profilePicture != + null && + userRanking + .userData![1] + .userData! + .profilePicture! + .isNotEmpty) + ? Image.network( + correctImgUrl( + '${userRanking.userData![1].userData!.profilePicture}'), + width: 60, + height: 60, + ) + : ClipRRect( + borderRadius: + BorderRadius + .circular(100), + child: Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I=', + width: 60, + height: 60, + ), + ), + ), + SizedBox(height: 10), + Text( + userRanking + .userData![1].user!.fullName + .toUpperCase(), + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + '${userRanking.userData![1].totalScore} Pt', + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + .withOpacity(0.6) + : ColorConstants + .kPrimaryColor, + ), + ) + ], + ), + ), + ), + Positioned( + top: -40, + right: -15, + child: Stack( + children: [ + Positioned( + child: Text( + '2', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + color: !globalContoller + .darkMode.value + ? Colors.white + : ColorConstants + .kBlack), + ), + ), + Text( + '2', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1 + ..color = !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants + .kPrimaryColor, + ), + ), + ], + ), + ), + ], + ), + ) + : SizedBox( + width: Get.size.width * 0.26, + ), + // index 3 + userRanking.userData!.length >= 3 + ? GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(3), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + width: Get.size.width * 0.26, + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff333333), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack + .withOpacity(0.2), + offset: const Offset( + 2.0, + 2.0, + ), + blurRadius: 10.0, + spreadRadius: 2.0, + ) + ], + borderRadius: + BorderRadius.circular(10), + ), + child: Padding( + padding: const EdgeInsets.only( + top: 12.0, + left: 12, + right: 12, + bottom: 10, + ), + child: Column( + children: [ + // Image.asset( + // 'assets/image/1.png', + // fit: BoxFit.cover, + // ), + ClipRRect( + borderRadius: + BorderRadius.circular(100), + child: (userRanking + .userData![2] + .userData! + .profilePicture != + null && + userRanking + .userData![2] + .userData! + .profilePicture + ?.isNotEmpty != + null) + ? Image.network( + correctImgUrl( + '${userRanking.userData![2].userData!.profilePicture}'), + width: 60, + height: 60, + ) + : ClipRRect( + borderRadius: + BorderRadius + .circular(100), + child: Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I=', + width: 60, + height: 60, + ), + ), + ), + SizedBox(height: 10), + Text( + userRanking + .userData![2].user!.fullName + .toUpperCase(), + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + '${userRanking.userData![2].totalScore} Pt', + style: TextStyle( + fontSize: 12, + color: !globalContoller + .darkMode.value + ? ColorConstants.kBlack + .withOpacity(0.6) + : ColorConstants + .kPrimaryColor, + ), + ) + ], + ), + ), + ), + Positioned( + top: -40, + right: -15, + child: Stack( + children: [ + Positioned( + child: Text( + '3', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + color: !globalContoller + .darkMode.value + ? Colors.white + : ColorConstants.kBlack, + ), + ), + ), + Text( + '3', + style: TextStyle( + fontSize: 64, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w800, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1 + ..color = !globalContoller + .darkMode.value + ? ColorConstants.kBlack + : ColorConstants + .kPrimaryColor, + ), + ), + ], + ), + ), + ], + ), + ) + : SizedBox( + width: Get.size.width * 0.26, + ), + ], + )); + } + return SizedBox( + height: 124, + child: ListView.builder( + itemCount: 3, + shrinkWrap: true, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 3.8, + height: 120, + borderRadius: BorderRadius.circular(10), + ), + ); + }, + ), + ); + }, + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: FullWdtBtn( + // styleElement: TextStyle(fontSize: 15), + btnText: 'View Leaderboard', + onTap: () => homePageController.updateBottomNavIndex(3), + ), + ), + const SizedBox(height: 20), + ], + ), + ), + ); + } + + Widget sectionFive() { + // GlobalController globalContoller = Get.find(); + // final screenSize = MediaQuery.of(context).size; + + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: headWithArrow( + 'Upcoming Live Activities', + () { + HomePageController.SessionsActiveTabIndex = 1; + homePageController.updateBottomNavIndex(1); + }, + ), + ), + const SizedBox(height: 10), + UpcomingSession(), + const SizedBox(height: 20), + ], + ); + } + + Widget sectionSix() { + GlobalController globalContoller = Get.find(); + final screenSize = MediaQuery.of(context).size; + bool isScaleStablized = GetStorage().read("scaleStablized") ?? false; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Obx( + () => Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text( + 'Personalised Nutrition Plan', + style: TextStyle( + fontSize: 17, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400, + ), + ), + ), + ), + const SizedBox(height: 15), + Stack( + children: [ + Image.asset( + 'assets/image/dietbg.jpeg', + width: screenSize.width * 1, + fit: BoxFit.cover, + ), + Positioned( + left: 0, + right: 0, + bottom: 20, + child: Column( + children: [ + const Text( + 'Is Your Food Helping You?', + style: TextStyle( + color: ColorConstants.kWhite, + fontSize: 18, + fontWeight: FontWeight.w600, + fontFamily: 'SFPRO', + letterSpacing: 0.5, + ), + ), + const SizedBox(height: 16), + SizedBox( + width: 250, + child: FullWdtBtn( + btnText: 'View Meal Plan', + onTap: () { + isScaleStablized + ? Get.to(() => DietChartPlan()) + : homePageController.updateBottomNavIndex(2); + }, + ), + ) + ], + ), + ), + ], + ), + const SizedBox(height: 20), + ], + ); + } + + Widget sectionSeven() { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: headWithArrow( + 'Bites', + () => Get.to( + () => InstaClips(), + ), + ), + ), + const SizedBox(height: 10), + // FutureBuilder>( + // future: ShortClipService().fetchShortClips(), + // builder: (context, snapshot) { + // if (snapshot.connectionState == ConnectionState.done && + // snapshot.hasData) { + // return HomePageShortClipsList(clips: snapshot.data!); + // } + // return HomePageShortVideosShimmer(); + // }, + // ), + + FutureBuilder( + future: shortClipNLikesFutureGrp.future, + builder: (context, snapshot) { + // print("hjkdgjhfskdjhfjkdhs ${snapshot.data}"); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + ShortClipTemp.tempClips = snapshot.data![0]; + ShortClipTemp.tempclipLikes = snapshot.data![1]; + + // print("kdfslndfsdsf ${][0].isLiked}"); + for (ShortClipLikesModel m in snapshot.data![1]) {} + + if (snapshot.data![0].isNotEmpty) { + return HomePageShortClipsList( + clips: snapshot.data![0], + shortClipLikesModel: snapshot.data![1], + ); + } + return VideosNotFound(); + } + return HomePageShortVideosShimmer(); + }, + ), + const SizedBox(height: 30), + ], + ); + } + + Widget sectionNine() { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Column( + children: [ + meetTheCommunity(), + const SizedBox(height: 10), + ], + ), + ), + ], + ); + } + + Widget sectionPodcasts() { + return Obx( + () { + return Visibility( + visible: showPodcast.value, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: headWithArrow( + 'Podcasts', + () => Get.to( + () => PodcastMain(), + ), + ), + ), + const SizedBox(height: 10), + // FutureBuilder>( + // future: ShortClipService().fetchShortClips(), + // builder: (context, snapshot) { + // if (snapshot.connectionState == ConnectionState.done && + // snapshot.hasData) { + // return HomePageShortClipsList(clips: snapshot.data!); + // } + // return HomePageShortVideosShimmer(); + // }, + // ), + + FutureBuilder( + future: PodcastApis().getPodcasts(), + builder: (context, snapshot) { + // print("hjkdgjhfskdjhfjkdhs ${snapshot.data}"); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + if (pods!.result!.latestPodcast!.isEmpty) { + Future.delayed(Duration(seconds: 1), + () => showPodcast.value = false); + } + return SizedBox( + height: 170, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: pods?.result?.latestPodcast?.length ?? 0, + itemBuilder: (context, index) => GestureDetector( + onTap: () { + Get.to(() => PodcastAudioPalyer()); + }, + child: Padding( + padding: const EdgeInsets.only(left: 10, right: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: SizedBox( + width: 94, + height: 94, + child: Image.network( + pods!.result!.latestPodcast![index] + .bannerImage!, + fit: BoxFit.cover, + ), + ), + ), + ), + const SizedBox(height: 10), + Text( + pods!.result!.latestPodcast![index].title!, + style: TextStyle( + fontSize: 12, + color: Color(0xffFFFFFF), + ), + ), + SizedBox( + height: 5, + ), + Image.asset('assets/image/music.png'), + SizedBox( + height: 5, + ), + // const Text( + // '0.30 Min', + // style: TextStyle( + // fontSize: 10, + // color: ColorConstants.kWhite, + // ), + // ) + ], + ), + ), + ), + ), + ); + } + return HomePageShortVideosShimmer(); + }, + ), + const SizedBox(height: 30), + ], + ), + ); + }, + ); + } + + Widget courses() { + GlobalController globalContoller = Get.find(); + return SizedBox( + height: 120, + child: ListView.builder( + itemCount: 12, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => OpenContainerWrappers( + openBuild: CoursesOverview(), + closeBuild: Obx( + () => Container( + margin: EdgeInsets.only(right: 20), + width: Get.width * 0.36, + // height: 200, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(4), + child: Image.asset( + 'assets/image/courses/fitness.jpg', + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 10), + Text( + 'Healthy with GSF', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ), + ), + ), + ); + } + + Widget sliderArea() { + final screenSize = Get.mediaQuery.size; + return StatefulBuilder(builder: (context, setSliderState) { + return Column( + children: [ + CarouselSlider( + carouselController: _controller, + options: CarouselOptions( + height: 400, + viewportFraction: 1.0, + autoPlay: true, + enableInfiniteScroll: false, + // autoPlayCurve: Curves.linear, + autoPlayInterval: const Duration(seconds: 3), + onPageChanged: (index, reason) { + // setState(() { + // _current = index; + // }); + setSliderState( + () { + _current = index; + }, + ); + }), + items: list + .map( + (item) => Container( + width: screenSize.width * 1, + height: 400, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + item['img'], + ), + fit: BoxFit.cover, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + width: 62, + height: 62, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + borderRadius: BorderRadius.circular(100), + ), + child: InkWell( + // onTap: (() => Get.to(() => const VimeoPlayer())), + child: const Icon( + Icons.play_arrow, + size: 40, + color: ColorConstants.kBlack, + ), + ), + ), + const SizedBox(height: 40), + Text( + item['headTxt'], + style: const TextStyle( + fontSize: 26, + color: Color(0xffE9E9E9), + ), + ), + Text( + item['subText'], + style: const TextStyle( + fontSize: 26, + color: Color(0xffE9E9E9), + fontWeight: FontWeight.bold, + letterSpacing: 1, + ), + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.only( + left: 50, right: 50, bottom: 30), + child: FullWdtBtn( + btnText: (controller.isLoggedIn) + ? 'Explore Now' + : item['btntxt'], + onTap: () {}, + styleElement: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ) + ], + ), + ), + ) + .toList(), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: list.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => _controller.animateToPage(entry.key), + child: Container( + width: 15, + height: 2, + margin: const EdgeInsets.symmetric( + vertical: 6.0, horizontal: 2.0), + decoration: BoxDecoration( + // shape: BoxShape.circle, + color: (_current == entry.key + ? ColorConstants.kPrimaryColor + : const Color(0xff858585)), + ), + ), + ); + }).toList(), + ), + ], + ); + }); + } + + Widget meetTheCommunity() { + final screenSize = Get.mediaQuery.size; + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + return SizedBox( + height: 210, + // width: screenSize.width * 1, + child: FutureBuilder( + future: MeetTheCommunityService().fetchCommunityData(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // print('snapshot.data ${snapshot.data}'); + // print('image data ${snapshot.data![0].user}'); + + return Column( + children: [ + headWithArrow('Meet the Community', () { + Get.to( + () => CommunityMember( + communityModel: snapshot.data!.user!, + ), + ); + }), + const SizedBox(height: 10), + Expanded( + child: ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.all(0), + physics: const BouncingScrollPhysics(), + itemCount: snapshot.data!.user!.length, + itemBuilder: (context, index) { + return GestureDetector( + // onTap: () => bottomSheetDesc(snapshot.data![index]), + onTap: () => Get.to(() => CommunityMember( + communityModel: snapshot.data!.user!, + )), + child: Obx( + () => Padding( + padding: const EdgeInsets.only( + left: 35.0, right: 10, top: 00), + child: Container( + width: screenSize.width * 0.7, + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.1) + : const Color(0xff191919), + borderRadius: BorderRadius.circular(11), + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: 0, + left: -50, + child: ClipRRect( + borderRadius: + BorderRadius.circular(12), + child: Image.network( + "https://thegsf.co/public/uploads/testimonial/${snapshot.data!.user![index].testimonialData!.first.images}", + width: 100, + height: 150, + fit: BoxFit.cover, + ), + ), + ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Expanded( + child: SizedBox(), + flex: 1, + ), + Expanded( + flex: 5, + child: Padding( + padding: const EdgeInsets.only( + left: 20.0), + child: Column( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + snapshot.data! + .user![index].title + .toString(), + style: TextStyle( + fontSize: 16, + color: !globalContoller + .darkMode.value + ? ColorConstants + .kBlack + : ColorConstants + .kPrimaryColor, + ), + maxLines: 2, + overflow: + TextOverflow.ellipsis, + ), + const SizedBox(height: 5), + // SizedBox( + // height: 20, + // child: ListView.builder( + // itemCount: 5, + // scrollDirection: + // Axis.horizontal, + // itemBuilder: + // (context, index1) { + // if (index1 < + // snapshot.data![index] + // .rating!) { + // return Icon( + // Icons.star, + // size: 18, + // color: (brightness == + // Brightness + // .light) + // ? ColorConstants + // .kBlack + // : ColorConstants + // .kPrimaryColor, + // ); + // } else { + // return Icon( + // Icons.star_outline, + // size: 18, + // color: + // Color(0xff8D8D8D), + // ); + // } + // }, + // ), + // ), + const SizedBox(height: 10), + Text( + snapshot + .data! + .user![index] + .description + .toString(), + style: TextStyle( + fontSize: 14, + color: !globalContoller + .darkMode.value + ? ColorConstants + .kBlack + : Color(0xffD9D9D9), + height: 1.3, + ), + maxLines: 3, + overflow: + TextOverflow.ellipsis, + ), + const SizedBox(height: 10), + Text( + snapshot.data! + .user![index].userName + .toString(), + style: TextStyle( + fontSize: 15, + color: !globalContoller + .darkMode.value + ? ColorConstants + .kBlack + : ColorConstants + .kWhite, + fontWeight: + FontWeight.w600, + ), + maxLines: 2, + overflow: + TextOverflow.ellipsis, + ) + ], + ), + ), + ), + ], + ), + ], + ), + ), + ), + ), + )); + }, + ), + ), + ], + ); + } + return meetTheCommunityLoader(); + }), + ); + } + + meetTheCommunityLoader() { + return SizedBox( + height: 180, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: 3, + physics: const ScrollPhysics(), + itemBuilder: (context, index) => SizedBox( + width: Get.width * 0.95, + child: Row( + children: [ + Expanded( + flex: 2, + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width, + height: 170, + borderRadius: BorderRadius.circular(10), + ), + ), + ), + Expanded( + flex: 4, + child: Column( + children: [ + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 3, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + const SizedBox(height: 5), + SkeletonParagraph( + style: SkeletonParagraphStyle( + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: true, + height: 15, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + bottomSheetDesc(data) { + return showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + child: Container( + decoration: const BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25.0), + topRight: Radius.circular(25.0), + ), + ), + height: Get.height * 0.85, + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.network( + '${data.img}', + fit: BoxFit.cover, + height: 250, + width: Get.width, + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + '${data.title}', + style: const TextStyle( + fontSize: 16, color: ColorConstants.kPrimaryColor), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SizedBox( + height: 20, + child: ListView.builder( + itemCount: 5, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index1) { + if (index1 < data.rating!) { + return const Icon( + Icons.star, + size: 18, + color: ColorConstants.kPrimaryColor, + ); + } else { + return const Icon( + Icons.star_outline, + size: 18, + color: Color(0xff8D8D8D), + ); + } + }, + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + data.desc, + style: const TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + height: 1.3, + ), + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Text( + '${data.memberName}', + style: const TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ) + ], + ), + ), + ), + ), + ); + } + + Widget headWithArrow(String head, VoidCallback ontap) { + GlobalController globalContoller = Get.find(); + // final brightness = Get.theme.brightness; + return Obx( + () => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + head, + style: TextStyle( + fontSize: 17, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + ), + ), + InkWell( + onTap: ontap, + child: Icon( + Icons.keyboard_arrow_right, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + size: 30, + ), + ) + ], + ), + ); + } + + Widget loggedInSlider() { + final aControllerFind = Get.put(AController()); + // final brightnes = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + // final screenSize = Get.mediaQuery.size; + final brightness = Get.theme.brightness; + // String? weightRangeTxt; + // String? bmrRangeTxt; + String? mRangeTxt; + String? waterRangeTxt; + String? bodyfatRangeTxt; + // int? weightRangeClr; + int? waterRangeClr; + int? bodyFatRangeClr; + // int? bmrRangeClr; + int? mrRangeClr; + + bool isScaleStablized = GetStorage().read("scaleStablized") ?? false; + double mrPercentage = double.parse( + (aControllerFind.localMusclerate.value == '- -') + ? '0.0' + : aControllerFind.localMusclerate.value); + + // BMR rate calculation range + double bmrPercentage = double.parse( + (aControllerFind.localBmr.value == '- -') + ? '0.0' + : aControllerFind.localBmr.value, + ); + + // body fate rate calculation range + double bodyFatPercentage = double.parse( + (aControllerFind.localbodyFat.value == '- -') + ? '0.0' + : aControllerFind.localbodyFat.value, + ); + + // water calculation range + double wPercentage = double.parse( + (aControllerFind.localWater.value == '- -') + ? '0.0' + : aControllerFind.localWater.value); + + String gender = appDataController.gender.toString(); + // calculate bodFat start here + // print('body fat local data ${bodyFatPercentage}'); + if (gender == 'male') { + if (bodyFatPercentage <= 10) { + bodyfatRangeTxt = + ((aControllerFind.localbodyFat.value == '- -') ? '- -' : 'Low'); + bodyFatRangeClr = 0xFFF44336; + // print('New BFlow'); + } else if (bodyFatPercentage > 10 && bodyFatPercentage <= 21) { + bodyfatRangeTxt = 'Standard'; + bodyFatRangeClr = 0xffFFFE00; + // print('New BFStandard'); + } else if (bodyFatPercentage > 21 && bodyFatPercentage <= 26) { + bodyfatRangeTxt = 'High'; + bodyFatRangeClr = 0xFF8ED34A; + // print('New BFHigh'); + } else if (bodyFatPercentage > 26 && bodyFatPercentage <= 100) { + bodyfatRangeTxt = 'Too High'; + bodyFatRangeClr = 0xFFF44336; + // print('New BFToo High'); + } + } else if (gender == 'female') { + if (bodyFatPercentage <= 10) { + bodyfatRangeTxt = + ((aControllerFind.localbodyFat.value == '- -') ? '- -' : 'Low'); + bodyFatRangeClr = 0xFFF44336; + // print('New BFlow'); + } else if (bodyFatPercentage > 10 && bodyFatPercentage <= 21) { + bodyfatRangeTxt = 'Standard'; + bodyFatRangeClr = 0xffFFFE00; + // print('New BFStandard'); + } else if (bodyFatPercentage > 21 && bodyFatPercentage <= 26) { + bodyfatRangeTxt = 'High'; + bodyFatRangeClr = 0xFF8ED34A; + // print('New BFHigh'); + } else if (bodyFatPercentage > 26 && bodyFatPercentage <= 100) { + bodyfatRangeTxt = 'Too High'; + bodyFatRangeClr = 0xFFF44336; + // print('New BFToo High'); + } + } + + // muscle rate range calculation + if (gender == 'male') { + if (mrPercentage <= 60) { + mRangeTxt = + (aControllerFind.localMusclerate.value == '- -') ? '- -' : 'Low'; + mrRangeClr = 0xFFF44336; + } else if (mrPercentage > 60 && mrPercentage <= 74) { + mRangeTxt = 'Standard'; + mrRangeClr = 0xffFFFE00; + } else if (mrPercentage > 74 && mrPercentage <= 100) { + mRangeTxt = 'Excellent'; + mrRangeClr = 0xFF8ED34A; + } + } else if (gender == 'female') { + if (mrPercentage >= 0 && mrPercentage <= 56) { + mRangeTxt = + (aControllerFind.localMusclerate.value == '- -') ? '- -' : 'Low'; + mrRangeClr = 0xFFF44336; + } else if (mrPercentage > 56 && mrPercentage <= 70) { + mRangeTxt = 'Standard'; + mrRangeClr = 0xffFFFE00; + } else if (mrPercentage > 70 && mrPercentage <= 100) { + mRangeTxt = 'Excellent'; + mrRangeClr = 0xFF8ED34A; + } + } + + // water rate range calculation + if (gender == 'male') { + if (wPercentage <= 55.00) { + waterRangeTxt = + (aControllerFind.localWater.value == '- -') ? '- -' : 'Low'; + waterRangeClr = 0xFFF44336; + } else if (wPercentage > 55.00 && wPercentage <= 65.00) { + waterRangeTxt = 'Standard'; + waterRangeClr = 0xffFFFE00; + } else if (wPercentage > 65.00 && wPercentage <= 100) { + waterRangeTxt = 'Excellent'; + waterRangeClr = 0xFF8ED34A; + } + } else if (gender == 'female') { + if (wPercentage <= 46.00) { + waterRangeTxt = + (aControllerFind.localWater.value == '- -') ? '- -' : 'Low'; + waterRangeClr = 0xFFF44336; + } else if (wPercentage > 46.00 && wPercentage <= 60.00) { + waterRangeTxt = 'Standard'; + waterRangeClr = 0xffFFFE00; + } else if (wPercentage > 60.00 && wPercentage <= 100) { + waterRangeTxt = 'Excellent'; + waterRangeClr = 0xFF8ED34A; + } + } + + Timer.periodic( + Duration(milliseconds: 360), + (timer) { + textOpacity = 1.0; + timer.cancel(); + }, + ); + + return FutureBuilder( + future: RankingLeaderboard().getLeaderBoardRankPositions(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + SelfRankPositions data = snapshot.data!.data; + appDataController.selfPosition.value = data.dailyPosition; + return isScaleStablized + ? Obx(() => Container( + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? Colors.white + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.2), + offset: const Offset( + 2.0, + 2.0, + ), + blurRadius: 10.0, + spreadRadius: 2.0, + ), + ], + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Row( + children: [ + Expanded( + flex: 2, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Column( + children: [ + Obx( + () => Text( + 'You are at', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + ), + ), + ), + SizedBox(height: 10), + GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(3), + child: Text( + '${appDataController.selfPosition.value}', + style: TextStyle( + fontSize: 60, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + height: 1, + ), + ), + ), + Text( + 'Global', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Color(0xffD9D9D9), + height: 1, + ), + ) + ], + ), + ), + ), + Expanded( + flex: 4, + child: Column( + children: [ + LayoutBuilder( + builder: + (context, BoxConstraints constraints) { + double maxWidth = constraints.maxWidth; + print(bmrPercentage * 100); + return GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(2), + child: Stack( + alignment: Alignment.centerRight, + children: [ + Container( + width: maxWidth, + height: 25, + decoration: const BoxDecoration( + color: Color(0xffE3E4EA), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: Radius.circular(12), + ), + ), + ), + + //progress 1 + TweenAnimationBuilder( + tween: Tween( + begin: 0, + end: (((bodyFatPercentage * + 100) / + maxWidth) / + 100) * + maxWidth), + duration: Duration(seconds: 1), + builder: (context, value, child) => + Container( + width: double.parse( + value.toString(), + ), + height: 25, + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: Color(bodyFatRangeClr!), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: + Radius.circular(12), + ), + ), + ), + ), + Positioned( + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + 'Body Fat', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: + FontWeight.w600, + ), + ), + Text( + '$bodyfatRangeTxt ${bodyFatPercentage.round()} %', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: + FontWeight.w600, + ), + ), + ], + ), + ), + ), + ], + ), + ); + }, + ), + const SizedBox(height: 20), + LayoutBuilder(builder: + (context, BoxConstraints constraints) { + double maxWidth = constraints.maxWidth; + return GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(2), + child: Stack( + alignment: Alignment.centerRight, + children: [ + Container( + width: maxWidth, + height: 25, + decoration: const BoxDecoration( + color: Color(0xffE3E4EA), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: Radius.circular(12), + ), + ), + ), + + //progress 2 + TweenAnimationBuilder( + tween: Tween( + begin: 0, + end: (mrPercentage / 100) * + maxWidth), + duration: Duration(seconds: 1), + builder: (context, value, child) => + Container( + width: + double.parse(value.toString()), + height: 25, + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: Color(mrRangeClr!), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: Radius.circular(12), + ), + ), + ), + ), + + Positioned( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + 'Muscle Rate', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: FontWeight.w600, + ), + ), + Text( + '$mRangeTxt ${mrPercentage.round()} %', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ], + ), + ); + }), + const SizedBox(height: 20), + LayoutBuilder(builder: + (context, BoxConstraints constraints) { + double maxWidth = constraints.maxWidth; + return GestureDetector( + onTap: () => homePageController + .updateBottomNavIndex(2), + child: Stack( + alignment: Alignment.centerRight, + children: [ + Container( + width: maxWidth, + height: 25, + decoration: const BoxDecoration( + color: Color(0xffE3E4EA), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: Radius.circular(12), + ), + ), + ), + + //progress 3 + TweenAnimationBuilder( + tween: Tween( + begin: 0, + end: (wPercentage / 100) * + maxWidth), + duration: Duration(seconds: 1), + builder: (context, value, child) => + Container( + width: + double.parse(value.toString()), + height: 25, + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: Color(waterRangeClr!), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomLeft: Radius.circular(12), + ), + ), + // child: AnimatedOpacity( + // duration: Duration(seconds: 1), + // opacity: textOpacity, + // child: Padding( + // padding: const EdgeInsets.only(right: 8.0), + // child: Text( + // wPercentage.toStringAsFixed(2), + // style: const TextStyle( + // fontSize: 12, + // color: Color(0xff000000), + // fontWeight: FontWeight.w600, + // ), + // ), + // ), + // ), + ), + ), + Positioned( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + 'Water', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: FontWeight.w600, + ), + ), + Text( + '$waterRangeTxt ${wPercentage.round()} %', + style: TextStyle( + fontSize: 12, + color: Color(0xff000000), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ], + ), + ); + }), + // const SizedBox(height: 20), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Row( + // children: [ + // Container( + // width: 16, + // height: 16, + // decoration: BoxDecoration( + // color: Color(0xff000000), + // borderRadius: BorderRadius.circular(100), + // ), + // ), + // const SizedBox(width: 5), + // Text( + // 'BMR', + // style: TextStyle( + // fontSize: 11, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : Color(0xffD9D9D9), + // ), + // ) + // ], + // ), + // Row( + // children: [ + // Container( + // width: 16, + // height: 16, + // decoration: BoxDecoration( + // color: Color(mrRangeClr!), + // borderRadius: BorderRadius.circular(100), + // ), + // ), + // const SizedBox(width: 5), + // Text( + // 'Muscle Rate', + // style: TextStyle( + // fontSize: 11, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : Color(0xffD9D9D9), + // ), + // ) + // ], + // ), + // Row( + // children: [ + // Container( + // width: 16, + // height: 16, + // decoration: BoxDecoration( + // color: Color(waterRangeClr!), + // borderRadius: BorderRadius.circular(100), + // ), + // ), + // const SizedBox(width: 5), + // Text( + // 'Water', + // style: TextStyle( + // fontSize: 11, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : Color(0xffD9D9D9), + // ), + // ) + // ], + // ), + // const SizedBox(), + // ], + // ), + ], + ), + ), + ], + ), + ), + )) + : Obx( + () => Container( + height: 150, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? Colors.white + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.2), + offset: const Offset(2.0, 2.0), + blurRadius: 10.0, + spreadRadius: 2.0, + ), + ], + borderRadius: BorderRadius.circular(20), + ), + child: Center( + child: GestureDetector( + onTap: () { + homePageController.updateBottomNavIndex(2); + }, + child: Text( + // 'No Data Found\nPlease use scale and get the health report.', + 'Connect your Scale from the Bioscale tab.\n Or tap Here to connect your scale.', + textAlign: TextAlign.center, + ), + ), + ), + ), + ); + } + return SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: context.width, + height: 170, + borderRadius: BorderRadius.circular(10), + ), + ); + }, + ); + } + + @override + void dispose() { + super.dispose(); + _animationController?.dispose(); + } +} + +class HomePageShortVideosShimmer extends StatelessWidget { + HomePageShortVideosShimmer({Key? key}) : super(key: key); + final list = [ + SizedBox(width: 22), + // Shimmer.fromColors( + // child: const ShortClipElementSkeleton(), + // baseColor: const Color.fromARGB(255, 26, 26, 26), + // highlightColor: const Color.fromARGB(255, 40, 40, 40), + // ), + // Shimmer.fromColors( + // child: const ShortClipElementSkeleton(), + // baseColor: const Color.fromARGB(255, 26, 26, 26), + // highlightColor: const Color.fromARGB(255, 40, 40, 40), + // ), + // Shimmer.fromColors( + // child: const ShortClipElementSkeleton(), + // baseColor: const Color.fromARGB(255, 26, 26, 26), + // highlightColor: const Color.fromARGB(255, 40, 40, 40), + // ), + SizedBox(width: 22), + ]; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 210, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: list.length, + itemBuilder: (context, index) { + return list[index]; + }, + ), + ); + } +} + +class HomePageShortClipsList extends StatelessWidget { + const HomePageShortClipsList({ + required this.clips, + required this.shortClipLikesModel, + Key? key, + }) : super(key: key); + + final List clips; + final List shortClipLikesModel; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 210, + // padding: EdgeInsets.symmetric(horizontal: 20), + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: clips.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + return SizedBox(width: 20); + } else { + return Padding( + padding: + EdgeInsets.only(right: index == clips.length ? 20 - 2.6 : 0), + child: ShortClipElement( + imgUrl: clips[index - 1].thumbnailUrl, + title: clips[index - 1].title, + onClick: () { + Get.to(() => SvpMain(fromHome: false, index: index - 1)); + }, + ), + ); + } + }, + ), + ); + } +} diff --git a/gsf/lib/views/pages/home/home_page.dart b/gsf/lib/views/pages/home/home_page.dart new file mode 100644 index 0000000..ad3e1fb --- /dev/null +++ b/gsf/lib/views/pages/home/home_page.dart @@ -0,0 +1,236 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_branch_sdk/flutter_branch_sdk.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/manage_banner_model.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/cj/manage_banner_service.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/views/pages/bioMaker/add_scale.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; +import 'package:gsp_app/views/pages/splash.dart'; +import 'package:gsp_app/views/short_video_player/svp_main.dart'; +import 'package:gsp_app/views/theme.dart'; +import '../../../view_model/home_page_controller.dart'; +import '../bioMaker/overview.dart'; +import '../my_ranking/mvp_elites_leaderboard.dart'; +import '../profile/pages/profile_page.dart'; +import '../sessions/session.dart'; +import 'home.dart'; + +class HomePage extends StatefulWidget { + const HomePage({Key? key}) : super(key: key); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + final box = GetStorage(); + HomePageController homePageController = Get.put(HomePageController()); + bool get isLoggedIn => box.read("isLoggedIn"); + bool get isScaleAdd => box.read("addScale") ?? false; + StreamSubscription? streamSubscription; + StreamController controllerData = StreamController(); + AppDataController appDataController = Get.find(); + + @override + void initState() { + listenDynamicLinks(); + callingBannerApiForHomeScreen(); + super.initState(); + } + + // bool apicalled = false; + // @override + // void initState() { + // // TODO: implement initState + // super.initState(); + // // moodOMeter(); + // // var moodResult = await MoodOMeterService().getMoodOMeter(); + // // // if() + // // if(moodResult.responseStatus != ResponseStatus.success ){ + // // return const HomePageSkeleton(); + // // } + // } + + // moodOMeter() async { + // var moodResult = await MoodOMeterService().getMoodOMeter(); + // // if() + // if(moodResult.responseStatus != ResponseStatus.success ){ + // // return const HomePageSkeleton(); + // setState(() { + // apicalled = true; + // }); + // } + // } + +//DeepLinkingSetup -by Kishan + + void listenDynamicLinks() async { + streamSubscription = FlutterBranchSdk.initSession().listen((data) { + print('listenDynamicLinks - DeepLink Data: $data'); + controllerData.sink.add((data.toString())); + if (data.containsKey('+clicked_branch_link') && + data['+clicked_branch_link'] == true) { + debugPrint( + '------------------------------------Link clicked----------------------------------------------'); + // debugPrint('Custom string: ${data['custom_string']}'); + debugPrint('Custom number: ${data['custom_number']}'); + debugPrint("var type is ${data['custom_number'].runtimeType}"); + debugPrint( + '------------------------------------------------------------------------------------------------'); + // showSnackBar( + // message: 'Link clicked: Custom string - ${data['custom_string']}', + // duration: 10); + Get.to(() => + SvpMain(fromHome: false, index: int.parse(data['custom_number']))); + } + }, onError: (error) { + print('InitSesseion error: ${error.toString()}'); + }); + } + + void callingBannerApiForHomeScreen() { + print("calling custom Banner api"); + ManageBannerService().fetchManageBanner().then((resModel) { + switch (resModel.responseStatus) { + case ResponseStatus.success: + //MANAGE BANNER SUCCESS + ManageBannerModel model = resModel.data; + appDataController.bannerPath.value = model.bannerPath; + appDataController.bannerPosition.value = model.bannerPosition; + break; + case ResponseStatus.failed: + // TODO: Handle this case. + break; + case ResponseStatus.expired: + // TODO: Handle this case. + break; + case ResponseStatus.error: + // TODO: Handle this case. + break; + } + }); + } + +//generate random number for bites section + int? randomNumber; + genRandomNo() { + randomNumber = Random().nextInt(20) + 1; + } + + @override + Widget build(BuildContext context) { + debugPrint("ksjdfsdfkndsf HomePage"); + + genRandomNo(); + Future showExitPopup() async { + return await showDialog( + //show confirm dialogue + //the return value will be from "Yes" or "No" options + context: context, + builder: (context) => AlertDialog( + elevation: 10, + backgroundColor: Colors.black, + title: const Text( + 'Exit App', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + content: const Text( + 'Do you want to exit an App?', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + actionsAlignment: MainAxisAlignment.spaceAround, + actions: [ + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: ColorConstants.kPrimaryColor, + ), + onPressed: () => Navigator.of(context).pop(false), + //return false when click on "NO" + child: const Text( + 'No', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kBlack, + ), + ), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: ColorConstants.kPrimaryColor, + ), + onPressed: () { + Navigator.of(context).pop(true); + }, + //return true when click on "Yes" + child: const Text( + 'Yes', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kBlack, + ), + ), + ), + ], + ), + ) ?? + false; //if showDialouge had returned null, then return false + } + + return WillPopScope( + onWillPop: () { + if (homePageController.bottomNavIndex.value == 0) { + return showExitPopup(); + } else { + homePageController.updateBottomNavIndex(0); + return Future.value(false); + } + }, + child: Scaffold( + backgroundColor: Colors.black, + body: Obx( + () { + switch (homePageController.bottomNavIndex.value) { + case 0: + return const Home(); + case 1: + return Sessions( + activeTabIndex: HomePageController.SessionsActiveTabIndex, + ); + + case 2: + return isLoggedIn + // ? const Overview() + ? isScaleAdd + ? const Overview() + : const AddScale() + : const SignIn(fromHomePage: true); + case 3: + return const MVPelitesBoard(); + case 4: + return isLoggedIn + ? SvpMain( + index: + Random().nextInt(ShortClipTemp.tempClips.length), + fromHome: true, + ) + : const SignIn(fromHomePage: true); + default: + return const SplashScreen(); + } + }, + )), + ); + } +} diff --git a/gsf/lib/views/pages/insta/insta_clip_list.dart b/gsf/lib/views/pages/insta/insta_clip_list.dart new file mode 100644 index 0000000..2847a52 --- /dev/null +++ b/gsf/lib/views/pages/insta/insta_clip_list.dart @@ -0,0 +1,262 @@ +// import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/components/videos_not_found.dart'; +import 'package:gsp_app/modals/short_clip_likes_model.dart'; +// import 'package:gsp_app/pages/home/home.dart'; +import 'package:gsp_app/repository/services/short_clip_service.dart'; +import 'package:gsp_app/views/pages/splash.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:shimmer/shimmer.dart'; +import 'package:transparent_image/transparent_image.dart'; + +import '../../../modals/short_clip_model.dart'; +import '../../short_video_player/svp_main.dart'; +import 'package:async/async.dart'; + +class InstaClips extends StatefulWidget { + const InstaClips({ + Key? key, + }) : super(key: key); + + @override + State createState() => IinstaClipStates(); +} + +class IinstaClipStates extends State { + var clipsNLikesFutureGroup = FutureGroup(); + + @override + void initState() { + var shortClipService = ShortClipService(); + clipsNLikesFutureGroup.add(shortClipService.fetchShortClips()); + clipsNLikesFutureGroup.add(shortClipService.fetchShortClipLikes()); + clipsNLikesFutureGroup.close(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars( + titleHead: 'Bites', + ), + ), + body: FutureBuilder( + future: clipsNLikesFutureGroup.future, + builder: (context, snapshot) { + debugPrint('SNAPSHOT $snapshot'); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + if (snapshot.data!.isNotEmpty) { + ShortClipTemp.tempClips = snapshot.data![0]; + ShortClipTemp.tempclipLikes = snapshot.data![1]; + return ShortClipsGrid( + clips: snapshot.data![0], + clipsLikesModel: snapshot.data![1], + ); + } + return const Center(child: VideosNotFound()); + } + return const ShimmerClips(); + }, + ), + ); + } +} + +class ShortClipsGrid extends StatelessWidget { + const ShortClipsGrid({ + required this.clips, + required this.clipsLikesModel, + Key? key, + }) : super(key: key); + + final List clips; + final List clipsLikesModel; + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + body: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisExtent: 226, + ), + itemCount: clips.length, + itemBuilder: (context, index) { + var clip = clips.elementAt(index); + return Padding( + padding: EdgeInsets.only( + top: 8.0, + left: index % 3 == 0 ? 8 : 0, + right: 8, + bottom: (index == clips.length - 1 || + index == clips.length - 2 || + index == clips.length - 3) + ? 8 + : 0, + ), + child: ShortClipElement( + imgUrl: clip.thumbnailUrl, + title: clip.title, + onClick: () { + Get.to(() => SvpMain( + index: index, + fromHome: false, + )); + }, + ), + ); + }, + ), + ); + } +} + +class ShimmerClips extends StatelessWidget { + const ShimmerClips({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + body: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisExtent: 226, + ), + itemCount: 7, + itemBuilder: (context, index) { + return Shimmer.fromColors( + child: Padding( + padding: EdgeInsets.only( + top: 8.0, + left: index % 3 == 0 ? 8 : 0, + right: 8, + bottom: 0, + ), + child: const ShortClipElementSkeleton(), + ), + // baseColor: const Color.fromARGB(255, 26, 26, 26), + baseColor: (brightness == Brightness.light) + ? const Color.fromARGB(255, 216, 214, 214) + : const Color.fromARGB(255, 26, 26, 26), + highlightColor: (brightness == Brightness.light) + ? const Color.fromARGB(255, 202, 201, 201) + : const Color.fromARGB(255, 40, 40, 40), + // highlightColor: const Color.fromARGB(255, 40, 40, 40), + ); + }, + ), + ); + } +} + +class ShortClipElement extends StatelessWidget { + const ShortClipElement({ + Key? key, + required this.imgUrl, + required this.title, + required this.onClick, + }) : super(key: key); + + final String imgUrl; + final String title; + final VoidCallback onClick; + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + return InkWell( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + bottomLeft: Radius.circular(6), + bottomRight: Radius.circular(6), + ), + onTap: onClick, + child: Padding( + padding: const EdgeInsets.all(2.6), + child: Obx( + () => SizedBox( + width: 120, + child: Column( + children: [ + SizedBox( + height: 163, + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + // child: Image.network(imgUrl), + child: FadeInImage.memoryNetwork( + placeholder: kTransparentImage, + image: imgUrl, + ), + ), + ), + const SizedBox(height: 6), + Text( + title, + overflow: TextOverflow.ellipsis, + maxLines: 2, + textAlign: TextAlign.start, + style: TextStyle( + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ], + ), + ), + ), + ), + ); + } +} + +class ShortClipElementSkeleton extends StatelessWidget { + const ShortClipElementSkeleton({Key? key}) : super(key: key); + + Container skeletonChild( + double radius, + double height, + Color color, + ) => + Container( + height: height, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(radius), + ), + ); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(2.6), + child: SizedBox( + width: 120, + child: Column( + children: [ + skeletonChild(20, 163, Colors.black), + SizedBox(height: 11), + skeletonChild(3, 10, Colors.black), + SizedBox(height: 7), + skeletonChild(3, 10, Colors.black), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/insta/insta_web_view.dart b/gsf/lib/views/pages/insta/insta_web_view.dart new file mode 100644 index 0000000..2e859f4 --- /dev/null +++ b/gsf/lib/views/pages/insta/insta_web_view.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class InstWebView extends StatelessWidget { + const InstWebView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + var webViewController = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(const Color(0x00000000)) + ..loadRequest( + Uri.parse('https://www.instagram.com/getsetfit/'), + ); + return Scaffold( + body: SafeArea(child: WebViewWidget(controller: webViewController)), + ); + } +} diff --git a/gsf/lib/views/pages/insta/intsa_overview.dart b/gsf/lib/views/pages/insta/intsa_overview.dart new file mode 100644 index 0000000..2b50db9 --- /dev/null +++ b/gsf/lib/views/pages/insta/intsa_overview.dart @@ -0,0 +1,99 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/theme.dart'; + +import '../vimeo_video_plyaer.dart'; + +class InstaOverview extends StatefulWidget { + const InstaOverview({Key? key}) : super(key: key); + + @override + State createState() => _InstaOverviewState(); +} + +class _InstaOverviewState extends State { + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars(titleHead: 'Courses Overview'), + ), + body: Column( + children: [ + Stack( + children: [ + Image.asset( + 'assets/image/courses/fitness.jpg', + width: Get.size.width, + fit: BoxFit.fitWidth, + ), + Positioned( + top: 0, + left: 0, + right: 0, + bottom: 0, + child: Align( + child: Container( + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor.withOpacity(0.5), + shape: BoxShape.circle, + ), + child: GestureDetector( + // onTap: () => Get.to( + // () => const VimeoPlayer(), + // ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow, + color: ColorConstants.kBlack, + size: 35, + ), + ), + ), + ), + ), + ) + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 10), + Text( + 'HIIT - Full Body', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 10), + Text( + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever.', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.7) + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/internet/internet.dart b/gsf/lib/views/pages/internet/internet.dart new file mode 100644 index 0000000..e2cc8cb --- /dev/null +++ b/gsf/lib/views/pages/internet/internet.dart @@ -0,0 +1,91 @@ +import 'dart:async'; + +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; + +import 'second_page.dart'; + +class InternetCheck extends StatefulWidget { + const InternetCheck({Key? key}) : super(key: key); + + @override + State createState() => _InternetCheckState(); +} + +class _InternetCheckState extends State { + late StreamSubscription subscription; + var isDeviceConnectd = false; + bool isAlert = false; + + @override + void initState() { + getContivity(); + super.initState(); + } + + getContivity() => subscription = Connectivity().onConnectivityChanged.listen( + (ConnectivityResult result) async { + isDeviceConnectd = await InternetConnectionChecker().hasConnection; + if (!isDeviceConnectd && isAlert == false) { + showDialogBox(); + setState(() => isAlert = true); + } + }, + ); + + @override + void dispose() { + subscription.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Internet Connection Check'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const SecondPage(), + )), + child: const Text('Next'), + ), + ], + ), + ), + ); + } + + showDialogBox() => showCupertinoDialog( + context: context, + builder: (BuildContext context) => CupertinoAlertDialog( + title: const Text('data'), + content: const Text('Please check you\'re internet connection'), + actions: [ + TextButton( + onPressed: () async { + Navigator.pop(context, 'Cancel'); + setState(() => isAlert = true); + isDeviceConnectd = + await InternetConnectionChecker().hasConnection; + if (!isDeviceConnectd) { + showDialogBox(); + setState(() => isAlert = true); + } + }, + child: const Text('OK'), + ) + ], + ), + ); +} diff --git a/gsf/lib/views/pages/internet/second_page.dart b/gsf/lib/views/pages/internet/second_page.dart new file mode 100644 index 0000000..4115a05 --- /dev/null +++ b/gsf/lib/views/pages/internet/second_page.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +class SecondPage extends StatefulWidget { + const SecondPage({Key? key}) : super(key: key); + + @override + State createState() => _SecondPageState(); +} + +class _SecondPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Second Page')), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => Navigator.pop(context), + child: const Text('Back')) + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/intro/get_started.dart b/gsf/lib/views/pages/intro/get_started.dart new file mode 100644 index 0000000..716e210 --- /dev/null +++ b/gsf/lib/views/pages/intro/get_started.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:gsp_app/views/components/tween_max.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../../repository/response_data.dart'; +import '../../../repository/services/cj/moodOmeter_services.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import '../biomateric.dart/face_id.dart'; +import '../signIn/sign_in.dart'; + +class Getstarted extends StatefulWidget { + const Getstarted({Key? key}) : super(key: key); + + @override + State createState() => _GetstartedState(); +} + +class _GetstartedState extends State { + final box = GetStorage(); + // bool apicalled = false; + + @override + void initState() { + if (box.read('fingerPrint') == true) { + LocalAuth.authenticate(); + } + super.initState(); + } + + var btnController = RoundedLoadingButtonController(); + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + body: Container( + height: screenSize.height * 1, + width: screenSize.width * 1, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/get_started.jpg'), + fit: BoxFit.cover, + ), + ), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: Column( + children: [ + const Spacer(), + tweenMaxAnimationbottom( + PrimaryButton( + controller: btnController, + onTap: () { + btnController.reset(); + Get.to(() => const SignIn()); + }, + text: 'Login for Progress', + ), + 10, + ), + const SizedBox( + height: 20, + ), + // tweenMaxAnimationbottom( + // InkWell( + // onTap: () => Get.to(() => const SignIn()), + // child: const Text( + // 'Log In', + // style: TextStyle( + // fontSize: 20, + // color: Color(0xffffffff), + // ), + // ), + // ), + // FullWdtBtn( + // btnText: 'Get Started', + // onTap: () { + // Get.to(() => const IntroSlider()); + // }), + // 10 + // ), + // ), + const SizedBox(height: 70), + ], + ), + ), + ) + // : Center(child: CircularProgressIndicator()), + ); + } +} diff --git a/gsf/lib/views/pages/intro/slider.dart b/gsf/lib/views/pages/intro/slider.dart new file mode 100644 index 0000000..b7223b0 --- /dev/null +++ b/gsf/lib/views/pages/intro/slider.dart @@ -0,0 +1,203 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/components/tween_max.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:gsp_app/views/pages/signUp/sign_up.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class IntroSlider extends StatefulWidget { + const IntroSlider({Key? key}) : super(key: key); + + @override + State createState() => _IntroSliderState(); +} + +class _IntroSliderState extends State { + final box = GetStorage(); + int _current = 0; + final CarouselController _controller = CarouselController(); + + List list = [ + { + 'img': 'assets/image/slider_img.png', + 'headTxt': 'Jump Right Into the\n Fitness Arena!', + 'shortdesc': + 'Get access to the best workout Sessions in Yoga, Calisthenics, Pilates, Kettlebells, Bodybuilding, and Circuit Training from certified trainers. Get full details of your body stats with detailed guidance on how to become the best version of yourself.', + }, + { + 'img': 'assets/image/slider_img.png', + 'headTxt': 'Jump Right Into the\n Fitness Arena!', + 'shortdesc': + 'Get access to the best workout Sessions in Yoga, Calisthenics, Pilates, Kettlebells, Bodybuilding, and Circuit Training from certified trainers. Get full details of your body stats with detailed guidance on how to become the best version of yourself.', + }, + { + 'img': 'assets/image/slider_img.png', + 'headTxt': 'Jump Right Into the\n Fitness Arena!', + 'shortdesc': + 'Get access to the best workout Sessions in Yoga, Calisthenics, Pilates, Kettlebells, Bodybuilding, and Circuit Training from certified trainers. Get full details of your body stats with detailed guidance on how to become the best version of yourself.', + }, + { + 'img': 'assets/image/slider_img.png', + 'headTxt': 'Jump Right Into the\n Fitness Arena!', + 'shortdesc': + 'Get access to the best workout Sessions in Yoga, Calisthenics, Pilates, Kettlebells, Bodybuilding, and Circuit Training from certified trainers. Get full details of your body stats with detailed guidance on how to become the best version of yourself.', + } + ]; + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + body: Stack( + children: [ + Positioned( + top: 0, + left: 0, + right: 0, + bottom: 0, + child: Column( + children: [ + Container( + height: screenSize.height * 0.3, + width: screenSize.width * 1, + color: ColorConstants.kPrimaryColor, + ), + Container( + height: screenSize.height * 0.7, + width: screenSize.width * 1, + color: const Color(0xff000000), + ), + ], + ), + ), + SizedBox( + height: screenSize.height * 1, + width: screenSize.width * 1, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: screenSize.width * 0.05, + ), + child: SingleChildScrollView( + child: Column( + children: [ + CarouselSlider( + carouselController: _controller, + options: CarouselOptions( + height: 650, + viewportFraction: 1.0, + // autoPlay: true, + enableInfiniteScroll: false, + // autoPlayCurve: Curves.linear, + autoPlayInterval: const Duration(seconds: 3), + onPageChanged: (index, reason) { + setState(() { + _current = index; + }); + }), + items: list + .map( + (item) => SizedBox( + width: screenSize.width * 1, + // height: screenSize.height * 1, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 50), + Image.asset( + 'assets/image/slider_img.png', + fit: BoxFit.cover, + width: screenSize.width * 1, + ), + // const SizedBox(height: 30), + tweenMaxAnimationtop( + Text( + item['headTxt'], + style: const TextStyle( + fontSize: 24, + fontFamily: 'Poppins', + color: Color(0xffEEEEEE), + ), + ), + 30), + // const SizedBox(height: 18), + tweenMaxAnimationtop( + Text( + item['shortdesc'], + // textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 14, + color: Color(0xffB7B7B7), + ), + ), + 20), + ], + ), + ), + ), + ) + .toList(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: list.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => _controller.animateToPage(entry.key), + child: Column( + children: [ + Container( + width: 15, + height: 5, + margin: const EdgeInsets.symmetric( + vertical: 6.0, horizontal: 2.0), + decoration: BoxDecoration( + // shape: BoxShape.circle, + color: (_current == entry.key + ? ColorConstants.kPrimaryColor + : const Color(0xff858585)), + ), + ), + ], + ), + ); + }).toList(), + ), + const SizedBox(height: 40), + // tweenMaxAnimationtop( + // FullWdtBtn( + // btnText: 'Gear Up and Join the Arena', + // onTap: () => Get.to( + // () => const SignUp(), + // ), + // ), + // 40), + // const SizedBox(height: 15), + tweenMaxAnimationtop( + GestureDetector( + onTap: () { + Get.offAll(() => const HomePage()); + }, + child: Text( + _current == 3 ? 'Next' : 'Skip Right to Arena', + style: const TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + 20, + ), + const SizedBox(height: 10), + ], + ), + ), + ), + ) + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/meditive/meditive.dart b/gsf/lib/views/pages/meditive/meditive.dart new file mode 100644 index 0000000..d4a278d --- /dev/null +++ b/gsf/lib/views/pages/meditive/meditive.dart @@ -0,0 +1,108 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/btn.dart'; +import '../../components/home_appbar.dart'; +import '../../theme.dart'; + +class Meditive extends StatelessWidget { + const Meditive({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: homeAppBar(), + body: Container( + width: Get.size.width, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'assets/image/meditive.jpg', + ), + fit: BoxFit.cover), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Spacer(flex: 4), + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + shape: BoxShape.circle, + ), + child: Icon( + Icons.play_arrow, + size: 40, + color: ColorConstants.kBlack, + ), + ), + SizedBox(height: 50), + Text( + 'Start Your MEDITIVE Fitness Journey', + style: TextStyle( + fontSize: 20, + color: Color(0xffe9e9e9), + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 25), + Text( + 'Improve your diet and exercise based on glucose Biomarkers', + style: TextStyle( + fontSize: 24, + color: Color(0xffe9e9e9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.center, + ), + SizedBox(height: 30), + Container( + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: Color(0xffc9c9c9), + ), + borderRadius: BorderRadius.circular(25)), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 30, + vertical: 10, + ), + child: Text( + 'Have a Meditive Scale? Start Now', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ), + ), + SizedBox(height: 10), + Text( + 'Don\'t have the Meditive Scale yet?', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w300, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 15), + FullWdtBtn(btnText: 'Get it Now', onTap: () {}), + Spacer(flex: 1), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/my_ranking/company_my_ranking.dart b/gsf/lib/views/pages/my_ranking/company_my_ranking.dart new file mode 100644 index 0000000..4bc6a46 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/company_my_ranking.dart @@ -0,0 +1,33 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; + +import '../../theme.dart'; + +class CompanyMyRanking extends StatefulWidget { + const CompanyMyRanking({Key? key}) : super(key: key); + + @override + State createState() => _CompanyMyRankingState(); +} + +class _CompanyMyRankingState extends State { + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Company", + style: QuizTextStyles.label, + ), + Text( + "In Progress", + style: QuizTextStyles.heading, + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/my_ranking/elites_leaderboard.dart b/gsf/lib/views/pages/my_ranking/elites_leaderboard.dart new file mode 100644 index 0000000..80748e3 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/elites_leaderboard.dart @@ -0,0 +1,181 @@ +import 'dart:ui'; + +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/bottom_navigation.dart'; +import '../../../view_model/bottom_navigation_controller.dart'; +import '../../theme.dart'; +import 'company_my_ranking.dart'; +import 'filter_elites_leaderboard.dart'; +import 'friends_my_ranking.dart'; +import 'global_my_ranking.dart'; + +class MyRanking extends StatefulWidget { + const MyRanking({Key? key}) : super(key: key); + + @override + State createState() => _MyRankingState(); +} + +class _MyRankingState extends State with TickerProviderStateMixin { + late AnimationController _animationController; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 600), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + ); + } + + @override + Widget build(BuildContext context) { + _animationController.forward(); + TabController tabController = TabController(length: 3, vsync: this); + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + showLeading: false, + titleHead: 'Elites Leaderboard', + // rightAction: IconButton( + // onPressed: () {}, + // icon: const Icon(Icons.help), + // ), + ), + ), + body: AnimatedBuilder( + child: Column( + children: [ + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + // Get.dialog( + // SizedBox( + // // height: 50, + // child: BackdropFilter( + // filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), + // child: FilterLeaderboard(defaultGender: ,defaultGroupLevel: ), + // ), + // ), + // ); + }, + child: Container( + height: 36, + padding: const EdgeInsets.symmetric(horizontal: 18), + decoration: const ShapeDecoration( + color: Color(0xff333333), + shape: StadiumBorder(), + ), + child: Row(mainAxisSize: MainAxisSize.min, children: [ + Text( + "Filter", + style: QuizTextStyles.heading, + ), + const SizedBox(width: 6), + const Icon( + Icons.filter_alt, + color: Colors.white, + size: 20, + ), + ]), + ), + ), + const SizedBox(width: 24), + ], + ), + const SizedBox(height: 14), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + decoration: BoxDecoration( + color: const Color(0xff2B2B2B), + borderRadius: BorderRadius.circular(28), + ), + child: TabBar( + isScrollable: false, + labelPadding: EdgeInsets.symmetric( + horizontal: Get.size.width * 0.0, + ), + labelColor: ColorConstants.kBlack, + unselectedLabelColor: Colors.white, + labelStyle: const TextStyle( + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontSize: 13, + ), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + ), + indicator: BoxDecoration( + color: ColorConstants.kWhite, + borderRadius: BorderRadius.circular(50), + ), + controller: tabController, + tabs: const [ + Tab( + text: 'Global', + ), + Tab( + text: 'Company', + ), + Tab( + text: 'Friends', + ), + ], + ), + ), + ], + ), + ), + Expanded( + child: TabBarView( + controller: tabController, + children: const [ + GlobalMyRanking(), + GlobalMyRanking(), + GlobalMyRanking(), + // CompanyMyRanking(), + // FriendsMyRanking(), + ], + ), + ), + ], + ), + animation: _animationController, + builder: (context, child) => FadeScaleTransition( + animation: _animationController, + child: child, + ), + ), + bottomNavigationBar: BottomNavigation( + // three: BottomNavigationController.three, + // four: BottomNavigationController.four, + // five: BottomNavigationController.five, + // six: BottomNavigationController.six, + // seven: BottomNavigationController.seven, + ), + ); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } +} diff --git a/gsf/lib/views/pages/my_ranking/filter_elites_leaderboard.dart b/gsf/lib/views/pages/my_ranking/filter_elites_leaderboard.dart new file mode 100644 index 0000000..fdd9291 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/filter_elites_leaderboard.dart @@ -0,0 +1,444 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +import '../../../view_model/my_ranking_controller.dart'; +import '../../theme.dart'; + +class FilterLeaderboard extends StatefulWidget { + final String defaultGender; + final String defaultGroupLevel; + + const FilterLeaderboard({ + Key? key, + required this.defaultGender, + required this.defaultGroupLevel, + }) : super(key: key); + + @override + State createState() => _FilterLeaderboardState(); +} + +class _FilterLeaderboardState extends State { + int activeRadioBtnIndex = 0; + int filterIndex = 0; + + // String defaultGenderStrore = widget.defaultGender; + // static String defaultGroupLevelStore = ''; + + MyRankingController myRankingController = Get.put(MyRankingController()); + + String selectedGender = 'Male'; + String selectedGroupLevel = 'Swole'; + + @override + void initState() { + selectedGender = myRankingController.gender.value; + selectedGroupLevel = myRankingController.groupLevel.value; + super.initState(); + } + + String radioBtn1Title = "Male"; + String radioBtn2Title = "Female"; + String radioBtn3Title = "All"; + + Widget radioBtn1Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_male.svg", + ); + Widget radioBtn2Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_female.svg", + ); + Widget radioBtn3Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_all.svg", + ); + + @override + Widget build(BuildContext context) { + print('gender from api ${widget.defaultGender}'); + print('gender from api ${widget.defaultGroupLevel}'); + print('gender from api ${myRankingController.defaultGroupLevelStore}'); + + final brightness = Get.theme.brightness; + switch (filterIndex) { + case 0: + radioBtn1Title = "Male"; + radioBtn2Title = "Female"; + radioBtn3Title = "All"; + + radioBtn1Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_male.svg", + ); + radioBtn2Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_female.svg", + ); + radioBtn3Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/gender/gender_all.svg", + ); + if (widget.defaultGender.toString() == "male") { + activeRadioBtnIndex = 0; + } else if (widget.defaultGender.toString() == "female") { + activeRadioBtnIndex = 1; + } else if (widget.defaultGender == 'all') { + activeRadioBtnIndex = 2; + } + break; + case 1: + radioBtn1Title = "Daily"; + radioBtn2Title = "Weekly"; + radioBtn3Title = "Monthly"; + + radioBtn1Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/date_range/daily.svg", + ); + radioBtn2Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/date_range/monthly.svg", + ); + radioBtn3Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/date_range/weekly.svg", + ); + break; + case 2: + radioBtn1Title = "Swole"; + radioBtn2Title = "Up Steppers"; + radioBtn3Title = "Rookie"; + + radioBtn1Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/group_level/elites.svg", + ); + radioBtn2Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/group_level/game_changers.svg", + ); + radioBtn3Leading = SvgPicture.asset( + "assets/image/filter_leaderboard/group_level/underdogs.svg", + ); + if (widget.defaultGroupLevel.toString() == "elites") { + activeRadioBtnIndex = 0; + } else if (widget.defaultGroupLevel.toString() == "gameChangers") { + activeRadioBtnIndex = 1; + } else if (widget.defaultGroupLevel.toString() == 'underdogs') { + activeRadioBtnIndex = 2; + } + break; + default: + } + return Scaffold( + backgroundColor: Colors.transparent, + body: Align( + alignment: Alignment.bottomCenter, + child: Container( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.4) + : const Color(0xff212121), + height: 356, + child: Column(children: [ + Expanded( + child: Row( + children: [ + Expanded( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 6.0), + child: Text( + "Filters", + style: QuizTextStyles.heading, + ), + ), + Expanded( + child: TextButton( + style: TextButton.styleFrom(padding: EdgeInsets.zero), + onPressed: () { + setState(() { + activeRadioBtnIndex = 0; + filterIndex = 0; + }); + }, + child: Container( + width: double.infinity, + color: filterIndex == 0 + ? const Color(0xffBBF046) + : null, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset( + "assets/image/filter_leaderboard/filters/gender_new.svg", + color: filterIndex == 0 + ? Colors.black + : Colors.white, + ), + const SizedBox(height: 4), + Text( + "GENDER", + style: TextStyle( + color: filterIndex == 0 + ? Colors.black + : Colors.white, + ), + ) + ], + ), + ), + ), + ), + ), + const Divider( + height: 2, + thickness: 2, + color: Color(0xff707070), + ), + Expanded( + child: TextButton( + style: TextButton.styleFrom(padding: EdgeInsets.zero), + onPressed: () { + setState(() { + activeRadioBtnIndex = 0; + filterIndex = 2; + }); + }, + child: Container( + color: filterIndex == 2 + ? const Color(0xffBBF046) + : null, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset( + "assets/image/filter_leaderboard/filters/group_level_new.svg", + color: filterIndex == 2 + ? Colors.black + : Colors.white, + ), + const SizedBox(height: 4), + Text( + "GROUP LEVEL", + style: TextStyle( + color: filterIndex == 2 + ? Colors.black + : Colors.white, + ), + ) + ], + ), + ), + ), + ), + ), + ], + ), + ), + Expanded( + flex: 2, + child: Column( + children: [ + Align( + alignment: Alignment.topRight, + child: Padding( + padding: const EdgeInsets.only( + top: 6.0, + bottom: 6.0, + right: 18, + ), + child: InkWell( + onTap: () { + myRankingController.gender.value = + myRankingController + .defaultGenderStore.value; + myRankingController.groupLevel.value = + myRankingController + .defaultGroupLevelStore.value; + Get.back(); + }, + child: Text( + "Clear All", + style: QuizTextStyles.heading, + ), + )), + ), + const Spacer(), + StatefulBuilder( + builder: (context, setBtnState) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + FilterRadioBtn( + isChecked: + activeRadioBtnIndex == 0 ? true : false, + title: radioBtn1Title, + leading: radioBtn1Leading, + onClick: () { + if (radioBtn1Title == "Male" || + radioBtn1Title == "Female" || + radioBtn1Title == "All") { + selectedGender = radioBtn1Title; + } else { + selectedGroupLevel = radioBtn1Title; + } + debugPrint(selectedGender); + debugPrint(selectedGroupLevel); + setBtnState(() { + activeRadioBtnIndex = 0; + }); + }, + ), + const SizedBox(height: 12), + FilterRadioBtn( + isChecked: + activeRadioBtnIndex == 1 ? true : false, + title: radioBtn2Title, + leading: radioBtn2Leading, + onClick: () { + if (radioBtn2Title == "Male" || + radioBtn2Title == "Female" || + radioBtn2Title == "All") { + selectedGender = radioBtn2Title; + } else { + selectedGroupLevel = radioBtn2Title; + } + debugPrint(selectedGender); + debugPrint(selectedGroupLevel); + setBtnState(() { + activeRadioBtnIndex = 1; + }); + }, + ), + const SizedBox(height: 12), + FilterRadioBtn( + isChecked: + activeRadioBtnIndex == 2 ? true : false, + title: radioBtn3Title, + leading: radioBtn3Leading, + onClick: () { + if (radioBtn3Title == "Male" || + radioBtn3Title == "Female" || + radioBtn3Title == "All") { + selectedGender = radioBtn3Title; + } else { + selectedGroupLevel = radioBtn3Title; + } + debugPrint(selectedGender); + debugPrint(selectedGroupLevel); + setBtnState(() { + activeRadioBtnIndex = 2; + }); + }, + ), + ], + ); + }, + ), + const Spacer(), + ], + ), + ), + ], + )), + Container( + height: 48, + color: const Color.fromARGB(255, 22, 22, 22), + child: Row(children: [ + Expanded( + child: TextButton( + onPressed: () => Get.back(), + child: const Center( + child: Text( + "Close", + style: TextStyle( + color: Color.fromARGB(255, 206, 206, 206), + fontSize: 14, + ), + ), + ))), + Expanded( + child: TextButton( + onPressed: () { + myRankingController.gender.value = selectedGender; + myRankingController.groupLevel.value = + selectedGroupLevel; + Get.back(); + print( + 'from apply btn click group level $selectedGroupLevel'); + print('from apply btn click gender $selectedGender'); + }, + child: const Center( + child: Text( + "Apply", + style: TextStyle( + color: Color.fromARGB(255, 255, 255, 255), + fontSize: 14, + ), + ), + ))), + ]), + ) + ]), + ), + ), + ); + } +} + +class FilterRadioBtn extends StatelessWidget { + const FilterRadioBtn({ + Key? key, + this.isChecked = false, + required this.leading, + required this.title, + required this.onClick, + }) : super(key: key); + + final bool isChecked; + final Widget leading; + final String title; + final void Function() onClick; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 18.0), + child: GestureDetector( + onTap: onClick, + child: Container( + padding: const EdgeInsets.all(12), + decoration: const ShapeDecoration( + shape: StadiumBorder(), + color: Color(0xff4B4B4B), + ), + child: Row(children: [ + leading, + // SvgPicture.asset("assets/image/filter_leaderboard/gender_male.svg"), + const SizedBox(width: 12), + Expanded( + child: Text( + title, + style: QuizTextStyles.heading, + ), + ), + Container( + width: 26, + height: 26, + padding: const EdgeInsets.all(6), + decoration: const BoxDecoration( + color: Colors.black, + shape: BoxShape.circle, + ), + child: isChecked + ? Container( + width: 26, + height: 26, + padding: const EdgeInsets.all(6), + decoration: const BoxDecoration( + color: Color(0xffBBF046), + shape: BoxShape.circle, + ), + ) + : null, + ), + ]), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/my_ranking/friends_my_ranking.dart b/gsf/lib/views/pages/my_ranking/friends_my_ranking.dart new file mode 100644 index 0000000..e49bba4 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/friends_my_ranking.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import '../../theme.dart'; + +class FriendsMyRanking extends StatefulWidget { + const FriendsMyRanking({Key? key}) : super(key: key); + + @override + State createState() => _FriendsMyRankingState(); +} + +class _FriendsMyRankingState extends State { + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Friends", + style: QuizTextStyles.label, + ), + Text( + "In Progress", + style: QuizTextStyles.heading, + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/my_ranking/global_my_ranking.dart b/gsf/lib/views/pages/my_ranking/global_my_ranking.dart new file mode 100644 index 0000000..a38aab3 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/global_my_ranking.dart @@ -0,0 +1,205 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/home/home.dart'; + +import '../../components/leaderboard_element.dart'; +import '../../theme.dart'; +import '../profile/pages/view_profile.dart'; + +class GlobalMyRanking extends StatefulWidget { + const GlobalMyRanking({Key? key}) : super(key: key); + + @override + State createState() => _GlobalMyRankingState(); +} + +class _GlobalMyRankingState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: GestureDetector( + // onTap: () => Get.to(() => ViewProfile(userDetailsModel: ,)), + child: Column( + children: [ + const SizedBox(height: 140), + SvgPicture.asset( + "assets/image/arrows/arrow_up.svg", + width: 24, + ), + Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + Image.asset( + "assets/image/1.png", + fit: BoxFit.fill, + width: 96, + height: 96, + ), + Container( + width: 20, + height: 20, + decoration: const BoxDecoration( + color: Color.fromARGB(255, 255, 255, 255), + shape: BoxShape.circle, + ), + child: const Center( + child: Text( + "2", + style: TextStyle( + fontSize: 12.5, + fontWeight: FontWeight.bold, + ), + )), + ) + ], + ), + const SizedBox(height: 6), + Text( + "Nadeem Shaikh", + style: QuizTextStyles.heading, + textAlign: TextAlign.center, + ), + Text( + "80122 Pt", + style: QuizTextStyles.label + .copyWith(fontWeight: FontWeight.normal), + ), + ], + ), + ), + ), + Expanded( + child: Column( + children: [ + SvgPicture.asset( + "assets/image/crown.svg", + width: 65, + ), + const SizedBox(height: 12), + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + Image.asset( + "assets/image/avatar.png", + fit: BoxFit.fill, + width: 115, + height: 115, + ), + Positioned( + bottom: -10, + child: Container( + width: 30, + height: 30, + decoration: const BoxDecoration( + color: Color(0xffBBF046), + shape: BoxShape.circle, + ), + child: const Center( + child: Text( + "1", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + )), + ), + ) + ], + ), + const SizedBox(height: 16), + Text( + "Kartikey Gautam", + style: QuizTextStyles.heading, + textAlign: TextAlign.center, + ), + Text( + "80122 Pt", + style: QuizTextStyles.label + .copyWith(fontWeight: FontWeight.normal), + ), + ], + )), + Expanded( + child: Column( + children: [ + const SizedBox(height: 140), + SvgPicture.asset( + "assets/image/arrows/arrow_down.svg", + width: 24, + ), + Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + Image.asset( + "assets/image/3.png", + fit: BoxFit.fill, + width: 96, + height: 96, + ), + Container( + width: 20, + height: 20, + decoration: const BoxDecoration( + color: Color.fromARGB(255, 255, 255, 255), + shape: BoxShape.circle, + ), + child: const Center( + child: Text( + "3", + style: TextStyle( + fontSize: 12.5, + fontWeight: FontWeight.bold, + ), + )), + ) + ], + ), + const SizedBox(height: 6), + Text( + "Atul Pandey", + style: QuizTextStyles.heading, + textAlign: TextAlign.center, + ), + Text( + "80122 Pt", + style: QuizTextStyles.label + .copyWith(fontWeight: FontWeight.normal), + ), + ], + )), + ], + ), + ), + const SizedBox(height: 42), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Column( + children: leaderboardJson + .map( + (e) => LeaderboardElement( + id: e["id"], + rank: e["rank"], + points: e["points"], + leaderboardArrowIconPath: e["leaderboardArrowIconPath"], + imgPath: e["imgPath"], + userName: e["userName"], + ), + ) + .toList(), + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/my_ranking/mvp_elites_leaderboard.dart b/gsf/lib/views/pages/my_ranking/mvp_elites_leaderboard.dart new file mode 100644 index 0000000..d940b70 --- /dev/null +++ b/gsf/lib/views/pages/my_ranking/mvp_elites_leaderboard.dart @@ -0,0 +1,643 @@ +// ignore_for_file: prefer_const_constructors, prefer_typing_uninitialized_variables, unrelated_type_equality_checks + +import 'dart:async'; +import 'dart:io'; +import 'dart:ui'; + +import 'package:animations/animations.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/view_model/StepcountController.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:skeletons/skeletons.dart'; +import '../../../modals/leaderboard_ranking_model.dart'; +import '../../../repository/services/cj/leader_board_ranking.dart'; +import '../../../view_model/my_ranking_controller.dart'; +import '../../components/bottom_navigation.dart'; +import '../../components/leaderboard_element.dart'; +import '../../theme.dart'; +import '../StepCount/HealthApp.dart'; +import '../profile/pages/view_profile.dart'; +import 'filter_elites_leaderboard.dart'; + +class MVPelitesBoard extends StatefulWidget { + const MVPelitesBoard({Key? key}) : super(key: key); + + @override + State createState() => _MVPelitesBoardState(); +} + +class _MVPelitesBoardState extends State + with SingleTickerProviderStateMixin { + AppDataController appDataController = Get.find(); + late AnimationController _animationController; + late Timer _timer; + var userIndexId; + var up = 'assets/image/arrows/arrow_up.svg'; + var down = 'assets/image/arrows/arrow_down.svg'; + var still = 'assets/image/arrows/arrow_right.svg'; + + late String genderDefaultSelected; + late String groupLevelDefaultSelected; + final calculateStepsFromHealthApp stepscontroller = + Get.put(calculateStepsFromHealthApp()); + String timeAgo = ''; + String timeAgoSelf = ''; + // Timer? _timer; // Timer object to schedule periodic refresh + + void _startTimer() { + _timer = Timer.periodic(Duration(seconds: 25), (Timer timer) async { + if (Platform.isIOS) { + await stepscontroller.storeStepsInDB(); + } + + setState(() {}); + }); + } + + @override + void initState() { + super.initState(); + _startTimer(); + if (Platform.isIOS) { + stepscontroller.storeStepsInDB(); + } + _animationController = AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 600), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + ); + } + + @override + void dispose() { + _timer.cancel(); + _animationController.dispose(); + super.dispose(); + } + + MyRankingController myRankingController = Get.put(MyRankingController()); + + @override + Widget build(BuildContext context) { + int index = -1; + _animationController.forward(); + final brightness = Get.theme.brightness; + + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: AppBar( + automaticallyImplyLeading: false, + titleSpacing: 0, + centerTitle: true, + // backgroundColor: ColorConstants.kBlack, + // elevation: 0, + title: Text( + 'Leaderboard', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + bottom: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: Padding( + padding: const EdgeInsets.only(bottom: 20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + // debugPrint("BackdropFilter, $genderDefaultSelected"); + // debugPrint("BackdropFilter, $groupLevelDefaultSelected"); + Get.dialog( + BackdropFilter( + filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), + child: FilterLeaderboard( + defaultGender: genderDefaultSelected, + defaultGroupLevel: groupLevelDefaultSelected), + ), + ); + }, + child: Container( + height: 36, + padding: const EdgeInsets.symmetric(horizontal: 18), + // decoration: ShapeDecoration( + // color: Color(0xff333333), + // shape: StadiumBorder(), + // ), + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(50), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.12), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Row(mainAxisSize: MainAxisSize.min, children: [ + Text( + "Filter", + style: QuizTextStyles.heading.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + SizedBox(width: 6), + Icon( + Icons.filter_alt, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white, + size: 20, + ), + ]), + ), + ), + const SizedBox(width: 24), + ], + ), + ), + ), + ), + body: Obx(() { + return AnimatedBuilder( + child: FutureBuilder( + future: RankingLeaderboard().getLeaderboardRanking( + gender: myRankingController.gender.value, + groupLevel: myRankingController.groupLevel.value, + ), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return ListView( + children: [ + for (var i = 0; i < 12; i++) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 8), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: context.width, + height: 56, + borderRadius: BorderRadius.circular(100), + ), + ), + ), + ], + ); + } else if (snapshot.hasError) { + return Center( + child: + Text('Something Went Wrong\n please try again later ☹️.'), + ); + } else { + RnakingModel userRanking = snapshot.data!.data; + // print('userRanking test ${userRanking.groupLevel}'); + genderDefaultSelected = userRanking.gender; + groupLevelDefaultSelected = userRanking.groupLevel; + final userID = appDataController.id; + List x = userRanking.userData as List; + var selfData; + // print('all x data ${userRanking.userData![0].totalScore}'); + try { + selfData = x.where((e) => e.userId == userID.value).first; + } catch (e) { + selfData = null; + } + + for (var i = 0; i < userRanking.userData!.length; i++) { + if (userRanking.userData![i].userId == userID.value) { + userIndexId = i + 1; + // print('userIndex without null'); + break; + // print('userIndexId $userIndexId'); + } else { + // print('userIndex with null'); + userIndexId = null; + } + // print('userIndexId user id ${appDataController.id};'); + } + print('userIndexId $userIndexId'); + + void calculateTimeAgo(times) { + // var yearsinDays = 365; + DateTime now = DateTime.now(); + DateTime timestamp = DateTime.parse(times); + Duration difference = now.difference(timestamp); + + if (difference.inSeconds < 60) { + timeAgo = '${difference.inSeconds} seconds ago'; + } else if (difference.inMinutes < 60) { + timeAgo = '${difference.inMinutes} minutes ago'; + } else if (difference.inHours < 24) { + timeAgo = '${difference.inHours} hours ago'; + } else if (difference.inDays < 30) { + timeAgo = '${difference.inDays} days ago'; + } else if (difference.inDays < 365) { + int months = (difference.inDays / 30).floor(); + timeAgo = '$months months ago'; + } else { + int years = (difference.inDays / 365).floor(); + timeAgo = '$years years ago'; + } + // return ''; + } + + void calculateTimeAgoSelf(times) { + // var yearsinDays = 365; + DateTime now = DateTime.now(); + DateTime timestamp = DateTime.parse(times); + Duration difference = now.difference(timestamp); + + if (difference.inSeconds < 60) { + timeAgoSelf = '${difference.inSeconds} seconds ago'; + } else if (difference.inMinutes < 60) { + timeAgoSelf = '${difference.inMinutes} minutes ago'; + } else if (difference.inHours < 24) { + timeAgoSelf = '${difference.inHours} hours ago'; + } else if (difference.inDays < 30) { + timeAgoSelf = '${difference.inDays} days ago'; + } else if (difference.inDays < 365) { + int months = (difference.inDays / 30).floor(); + timeAgoSelf = '$months months ago'; + } else { + int years = (difference.inDays / 365).floor(); + timeAgoSelf = '$years years ago'; + } + // return ''; + } + + return (userRanking.userData!.isNotEmpty) + ? ListView( + children: [ + SizedBox( + height: 300, + child: Center( + child: ListView( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + children: [ + //index: 1 + SizedBox( + width: Get.size.width * 0.31, + child: (userRanking.userData!.length >= 2 && + userRanking.userData![1].user + ?.fullName != + null) + ? OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.only( + top: 110), + child: WinnerUserElement( + point: userRanking + .userData![1].totalScore, + rankIconPath: (userRanking + .userData![1] + .progressBar == + '0') + ? "assets/image/arrows/arrow_up.svg" + : (userRanking.userData![1] + .progressBar == + '1') + ? "assets/image/arrows/arrow_down.svg" + : "assets/image/arrows/arrow_right.svg", + imgUrl: userRanking + .userData![1] + .userData! + .profilePicture ?? + "", + name: userRanking.userData![1] + .user!.fullName, + rank: 2, + ), + ), + openBuild: ViewProfile( + viewFrndProfileModels: + userRanking.userData![1], + groupLevel: + userRanking.groupLevel, + ), + ) + : SizedBox(), + ), + //index: 0 + SizedBox( + width: Get.size.width * 0.31, + child: (userRanking.userData!.length >= 1 && + userRanking.userData![0].user + ?.fullName != + null) + ? OpenContainerWrappers( + closeBuild: WinnerUserElement( + point: userRanking + .userData![0].totalScore, + large: true, + rankIconPath: + "assets/image/crown.svg", + imgUrl: userRanking + .userData![0] + .userData! + .profilePicture ?? + "", + name: userRanking + .userData![0].user!.fullName, + rank: 1, + ), + openBuild: ViewProfile( + viewFrndProfileModels: + userRanking.userData![0], + groupLevel: + userRanking.groupLevel, + ), + ) + : SizedBox(), + ), + //index: 2 + SizedBox( + width: Get.size.width * 0.31, + child: (userRanking.userData!.length >= 3 && + userRanking.userData![2].user + ?.fullName != + null) + ? OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.only( + top: 110), + child: WinnerUserElement( + point: userRanking + .userData![2].totalScore, + rankIconPath: (userRanking + .userData![2] + .progressBar == + '0') + ? "assets/image/arrows/arrow_up.svg" + : (userRanking.userData![2] + .progressBar == + '1') + ? "assets/image/arrows/arrow_down.svg" + : "assets/image/arrows/arrow_right.svg", + imgUrl: userRanking + .userData![2] + .userData! + .profilePicture ?? + "", + name: userRanking.userData![2] + .user!.fullName, + rank: 3, + ), + ), + openBuild: ViewProfile( + viewFrndProfileModels: + userRanking.userData![2], + groupLevel: + userRanking.groupLevel, + ), + ) + : SizedBox(), + ) + ], + ), + ), + ), + + // Self ranking counting + + userIndexId != null + ? userIndexId > 5 + ? Builder(builder: (context) { + calculateTimeAgoSelf( + selfData.updatatedTime); + return OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.only( + left: 8, + right: 8, + bottom: 16, + ), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants + .kPrimaryColor, + width: 1, + ), + borderRadius: + BorderRadius.circular(30)), + child: LeaderboardElement( + id: index, + rank: userIndexId, + points: selfData.totalScore, + leaderboardArrowIconPath: (selfData + .progressBar == + '0') + ? "assets/image/arrows/arrow_up.svg" + : (selfData.progressBar == + '1') + ? "assets/image/arrows/arrow_down.svg" + : "assets/image/arrows/arrow_right.svg", + imgPath: selfData.userData + ?.profilePicture ?? + "", + userName: 'You', + lastUpdate: timeAgoSelf, + ), + ), + ), + openBuild: ViewProfile( + viewFrndProfileModels: userRanking + .userData![userIndexId - 1], + groupLevel: userRanking.groupLevel, + ), + ); + }) + : SizedBox() + : SizedBox(), + + (userRanking.userData!.length > 3) + ? ListView.builder( + itemCount: userRanking.userData!.length - 3, + physics: BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + List newLength = + userRanking.userData!.sublist(3); + calculateTimeAgo( + newLength[index].updatatedTime); + return OpenContainerWrappers( + closeBuild: Padding( + padding: const EdgeInsets.only( + left: 8, + right: 8, + bottom: 16, + ), + child: LeaderboardElement( + lastUpdate: '${timeAgo}', + id: index, + rank: index + 4, + points: newLength[index].totalScore, + leaderboardArrowIconPath: (newLength[ + index] + .progressBar == + '0') + ? "assets/image/arrows/arrow_up.svg" + : (newLength[index].progressBar == + '1') + ? "assets/image/arrows/arrow_down.svg" + : "assets/image/arrows/arrow_right.svg", + imgPath: newLength[index] + .userData + ?.profilePicture ?? + "", + userName: + newLength[index].user.fullName, + ), + ), + openBuild: ViewProfile( + viewFrndProfileModels: newLength[index], + groupLevel: userRanking.groupLevel, + ), + ); + }, + ) + : SizedBox(), + ], + ) + : Center(child: Text('No User Found')); + } + }, + ), + animation: _animationController, + builder: (context, child) => FadeScaleTransition( + animation: _animationController, + child: child, + ), + ); + }), + + bottomNavigationBar: BottomNavigation( + // three: BottomNavigationController.three, + // four: BottomNavigationController.four, + // five: BottomNavigationController.five, + // six: BottomNavigationController.six, + // seven: BottomNavigationController.seven, + ), + ); + } +} + +class WinnerUserElement extends StatelessWidget { + const WinnerUserElement({ + Key? key, + required this.rankIconPath, + required this.imgUrl, + required this.name, + required this.rank, + required this.point, + this.large = false, + }) : super(key: key); + + final String rankIconPath; + final String imgUrl; + final String name; + final int rank; + final bool large; + final int point; + + @override + Widget build(BuildContext context) { + // AppDataController appDataController = Get.find(); + GlobalController globalController = Get.find(); + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + //rank icon + SvgPicture.asset( + rankIconPath, + width: large ? 65 : 24, + ), + const SizedBox(height: 8), + //profile pic + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + Container( + width: large ? 118 : 84, + height: large ? 118 : 84, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 2, + ), + shape: BoxShape.circle, + ), + child: imgUrl.isEmpty + ? ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I='), + ) + : CircleAvatar( + // foregroundColor:!globalController.darkMode.value? Colors.transparent:Colors.transparent, + backgroundImage: NetworkImage( + correctImgUrl(imgUrl), + ), + backgroundColor: Colors.transparent, + ), + ), + Positioned( + bottom: -10, + child: CircleAvatar( + // foregroundColor:!globalController.darkMode.value?ColorConstants.kErroColor:Colors.transparent, + backgroundColor: large + ? ColorConstants.kPrimaryColor + : ColorConstants.kWhite, + maxRadius: large ? 16 : 12, + child: Text( + rank.toString(), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: large ? 18 : 14, + color: ColorConstants.kBlack, + ), + ), + ), + ), + ], + ), + SizedBox(height: 16), + Text( + name, + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox(height: 2), + Obx( + () => Text( + point.toString(), + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/no_internet.dart b/gsf/lib/views/pages/no_internet.dart new file mode 100644 index 0000000..83eb46a --- /dev/null +++ b/gsf/lib/views/pages/no_internet.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../components/appbar.dart'; +import '../components/btn.dart'; +import '../theme.dart'; + +class NoInternetConnection extends StatelessWidget { + const NoInternetConnection({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'No Internet',showLeading: false,), + ), + body: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + children: [ + const Spacer(), + SvgPicture.asset('assets/image/no-wifi-icon.svg'), + const SizedBox(height: 16), + const Text( + 'No Internet Connection!', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 15), + const Text( + 'Due to some reason, we are unable to connect with our server. Please check your internet connection. Do not let this disturbance stop your fitness journey. Get down on the ground right now and do 5 sets of 25 push-ups till the connection is restored.', + style: TextStyle( + fontSize: 16, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 30), + FullWdtBtn(btnText: 'Try Again', onTap: () {}), + const Spacer(), + ], + ), + )), + ); + } +} diff --git a/gsf/lib/views/pages/notification.dart b/gsf/lib/views/pages/notification.dart new file mode 100644 index 0000000..c3e9865 --- /dev/null +++ b/gsf/lib/views/pages/notification.dart @@ -0,0 +1,389 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/components/appbar.dart'; +import 'package:gsp_app/views/pages/bioMaker/add_scale.dart'; +import 'package:gsp_app/views/pages/home/home.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:skeletons/skeletons.dart'; +import '../../modals/notification_model.dart'; +import '../../repository/response_data.dart'; +import '../../repository/services/cj/get_notification_count_service.dart'; +import '../../view_model/home_page_controller.dart'; +import '../theme.dart'; +import '../../view_model/home_controller.dart'; +import 'bioMaker/overview.dart'; +import 'profile/pages/profile_page.dart'; + +class Notifications extends StatefulWidget { + const Notifications({Key? key}) : super(key: key); + + @override + State createState() => _NotificationsState(); +} + +class _NotificationsState extends State { + String timeAgo = ''; + HomePageController homePageController = Get.put(HomePageController()); + + @override + void initState() { + GetNotificationCount().getNotificationCout(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final TabsController controller = TabsController(); + final brightness = Get.theme.brightness; + return Scaffold( + key: controller.scaffoldKey, + // backgroundColor: ColorConstants.kBlack, + // drawer: AppDrawer(), + appBar: PreferredSize( + preferredSize: Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Notification'), + ), + body: Column( + children: [ + FutureBuilder( + future: GetNotificationCount().getNotificationCout(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + NotificationModel data = snapshot.data!.data; + return Expanded( + child: data.notificationList.isNotEmpty + ? ListView.separated( + itemCount: data.notificationList.length, + shrinkWrap: true, + itemBuilder: (context, index) { + var notificvationList = data.notificationList; + List + notificvationListReversed = + List.from(notificvationList.reversed); + + void calculateTimeAgo() { + DateTime now = DateTime.now(); + DateTime timestamp = DateTime.parse( + notificvationListReversed[index].timesAgo); + Duration difference = now.difference(timestamp); + + if (difference.inSeconds < 60) { + timeAgo = '${difference.inSeconds} seconds ago'; + } else if (difference.inMinutes < 60) { + timeAgo = '${difference.inMinutes} minutes ago'; + } else if (difference.inHours < 24) { + timeAgo = '${difference.inHours} hours ago'; + } else if (difference.inDays < 30) { + timeAgo = '${difference.inDays} days ago'; + } else if (difference.inDays < 365) { + int months = (difference.inDays / 30).floor(); + timeAgo = '$months months ago'; + } else { + int years = (difference.inDays / 365).floor(); + timeAgo = '$years years ago'; + } + } + + calculateTimeAgo(); + + return GestureDetector( + // print() + onTap: () { + if (notificvationListReversed[index] + .notificationMasterData + .message == + "Mood-O-Meter") { + Get.back(); + // Get.to(()=>Notifications()); + homePageController.updateBottomNavIndex(0); + } else if (notificvationListReversed[index] + .notificationMasterData + .message == + "Test1") { + Get.back(); + homePageController.updateBottomNavIndex(4); + } else if (notificvationListReversed[index] + .notificationMasterData + .message == + "Test2") { + Get.back(); + homePageController.updateBottomNavIndex(0); + } else if (notificvationListReversed[index] + .notificationMasterData + .message == + "frfr") { + Get.back(); + homePageController.updateBottomNavIndex(0); + } + GetNotificationCount().readNotification( + notificvationListReversed[index] + .notificationId); + }, + child: Container( + color: (brightness == Brightness.light) + ? (notificvationListReversed[index] + .isRead == + "0") + ? Colors.white + : Colors.black.withOpacity(0.2) + : (notificvationListReversed[index] + .isRead == + "0") + ? Color(0xff212121) + : Color(0xff000000), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Expanded( + flex: 0, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: const Color(0xff707070), + ), + borderRadius: + BorderRadius.circular(100), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(50), + child: Image.asset( + 'assets/image/gsf_avatar.png', + fit: BoxFit.cover, + filterQuality:FilterQuality.high, + ), + ), + ), + ), + const SizedBox(width: 10), + Expanded( + flex: 2, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + notificvationListReversed[ + index] + .notificationMasterData + .title, + style: TextStyle( + fontSize: 16, + color: (brightness == + Brightness + .light) + ? Color( + 0xff000000) + : Color( + 0xffD9D9D9), + fontFamily: 'SFPRO', + fontWeight: (notificvationListReversed[ + index] + .isRead == + "0") + ? FontWeight.w600 + : FontWeight + .normal, + ), + maxLines: 2, + overflow: TextOverflow + .ellipsis, + ), + SizedBox(height: 4), + ], + ), + ), + Expanded( + flex: 0, + child: GestureDetector( + onTap: () { + print( + // "Notification id is ${notificvationListReversed[index].notificationId}"); + GetNotificationCount() + .deleteNnotification( + notificvationListReversed[ + index] + .notificationId)); + setState(() {}); + }, + child: Icon( + Icons.delete_rounded, + size: 30, + color: (brightness == + Brightness + .light) + ? ColorConstants + .kBlack + : ColorConstants + .kWhite, + ), + )) + ], + ), + SizedBox(height: 8), + Text( + timeAgo, + style: TextStyle( + fontSize: 14, + color: (brightness == + Brightness.light) + ? Color(0xff000000) + .withOpacity(0.7) + : Color(0xff858585), + fontFamily: 'SFPRO', + ), + ) + ], + ), + ), + ], + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return Padding( + padding: + const EdgeInsets.symmetric(horizontal: 20), + child: Divider( + height: 1, + thickness: 1, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0) + : ColorConstants.kWhite.withOpacity(0.3), + ), + ); + }, + ) + : Center(child: Text('No Notification Found')), + ); + } + return ListView.builder( + itemCount: 7, + shrinkWrap: true, + itemBuilder: (context, index) { + return SkeletonAvatar( + style: SkeletonAvatarStyle( + maxWidth: Get.width, + padding: + const EdgeInsets.only(left: 12, right: 12, top: 8), + width: Get.width, + height: 60, + borderRadius: BorderRadius.circular(5), + ), + ); + }, + ); + }, + ), + ], + ), + ); + } + + notificationWidget() { + final brightness = Get.theme.brightness; + return Container( + color: + (brightness == Brightness.light) ? Colors.white : Color(0xff000000), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + child: Row( + children: [ + Expanded( + flex: 0, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: const Color(0xff707070), + ), + borderRadius: BorderRadius.circular(100), + ), + child: Image.asset( + 'assets/image/avatar.png', + ), + ), + ), + const SizedBox(width: 10), + Expanded( + flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: Text( + 'You received 5 points for maintaining your daily step count. Keep up the grind.', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? Color(0xff000000) + : Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + Expanded( + flex: 0, + child: Icon( + Icons.delete_rounded, + size: 30, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + )) + ], + ), + SizedBox(height: 8), + Text( + '4 hours ago', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? Color(0xff000000).withOpacity(0.7) + : Color(0xff858585), + fontFamily: 'SFPRO'), + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/podcast/podcast.dart b/gsf/lib/views/pages/podcast/podcast.dart new file mode 100644 index 0000000..a34f31b --- /dev/null +++ b/gsf/lib/views/pages/podcast/podcast.dart @@ -0,0 +1,226 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/podcast/podcats_manager.dart'; + +import '../../components/appbar.dart'; +import '../../components/page_animation.dart'; +import '../../theme.dart'; +import 'podcast_list_audio.dart'; +import 'viewModel/PodcastApis.dart'; + +class PodcastMain extends StatefulWidget { + const PodcastMain({Key? key}) : super(key: key); + + @override + State createState() => _PodcastMainState(); +} + +class _PodcastMainState extends State { + Future? myfuture; + List itemList = [ + 'Latest', + // 'Most Played', + // 'Self Help', + ]; + @override + void initState() { + myfuture = PodcastApis().getPodcasts(); + super.initState(); + } + + Visible visibleController = Get.put(Visible()); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Podcasts'), + ), + body: FutureBuilder( + future: myfuture, + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [Center(child: CircularProgressIndicator())], + ); + } + if (snapshot.connectionState == ConnectionState.done) { + visibleController.addTitles(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return _buildBody(); + }, + ), + ); + } + + _buildBody() { + return SingleChildScrollView( + physics: ScrollPhysics(), + child: Column( + children: [ + Container( + height: 300, + width: Get.size.width, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'assets/image/podcast/podcastImg.jpg', + ), + alignment: Alignment.topCenter, + fit: BoxFit.cover, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Spacer(flex: 3), + // Container( + // width: 52, + // height: 52, + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor.withOpacity(0.9), + // shape: BoxShape.circle, + // ), + // child: const Icon( + // Icons.play_arrow_rounded, + // color: ColorConstants.kBlack, + // size: 40, + // ), + // ), + SizedBox(height: 10), + Text( + 'Weekly Podcasts', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + Spacer(flex: 1), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListView.builder( + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: itemList.length, + scrollDirection: Axis.vertical, + itemBuilder: (context, index) => Column( + children: [ + headWithArrow( + itemList[index], + () => Get.to( + () => const PodcastAudioPalyer(), + ), + ), + const SizedBox(height: 15), + podcast(), + SizedBox(height: 30) + ], + ), + ), + ), + ], + ), + ); + } + + podcast() { + return SizedBox( + height: 170, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: pods?.result?.latestPodcast?.length ?? 0, + itemBuilder: (context, index) => GestureDetector( + onTap: () { + Get.to(() => PodcastAudioPalyer()); + }, + child: Padding( + padding: const EdgeInsets.only(left: 8, right: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: SizedBox( + width: 94, + height: 94, + child: Image.network( + pods!.result!.latestPodcast![index].bannerImage!, + fit: BoxFit.cover, + ), + ), + ), + ), + const SizedBox(height: 10), + Text( + pods!.result!.latestPodcast![index].title!, + style: TextStyle( + fontSize: 12, + color: Color(0xffFFFFFF), + ), + ), + SizedBox( + height: 5, + ), + Image.asset('assets/image/music.png'), + SizedBox( + height: 5, + ), + // const Text( + // '0.30 Min', + // style: TextStyle( + // fontSize: 10, + // color: ColorConstants.kWhite, + // ), + // ) + ], + ), + ), + ), + ), + ); + } + + headWithArrow(String head, VoidCallback ontap) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + head, + style: const TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + InkWell( + onTap: ontap, + child: const Icon( + Icons.keyboard_arrow_right, + color: ColorConstants.kWhite, + size: 30, + ), + ) + ], + ); + } +} diff --git a/gsf/lib/views/pages/podcast/podcast_list.dart b/gsf/lib/views/pages/podcast/podcast_list.dart new file mode 100644 index 0000000..52d921c --- /dev/null +++ b/gsf/lib/views/pages/podcast/podcast_list.dart @@ -0,0 +1,452 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:audioplayers/audioplayers.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class PodcastList extends StatefulWidget { + const PodcastList({Key? key}) : super(key: key); + + @override + State createState() => _PodcastListState(); +} + +class _PodcastListState extends State with WidgetsBindingObserver { + bool isplaying = false; + bool playOrNot = false; + double value = 0; + List audioList = [ + "https://pwdown.info/8555/01 Desi Kalakaar - Yo Yo Honey Singh (PagalWorld.com).mp3", + "https://pwdown.info/113504/First Kiss - Yo Yo Honey Singh.mp3" + ]; + String audioMusic = + "https://pwdown.info/113504/First Kiss - Yo Yo Honey Singh.mp3"; + initplayer() async { + // await player.setSourceUrl(audioMusic); + await player.setSource(AssetSource("audio/nature.mp3")); + duration = await player.getDuration(); + } + + @override + void initState() { + super.initState(); + initplayer(); + checkMusicApp(); + WidgetsBinding.instance.addObserver(this); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.paused) { + //stop your audio player + setState(() { + player.pause(); + isplaying = false; + }); + // dispose(); + } + } + + checkMusicApp() { + player.onPlayerComplete.listen((event) { + setState(() { + isplaying = false; + }); + }); + } + + @override + void dispose() async { + await player.pause(); + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + // late AudioPlayer audioPlayer; + final player = AudioPlayer(); + Duration? duration = Duration(seconds: 0); + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + setState(() { + player.stop(); + isplaying = false; + }); + return true; + }, + child: Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: Size.fromHeight(300), + child: AppBar( + backgroundColor: Colors.transparent, + leadingWidth: 70, + flexibleSpace: FlexibleSpaceBar( + titlePadding: EdgeInsets.all(0), + title: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Set To Inspire', + style: TextStyle( + fontSize: 35, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + height: 0, + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + 'Our Daily Latest Podcast', + style: TextStyle( + fontSize: 22, + fontFamily: 'SFPRO', + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w600, + ), + ), + Spacer(), + Container( + width: 52, + height: 52, + decoration: BoxDecoration( + color: + ColorConstants.kPrimaryColor.withOpacity(0.9), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.play_arrow_rounded, + color: ColorConstants.kBlack, + size: 40, + ), + ), + ], + ), + ], + ), + ), + background: Image.asset( + 'assets/image/podcast/podcastImg.jpg', + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + ), + leading: Padding( + padding: const EdgeInsets.only( + top: 10, left: 18, right: 15, bottom: 10), + child: InkWell( + splashColor: const Color(0xff313030).withOpacity(0.5), + borderRadius: BorderRadius.circular(7), + onTap: () { + Get.back(); + // setState(() { + // player.pause(); + // isplaying = false; + // }); + dispose(); + }, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: const Color(0xff313030), + borderRadius: BorderRadius.circular(7), + ), + child: const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Icon( + Icons.arrow_back_ios, + color: ColorConstants.kWhite, + size: 20, + ), + ), + ), + ), + ), + ), + ), + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 20), + Text( + 'Latest', + style: TextStyle( + fontSize: 22, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 30), + ListView.builder( + scrollDirection: Axis.vertical, + itemCount: 8, + shrinkWrap: true, + physics: ScrollPhysics(), + itemBuilder: (context, index) => Padding( + padding: EdgeInsets.only(bottom: 25), + child: podcastList(index + 1), + ), + ), + Visibility( + child: SizedBox( + height: 80, + ), + replacement: SizedBox(), + visible: playOrNot, + ) + ], + ), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: playOrNot + ? Container( + width: Get.size.width, + height: 100, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor, + ), + child: Row( + children: [ + Expanded( + flex: 1, + child: Align( + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/image/avatar.png', + width: 57, + height: 57, + fit: BoxFit.cover, + ), + ), + ), + ), + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Ep.25- Set To Inspire:', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + // SizedBox(height: 5), + Text( + 'Our Daily Podcast', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + SizedBox(height: 5), + SizedBox( + height: 20, + child: Stack( + children: [ + Positioned( + left: -20, + right: 0, + top: 0, + bottom: 0, + child: SliderTheme( + data: SliderThemeData( + trackHeight: 2.0, + thumbColor: Colors.black, + thumbShape: RoundSliderThumbShape( + enabledThumbRadius: 0.0, + ), + inactiveTrackColor: Colors.black, + activeTrackColor: Colors.white, + ), + child: Slider( + min: 0, + max: duration!.inSeconds.toDouble(), + divisions: 100, + activeColor: Colors.black, + inactiveColor: Colors.white, + value: value, + onChanged: (v) { + setState(() { + value = v; + }); + }, + onChangeEnd: (newValue) async { + setState(() { + value = newValue; + // print(newValue); + }); + player.pause(); + await player.seek( + Duration( + seconds: newValue.toInt(), + ), + ); + await player.resume(); + }, + ), + ), + ), + ], + ), + ) + ], + ), + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () async { + if (isplaying) { + await player.pause(); + setState(() { + isplaying = false; + }); + } else { + await player.resume(); + player.onPositionChanged.listen( + (position) { + setState( + () { + value = position.inSeconds.toDouble(); + }, + ); + }, + ); + setState( + () { + isplaying = true; + }, + ); + } + }, + child: Icon( + isplaying ? Icons.pause : Icons.play_arrow_rounded, + size: 50, + color: ColorConstants.kBlack, + ), + ), + ), + ], + ), + ) + : SizedBox(), + ), + ); + } + + podcastList(int index) { + return Row( + children: [ + Expanded( + flex: 0, + child: Text( + index.toString(), + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ), + Expanded( + flex: 1, + child: Align( + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/image/avatar.png', + width: 57, + height: 57, + fit: BoxFit.cover, + )), + ), + ), + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + 'Ep.25- Set To Inspire:', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + SizedBox(height: 5), + Text( + 'Our Daily Podcast', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + ], + ), + ), + Expanded( + flex: 0, + child: InkWell( + onTap: () { + setState(() { + playOrNot = true; + isplaying = true; + }); + setState(() async { + await player.resume(); + player.onPositionChanged.listen( + (position) { + setState( + () { + value = position.inSeconds.toDouble(); + }, + ); + }, + ); + // if (player.getDuration() == 0) { + // isplaying = false; + // } + }); + }, + child: Icon( + Icons.play_arrow_rounded, + size: 50, + color: ColorConstants.kWhite, + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/podcast/podcast_list_audio.dart b/gsf/lib/views/pages/podcast/podcast_list_audio.dart new file mode 100644 index 0000000..073b808 --- /dev/null +++ b/gsf/lib/views/pages/podcast/podcast_list_audio.dart @@ -0,0 +1,416 @@ +import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/pages/podcast/podcats_manager.dart'; +import 'package:gsp_app/views/pages/podcast/viewModel/PodcastApis.dart'; +import 'package:lottie/lottie.dart'; + +import '../../theme.dart'; + +class PodcastAudioPalyer extends StatefulWidget { + const PodcastAudioPalyer({Key? key}) : super(key: key); + + @override + State createState() => _PodcastAudioPalyerState(); +} + +class _PodcastAudioPalyerState extends State + with WidgetsBindingObserver { + Visible visibleController = Get.put(Visible()); + PodcastPageManager helperController = Get.put(PodcastPageManager()); + + @override + void initState() { + setAllTitlesbools(); + WidgetsBinding.instance.addObserver(this); + visibleController.isAudioSeekBarVisible.value = false; + super.initState(); + } + + // @override + // void didChangeAppLifecycleState(AppLifecycleState state) { + // if (state == AppLifecycleState.paused) { + // helperController + // .stop(); // Stop audio when the app goes into the background + // } + // } + + setAllTitlesbools() { + visibleController.titlePlayingList!.assignAll(List.generate( + pods!.result!.latestPodcast!.length, + (index) => false, + )); + } + + @override + void dispose() { + helperController.stop(); + WidgetsBinding.instance?.removeObserver(this); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + // visibleController.isAudioSeekBarVisible.value = false; + return true; + }, + child: Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(300), + child: AppBar( + backgroundColor: Colors.transparent, + leadingWidth: 70, + flexibleSpace: FlexibleSpaceBar( + titlePadding: const EdgeInsets.all(0), + title: Padding( + padding: + const EdgeInsets.only(left: 20.0, right: 20, bottom: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Set To Inspire', + style: TextStyle( + fontSize: 35, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + height: 0, + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const Text( + 'Our Daily Latest Podcast', + style: TextStyle( + fontSize: 22, + fontFamily: 'SFPRO', + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w600, + ), + ), + const Spacer(), + SizedBox( + width: 52, + height: 52, + ) + // Container( + // width: 52, + // height: 52, + // decoration: BoxDecoration( + // color: + // ColorConstants.kPrimaryColor.withOpacity(0.9), + // shape: BoxShape.circle, + // ), + // child: const Icon( + // Icons.play_arrow_rounded, + // color: ColorConstants.kBlack, + // size: 40, + // ), + // ), + ], + ), + ], + ), + ), + background: Image.asset( + 'assets/image/podcast/podcastImg.jpg', + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + ), + leading: Padding( + padding: const EdgeInsets.only( + top: 10, left: 18, right: 15, bottom: 10), + child: InkWell( + splashColor: const Color(0xff313030).withOpacity(0.5), + borderRadius: BorderRadius.circular(7), + onTap: () { + // visibleController.isAudioSeekBarVisible.value = false; + Get.back(); + }, + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: const Color(0xff313030), + borderRadius: BorderRadius.circular(7), + ), + child: const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Icon( + Icons.arrow_back_ios, + color: ColorConstants.kWhite, + size: 20, + ), + ), + ), + ), + ), + ), + ), + body: SingleChildScrollView( + physics: const ScrollPhysics(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + const Text( + 'Latest', + style: TextStyle( + fontSize: 22, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 30), + ListView.builder( + scrollDirection: Axis.vertical, + itemCount: pods?.result?.latestPodcast?.length ?? 0, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemBuilder: (context, index) => Padding( + padding: const EdgeInsets.only(bottom: 25), + child: podcastList(index), + ), + ), + const SizedBox( + height: 100, + ) + ], + ), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: + Obx(() => visibleController.isAudioSeekBarVisible.value + ? Container( + width: Get.size.width, + height: 100, + decoration: const BoxDecoration( + color: ColorConstants.kPrimaryColor, + ), + child: Row( + children: [ + Expanded( + flex: 1, + child: Align( + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.network( + pods! + .result! + .latestPodcast![ + visibleController.indexForAudios.value] + .bannerImage!, + width: 57, + height: 57, + fit: BoxFit.cover, + ), + ), + ), + ), + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + pods! + .result! + .latestPodcast![ + visibleController.indexForAudios.value] + .title!, + style: const TextStyle( + fontSize: 14, + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + // SizedBox(height: 5), + Text( + pods! + .result! + .latestPodcast![ + visibleController.indexForAudios.value] + .description!, + style: const TextStyle( + fontSize: 14, + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + ValueListenableBuilder( + valueListenable: + helperController.progressNotifier, + builder: (_, value, __) { + return ProgressBar( + progress: value.current, + buffered: value.buffered, + total: value.total, + onSeek: helperController.seek, + barHeight: 4, + thumbRadius: 6, + thumbGlowRadius: 15, + thumbColor: ColorConstants.kBlack, + baseBarColor: + ColorConstants.kBlack.withOpacity(0.3), + progressBarColor: ColorConstants.kBlack, + bufferedBarColor: + ColorConstants.kBlack.withOpacity(0.3), + ); + }, + ), + ], + ), + ), + Expanded( + flex: 1, + child: ValueListenableBuilder( + valueListenable: helperController.buttonNotifier, + builder: (_, value, __) { + switch (value) { + case ButtonState.paused: + return IconButton( + icon: const Icon(Icons.play_arrow_rounded), + iconSize: 50.0, + onPressed: () => helperController.play( + visibleController.indexForAudios.value), + ); + case ButtonState.playing: + return IconButton( + icon: const Icon(Icons.pause), + iconSize: 50.0, + onPressed: helperController.pause, + ); + } + }, + ), + ), + ], + ), + ) + : Container()), + ), + ); + } + + podcastList(int index) { + return InkWell( + onTap: () { + visibleController.updateTitlePlaying(index); + if (helperController.isPlaying()) { + helperController.stop(); + } + + helperController.init(index); + helperController.play(index); + setState(() {}); + }, + child: Row( + children: [ + Expanded( + flex: 0, + child: Text( + (index + 1).toString(), + style: const TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ), + Expanded( + flex: 1, + child: Align( + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.network( + pods!.result!.latestPodcast![index].bannerImage!, + width: 57, + height: 57, + fit: BoxFit.cover, + )), + ), + ), + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 180, + child: Row( + children: [ + Obx(() => visibleController.titlePlayingList![index] + ? SizedBox( + width: 30, + height: 30, + child: Lottie.asset( + 'assets/lottie/spotifyMusic.json')) + : Container()), + Obx( + () => Text( + pods!.result!.latestPodcast![index].title!, + style: TextStyle( + fontSize: 14, + color: visibleController.titlePlayingList![index] + ? ColorConstants.kPrimaryColor + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 5), + Text( + pods!.result!.latestPodcast![index].description!, + style: const TextStyle( + fontSize: 14, + color: Color.fromARGB(174, 255, 255, 255), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + height: 1.5, + ), + ), + ], + ), + ), + // Expanded( + // flex: 0, + // child: InkWell( + // splashColor: Colors.transparent, + // onTap: () { + // // helperController.stop(); + // helperController.init(index); + // helperController.play(index); + // }, + // child: const Icon( + // Icons.play_arrow_rounded, + // size: 50, + // color: ColorConstants.kWhite, + // ), + // ), + // ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/podcast/podcats_manager.dart b/gsf/lib/views/pages/podcast/podcats_manager.dart new file mode 100644 index 0000000..06e2770 --- /dev/null +++ b/gsf/lib/views/pages/podcast/podcats_manager.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/pages/podcast/viewModel/PodcastApis.dart'; +import 'package:just_audio/just_audio.dart'; + +class Visible extends GetxController { + RxBool isAudioSeekBarVisible = false.obs; + RxInt indexForAudios = 0.obs; + RxBool titlePlaying = false.obs; + RxList? titlePlayingList = [].obs; + + addTitles() { + titlePlayingList = List.generate( + pods!.result!.latestPodcast!.length, + (index) => false, + ).obs; + } + + void updateTitlePlaying(int index) { + // Check if the index is within valid range + if (index >= 0 && index < titlePlayingList!.length) { + // Set all values to false + titlePlayingList!.assignAll(List.generate( + titlePlayingList!.length, + (index) => false, + )); + // Set the specified index to true + titlePlayingList![index] = true; + } + } +} + +class PodcastPageManager extends GetxController { + final progressNotifier = ValueNotifier( + ProgressBarState( + current: Duration.zero, + buffered: Duration.zero, + total: Duration.zero, + ), + ); + final buttonNotifier = ValueNotifier(ButtonState.paused); + + late AudioPlayer _audioPlayer; + Visible visibleController = Get.put(Visible()); + + PodcastPageManager() { + init(0); + } + + void init(index) async { + _audioPlayer = AudioPlayer(); + try { + await _audioPlayer.setUrl(pods! + .result!.latestPodcast![index].podcastUrl ?? + 'https://ghantalele.com/uploads/files/data-78/38825/Besharam%20Rang_192(Ghantalele.com).mp3'); + // await _audioPlayer.setAsset(url); + } on PlayerException catch (e) { + print("Error code: ${e.code}"); + // iOS/macOS: maps to NSError.localizedDescription + // Android: maps to ExoPlaybackException.getMessage() + // Web/Linux: a generic message + // Windows: MediaPlayerError.message + print("Error message: ${e.message}"); + } +//Catching errors during playback (e.g. lost network connection) + _audioPlayer.playbackEventStream.listen((event) {}, + onError: (Object e, StackTrace st) { + if (e is PlayerException) { + print('Error code: ${e.code}'); + print('Error message: ${e.message}'); + } else { + print('An error occurred: $e'); + } + }); + + _audioPlayer.playerStateStream.listen((playerState) { + final isPlaying = playerState.playing; + final processingState = playerState.processingState; + if (!isPlaying) { + buttonNotifier.value = ButtonState.paused; + } else if (processingState != ProcessingState.completed) { + buttonNotifier.value = ButtonState.playing; + } else { + _playNextTrack(); + + // _audioPlayer.seek(Duration.zero); + // _audioPlayer.pause(); + } + }); + + _audioPlayer.positionStream.listen((position) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: position, + buffered: oldState.buffered, + total: oldState.total, + ); + }); + + _audioPlayer.bufferedPositionStream.listen((bufferedPosition) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: oldState.current, + buffered: bufferedPosition, + total: oldState.total, + ); + }); + + _audioPlayer.durationStream.listen((totalDuration) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: oldState.current, + buffered: oldState.buffered, + total: totalDuration ?? Duration.zero, + ); + }); + } + + void _playNextTrack() { + // Determine the index of the next track (you need to implement this logic) + int nextIndex = getNextTrackIndex(); + + if (nextIndex != -1) { + // Play the next track + visibleController.updateTitlePlaying(nextIndex); + if (isPlaying()) { + stop(); + } + init(nextIndex); + play(nextIndex); + } else { + _audioPlayer.seek(Duration.zero); + _audioPlayer.pause(); + } + } + + int getNextTrackIndex() { + if (visibleController.indexForAudios.value == + pods!.result!.latestPodcast!.length - 1) { + return -1; + } else { + return visibleController.indexForAudios.value + 1; + } + + // You need to implement this logic based on your playlist structure + // For example, if you have a list of tracks, return the index of the next track + // If there is no next track, return -1 + // This logic depends on how you manage your playlist + // Example: return currentTrackIndex + 1; + } + + void play(index) { + _audioPlayer.play(); + visibleController.isAudioSeekBarVisible.value = false; + visibleController.isAudioSeekBarVisible.value = true; + visibleController.indexForAudios.value = index; + } + + void pause() { + _audioPlayer.pause(); + } + + void seek(Duration position) { + _audioPlayer.seek(position); + } + + void stop() { + _audioPlayer.stop(); + } + + bool isPlaying() { + return _audioPlayer.playing; + } + + // void dispose() { + // super.dispose(); + // _audioPlayer.stop(); + // } +} + +class ProgressBarState { + ProgressBarState({ + required this.current, + required this.buffered, + required this.total, + }); + final Duration current; + final Duration buffered; + final Duration total; +} + +enum ButtonState { paused, playing } diff --git a/gsf/lib/views/pages/podcast/viewModel/PodcastApis.dart b/gsf/lib/views/pages/podcast/viewModel/PodcastApis.dart new file mode 100644 index 0000000..2155e36 --- /dev/null +++ b/gsf/lib/views/pages/podcast/viewModel/PodcastApis.dart @@ -0,0 +1,29 @@ +import 'package:get/get.dart'; +import 'package:gsp_app/api/network_api.dart'; +import 'package:gsp_app/modals/PodcastsModel.dart'; +import 'package:gsp_app/modals/QuizModel.dart'; +import 'package:gsp_app/repository/endpoints.dart'; +import 'package:gsp_app/views/pages/quiz/quiz_home.dart'; + +import '../../../../api/base_manager.dart'; + +PodcastsModel? pods; + +class PodcastApis { + // Future> storePoints(updata) async { + // final response = + // await NetworkApi().postApi(url: Endpoints.storePoints, data: updata); + // if (response.status == ResponseStatus.SUCCESS) { + // showQuizbool = false; + // } + // print("response from store points $response"); + + // return response; + // } + + Future> getPodcasts() async { + final response = await NetworkApi().getApi(Endpoints.getPodcast); + pods = PodcastsModel.fromJson(response.data); + return response; + } +} diff --git a/gsf/lib/views/pages/privacy_policy/privacy_policy.dart b/gsf/lib/views/pages/privacy_policy/privacy_policy.dart new file mode 100644 index 0000000..3522480 --- /dev/null +++ b/gsf/lib/views/pages/privacy_policy/privacy_policy.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class PrivacyPolicy extends StatelessWidget { + const PrivacyPolicy({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Privacy Policy'), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.center, + child: + SvgPicture.asset('assets/image/fitness_regulations.svg')), + const SizedBox(height: 35), + const Text( + 'Privacy Policy', + style: TextStyle( + fontSize: 22, + color: Color(0xff858585), + fontFamily: "SFPRO", + fontWeight: FontWeight.w800, + ), + ), + const SizedBox(height: 20), + const Text( + 'Getsetfit Private Limited (“GetSetFit”) is committed to the protection of personal information provided by the Users to Getsetfit. Users agree that visiting/use of Getsetfit’s website (“Website”) and mobile application (“Mobile App”), or the use of the products and services available thereon, implies consent to the collection, retention and use of Users personal information in accordance with the terms of this Privacy Policy (“Privacy Policy”). Getsetfit takes the privacy of Users seriously. Getsetfit is committed to safeguarding the privacy of Users while providing its Products and Services (as defined in the Terms of Use) in a personalized and valuable manner. No information provided by the User to Getsetfit is rented or sold to any third party. When a User uses the Services, Users’ IP address and other personal information may automatically get stored. A high standard of security is maintained by Getsetfit for Users. However, the transmission of information via the internet and web networks is not completely secure. While Getsetfit does its best to protect Users’ information, particularly with respect to protection of Users’ personal data, Getsetfit cannot ensure the security of Users’ data transmitted via the internet, web network or any other networks. Access to the contents of Getsetfit is conditional upon User’s approval of the Privacy Policy which should be read together with the terms of use of service (“Terms”). Users acknowledge that this Privacy Policy, together with our Terms, forms a legally binding agreement with Getsetfit in relation to the use of Services (“Agreement”). All capitalized terms used but not defined herein shall have the meaning ascribed to such term in the Terms. Getsetfit reserves the right to contact the customer via any mechanisms, not limited to Email, SMS, or phone calls, to solicit feedback of customer\'s experience and to provide any additional services that customer would be eligible for, either as a customer or as a visitor.', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 30), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/SampleChart.dart b/gsf/lib/views/pages/profile/SampleChart.dart new file mode 100644 index 0000000..332a391 --- /dev/null +++ b/gsf/lib/views/pages/profile/SampleChart.dart @@ -0,0 +1,136 @@ +// ignore_for_file: unused_element + +import 'package:flutter/material.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:intl/intl.dart' show DateFormat; + +class SampleChart extends StatefulWidget { + SampleChart({Key? key, this.dateList, this.priceList}) : super(key: key); + + //String lastMonthDate; + List? dateList; + List? priceList; + @override + State createState() => _SampleChartState(); +} + +class _SampleChartState extends State { + late TooltipBehavior _tooltipBehavior; + @override + void initState() { + print("list of date is ${widget.dateList!}"); + // _chartData = getChartData(); + _tooltipBehavior = TooltipBehavior(enable: true); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + + return Scaffold( + body: SizedBox( + height: screenSize.width, + width: screenSize.width, + child: SfCartesianChart( + // title: ChartTitle(text: 'Yearly sales analysis'), + // legend: Legend(isVisible: true), + plotAreaBorderWidth: 0, + tooltipBehavior: _tooltipBehavior, + series: _getDefaultDateTimeSeries(), + primaryXAxis: + DateTimeAxis(majorGridLines: const MajorGridLines(width: 0)), + primaryYAxis: NumericAxis( + // title: AxisTitle(text: "Price"), + labelFormat: '{value}', + // numberFormat: NumberFormat.simpleCurrency(decimalDigits: 0), + ), + ), + ), + ); + } + + List> _getDefaultDateTimeSeries() { + // DateFormat inputFormat = DateFormat('MM/dd/yyyy hh:mm:ss a'); + + //DateTime kk = inputFormat.parse(widget.dateList!.last); + + List> uplist = []; + List dynamicdata = []; + List upDate = []; + for (var i = 0; i < widget.dateList!.length; i++) { + upDate.add(DateFormat("dd-MM-yyyy HH:mm:ss").parse(widget.dateList![i])); + // uplist.add(LineSeries( + // dataSource: [ + // ChartSampleData( + // x: upDate[i], yValue: double.parse(widget.priceList![i])), + // ], + // xValueMapper: (ChartSampleData data, _) => data.x as DateTime, + // yValueMapper: (ChartSampleData data, _) => data.yValue, + // color: const Color.fromRGBO(242, 117, 7, 1), + // ) + // ); + dynamicdata.add( + ChartSampleData( + x: upDate[i], yValue: double.parse(widget.priceList![i])), + ); + } + return >[ + LineSeries( + dataSource: dynamicdata, + xValueMapper: (ChartSampleData data, _) => data.x as DateTime, + yValueMapper: (ChartSampleData data, _) => data.yValue, + color: Color(0xFF8ED34A), + markerSettings: MarkerSettings( + isVisible: true, // Show markers + ), + ) + ]; + } + + // List getChartData() { + // var currentDate = DateTime.now(); + // print("current date is ${currentDate.day}"); + // DateFormat inputFormat = DateFormat('dd/MM/yyyy hh:mm:ss a'); + // DateTime now = inputFormat.parse(widget.lastMonthDate); + + // print("last month date is ${now.day}"); + // for (var i = 0; i < 10; i++) {} + // final List chartData = [ + // SalesData(14, 664.8), + // SalesData(15, 655.1), + // SalesData(16, 642.85), + // SalesData(17, 643.65), + // SalesData(18, 638.85), + // SalesData(19, 627.15), + // SalesData(20, 625.7), + // // SalesData(2024, 23), + // // SalesData(2025, 12), + // // SalesData(2026, 8), + // ]; + // return chartData; + // } +} + +class ChartSampleData { + ChartSampleData({ + required this.x, + required this.yValue, + }); + final DateTime x; + final double yValue; +} + +class _ChartData { + _ChartData(this.x, this.y, this.y2); + final double x; + final double y; + final double y2; +} + +class SalesData { + SalesData(this.year, this.sales, this.numbers); + final DateTime year; + final String sales; + final double numbers; +} diff --git a/gsf/lib/views/pages/profile/basal_metabolism.dart b/gsf/lib/views/pages/profile/basal_metabolism.dart new file mode 100644 index 0000000..31c43fe --- /dev/null +++ b/gsf/lib/views/pages/profile/basal_metabolism.dart @@ -0,0 +1,232 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class BasalMetaBolism extends StatelessWidget { + // final String apiBmr; + const BasalMetaBolism( + { + // required this.apiBmr, + Key? key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + final sliderdotInt = Get.size.width * 0.75; + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: ''), + ), + body: SingleChildScrollView( + child: SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 20), + SvgPicture.asset( + 'assets/image/profileIcons/basal_metabolism.svg'), + const SizedBox(height: 20), + Text( + 'Basal metabolism', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Energy consumed for various activities (breathing, heartbeat, maintaining body temperature, ETC, etc.). It is the energy that is the minimum necessary for survival.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your basal metabolism is ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + children: [ + TextSpan( + text: ' 1515kcal', + style: TextStyle( + fontSize: 22, + color: Color(0xffFFBC04), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '1575kcal', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Low', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff8FD155), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Up to Standard', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + Positioned( + top: -4, + // bottom: 0, + left: sliderdotInt * 0.5, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: const Color(0xffFFBC04), + ), + ), + ), + ) + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'Your basal metabolism level is low. Factors such as increased age, weight loss, drugs, less sympathetic nerve activity, and decreased thyroid gland may all lead to lower primary generation levels. In addition, environmental temperature also affects metabolism. In a comfortable environment (20-25°C), metabolism is the lowest. If the basal metabolism level continues to be too low, please consult a professional doctor in time.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/body_age.dart b/gsf/lib/views/pages/profile/body_age.dart new file mode 100644 index 0000000..095144b --- /dev/null +++ b/gsf/lib/views/pages/profile/body_age.dart @@ -0,0 +1,326 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class BodyAge extends StatefulWidget { + final String bodyAgeApi; + const BodyAge({required this.bodyAgeApi, Key? key}) : super(key: key); + + @override + State createState() => _BodyAgeState(); +} + +class _BodyAgeState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].age!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + final actuallAge = appDataController.age; + + // value from scale + final ageValueScale = (aControllerFind.localAge.value == '- -') + ? '0' + : aControllerFind.localAge.value; + + // value Date wise from API + final ageValueApi = widget.bodyAgeApi; + + // String rangeTxt = ''; + String rangeColor = ''; + // double newBodyage = double.parse(bodyAgeApi); + + var newValueOfAge = + aControllerFind.checDate.value ? ageValueScale : ageValueApi; + + if (double.parse(newValueOfAge) <= double.parse(actuallAge.toString())) { + // rangeTxt = 'Standard'; + rangeColor = '0xff8FD155'; + } else if (double.parse(newValueOfAge) >= + double.parse(actuallAge.toString())) { + // rangeTxt = 'Low'; + rangeColor = '0xFFF44336'; + } + + // if (((aControllerFind.checDate.value == true) + // ? aControllerFind.localAge.value + // : newValuesss) >= + // 0 && + // ((aControllerFind.checDate.value == true) + // ? double.parse(newMuscle) + // : newValuesss) <= + // 60.00) { + // rangeTxt = 'Low'; + // rangeColor = '0xFFF44336'; + // } else if (((aControllerFind.checDate.value == true) + // ? double.parse(newMuscle) + // : newValuesss) > + // 60.00 && + // ((aControllerFind.checDate.value == true) + // ? double.parse(newMuscle) + // : newValuesss) <= + // 74.00) { + // rangeTxt = 'Standard'; + // rangeColor = '0xff8FD155'; + // } else if (((aControllerFind.checDate.value == true) + // ? double.parse(newMuscle) + // : newValuesss) > + // 74.00 && + // ((aControllerFind.checDate.value == true) + // ? double.parse(newMuscle) + // : newValuesss) <= + // 100) { + // rangeTxt = 'Excellent'; + // rangeColor = '0xFF8ED34A'; + // } + + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/body_age.svg'), + const SizedBox(height: 20), + Text( + 'Body Age', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Body age is calculated by looking at your BMR. Once your BMR starts to show improvement, the body age will also show improvement', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 22, vertical: 25), + child: Column( + children: [ + RichText( + text: TextSpan( + text: 'Your body age ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: + ' ${aControllerFind.checDate.value ? ageValueScale : ageValueApi} years old', + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 35), + Text( + 'Your body is too old, please strengthen exercise, pay attention to a healthy diet, and maintain a reasonable schedule.', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w500, + ), + ) + ], + ), + ), + ), + // Spacer(), + + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = { + "created_at": "", + "data": "month" + }; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return allDatesData!.authorisation!.userData!.isEmpty + ? SizedBox( + height: 100, + child: Center(child: Text("No Data Found"))) + : SizedBox( + height: 300, + width: Get.width, + child: + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + ); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/body_fat.dart b/gsf/lib/views/pages/profile/body_fat.dart new file mode 100644 index 0000000..19951a2 --- /dev/null +++ b/gsf/lib/views/pages/profile/body_fat.dart @@ -0,0 +1,710 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../api/base_manager.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class BodyFat extends StatefulWidget { + final String bFat; + const BodyFat({required this.bFat, Key? key}) : super(key: key); + + @override + State createState() => _BodyFatState(); +} + +class _BodyFatState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].bodyFat!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + // final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + + final bFatValueScale = (aControllerFind.localbodyFat.value == '- -') + ? '0' + : aControllerFind.localbodyFat.value; + + // value Date wise from API + double newValuesss = + double.parse(widget.bFat.toString().replaceAll('%', '')); + + // final newBFatValue = (aControllerFind.checDate.value == true) + // ? double.parse(bFatValueScale) + // : newValuesss; + + final gender = appDataController.gender; + + String rangeTxt = ''; + String rangeColor = ''; + bool first = false; + bool second = false; + bool third = false; + bool four = false; + String desc = ''; + + final newBFat = (aControllerFind.localbodyFat.value == '- -') + ? '0.0' + : aControllerFind.localbodyFat.value; + + final newBFatValue = (aControllerFind.checDate.value == true) + ? double.parse(newBFat) + : newValuesss; + + if (gender == 'male') { + if (newBFatValue >= 0 && newBFatValue <= 10.00) { + rangeTxt = 'Low'; + rangeColor = '0xFFF44336'; + first = true; + second = false; + third = false; + four = false; + } else if (newBFatValue > 10.00 && newBFatValue <= 21.00) { + rangeTxt = 'Standard'; + log('Standard'); + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + four = false; + } else if (newBFatValue > 21.00 && newBFatValue <= 26) { + rangeTxt = 'High'; + log('High'); + rangeColor = '0xFF8ED34A'; + first = false; + second = false; + third = true; + four = false; + } else if (newBFatValue > 26.00 && newBFatValue <= 100) { + rangeTxt = 'Too High'; + log('Too High'); + rangeColor = '0xFFF44336'; + first = false; + second = false; + third = false; + four = true; + } + } else if (gender == 'female') { + if (newBFatValue >= 0 && newBFatValue <= 16.00) { + rangeTxt = + (aControllerFind.localbodyFat.value == '- -') ? '- -' : 'Low'; + rangeColor = '0xFFF44336'; + log('low'); + log('AAAAA First'); + first = true; + second = false; + third = false; + four = false; + } else if (newBFatValue > 16.00 && newBFatValue <= 24.00) { + rangeTxt = 'Standard'; + log('Standard'); + rangeColor = '0xffFFFE00'; + first = false; + log('AAAAA second'); + second = true; + third = false; + four = false; + } else if (newBFatValue > 24.00 && newBFatValue <= 30) { + rangeTxt = 'High'; + log('High'); + rangeColor = '0xFF8ED34A'; + log('AAAAA third'); + first = false; + second = false; + third = true; + four = false; + } else if (newBFatValue > 30.00 && newBFatValue <= 100.00) { + rangeTxt = 'Too High'; + rangeColor = '0xFFF44336'; + first = false; + log('AAAAA four'); + second = false; + third = true; + four = false; + } + } + // log('newBFatValue ${newBFatValue}'); + + // first range calcultaion -start + rangeSliderCalulation(startRange, endRnage) { + double mainValue = double.parse(newBFatValue.toString()); + log('MainVALUE Main $mainValue'); + + double rangeValue = endRnage - startRange.toDouble(); + log('MainVALUE rangeValue $rangeValue'); + + double dividedValue = 100 / rangeValue; + log('MainVALUE DIVIDED VALUE $dividedValue'); + + double remaivalue = mainValue - startRange; + log('MainVALUE DIVIDED Value ${remaivalue}'); + + double finalSliderValue = remaivalue * dividedValue; + log('MainVALUE DIVIDED Value FINAL RANGE VALUE 1 $finalSliderValue'); + return finalSliderValue.toDouble(); + } + + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/bodyFat.svg'), + const SizedBox(height: 20), + Text( + 'Body fat', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Did you know? You can be overweight and yet healthier with a lower fat mass and higher muscles mass. \n\nWhen you fall, FAT cells give the cushion\nFAT makes your hormones function better \nFAT protects your brain health\n\nFAT is good\nBut too much of anything is not good!', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your body fat mass is ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: newBFatValue.toString(), + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + const Spacer(), + Text( + '${(gender == 'male') ? 10 : 16}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + Text( + '${(gender == 'male') ? 21 : 24}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + Text( + '${(gender == 'male') ? 26 : 30}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Builder( + builder: (context) { + // log('rang slider calculation ${rangeSliderCalulation(20, 22)}'); + return Row( + children: [ + Expanded( + // flex: 1, + child: LayoutBuilder( + builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 0 : 0, + (gender == 'male') ? 10 : 16); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: + const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Low', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: first, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color( + int.parse(rangeColor)), + ), + ), + ), + ), + ), + ], + ); + }, + )), + Expanded( + // flex: 1, + child: LayoutBuilder( + builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 11 : 17, + (gender == 'male') ? 21 : 24); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: + const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFFE00), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: second, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion, + + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color( + int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }, + )), + Expanded( + // flex: 1, + child: LayoutBuilder( + builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 22 : 25, + (gender == 'male') ? 26 : 30); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: + const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFC000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'High', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: third, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color( + int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }, + )), + Expanded( + // flex: 1, + child: LayoutBuilder( + builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 27 : 31, + (gender == 'male') ? 100 : 100); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: + const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Too High', + style: TextStyle( + fontSize: 12, + color: (brightness == + Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: four, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color( + int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }, + )), + ], + ); + }, + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'It’s important to get closer to standard BODY FAT range.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = { + "created_at": "", + "data": "month" + }; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder>( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return allDatesData!.authorisation!.userData!.isEmpty + ? SizedBox( + height: 100, + child: Center(child: Text("No Data Found"))) + : SizedBox( + height: 300, + width: Get.width, + child: + + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + ); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/body_type.dart b/gsf/lib/views/pages/profile/body_type.dart new file mode 100644 index 0000000..7639b11 --- /dev/null +++ b/gsf/lib/views/pages/profile/body_type.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class BodyType extends StatelessWidget { + const BodyType({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/idealWeight.svg'), + const SizedBox(height: 20), + Text( + 'Ideal Weight', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'An ideal weight is the perfect weight for you according to your height and metabolism. This is the weight that helps you maintain a healthy body fat percentage and hormonal levels. It is also easy to sustain without making any drastic changes to your diet.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 22, vertical: 25), + child: RichText( + text: TextSpan( + text: 'Your idea weight ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: ' 63.50kg', + style: TextStyle( + fontSize: 22, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/bone_mass.dart b/gsf/lib/views/pages/profile/bone_mass.dart new file mode 100644 index 0000000..1d6af70 --- /dev/null +++ b/gsf/lib/views/pages/profile/bone_mass.dart @@ -0,0 +1,598 @@ +// ignore_for_file: unrelated_type_equality_checks + +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/api/StreamEnum.dart'; +import 'package:gsp_app/modals/BioscalOverviewForallDates.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class BoneMass extends StatefulWidget { + final String skeletalMuscleApi; + const BoneMass({required this.skeletalMuscleApi, Key? key}) : super(key: key); + + @override + State createState() => _BoneMassState(); +} + +class _BoneMassState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].skeletalMuscle!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + // final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + + // value from scale + final double skeletalMuscle = double.parse( + (aControllerFind.localSkeletalRate.value == '- -') + ? '0' + : aControllerFind.localSkeletalRate.value); + print('newBoneMassValue scale data ${skeletalMuscle}'); + // double skeletalMusclePercentage = skeletalMuscle / 100; + + // value Date wise from API + double skeletalMuscleApiParse = + double.parse(widget.skeletalMuscleApi.toString().replaceAll('%', '')); + // var skeletalMuscleApiParseInPercentage = skeletalMuscleApiParse / 100; + print('newBoneMassValue api data ${skeletalMuscleApiParse}'); + + // color calculations + final gender = appDataController.gender; + // String rangeTxt = ''; + String rangeColor = ''; + bool first = false; + bool second = false; + bool third = false; + + final newSkeletalMuscle = (aControllerFind.localSkeletalRate.value == '- -') + ? '0.0' + : aControllerFind.localSkeletalRate.value; + + final newBoneMassValue = (aControllerFind.checDate.value) + ? double.parse(newSkeletalMuscle) + : skeletalMuscleApiParse; + + if (gender == 'male') { + if ((newBoneMassValue) >= 0 && (newBoneMassValue) <= 40.00) { + // rangeTxt = 'Low'; + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + } else if ((newBoneMassValue) > 40.00 && (newBoneMassValue) <= 60.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + } else if ((newBoneMassValue) > 60.00 && (newBoneMassValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + } + } else if (gender == 'female') { + if ((newBoneMassValue) >= 0.00 && (newBoneMassValue) <= 30.00) { + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + // print('Cahunga frist'); + } else if ((newBoneMassValue) > 30.00 && (newBoneMassValue) <= 50.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + // print('Cahunga second'); + } else if ((newBoneMassValue) > 50.00 && (newBoneMassValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + // print('Cahunga third'); + } + } + + // first range calcultaion -start + rangeSliderCalulation(start, end) { + double mainValue = double.parse(newBoneMassValue.toString()); + + double rangeValue = end - start.toDouble(); + + double dividedValue = 100 / rangeValue; + // print('DIVIDED VALUE $dividedValue'); + + double remaivalue = mainValue - start; + // print('DIVIDED Value ${remaivalue}'); + + double finalSliderValue = remaivalue * dividedValue; + // print('DIVIDED Value FINAL RANGE VALUE $finalSliderValue'); + return finalSliderValue.toDouble(); + } + + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/bone_mass.svg'), + const SizedBox(height: 20), + Text( + 'Bone Mass', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'These are attached to bones by tendons and are responsible for voluntary movements like walking, running, and lifting objects. So more the skeletal muscles the easier it is to move around and do day to day things. ', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your bone mass is ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: + '${aControllerFind.checDate.value ? skeletalMuscle.toString() : skeletalMuscleApiParse.toString()}%', + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + // const Spacer(), + const Expanded(flex: 4, child: SizedBox()), + Text( + '${(gender == 'male') ? 40 : 30}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + // const Spacer(), + const Expanded(flex: 2, child: SizedBox()), + Text( + '${(gender == 'male') ? 60 : 50}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Expanded(flex: 4, child: SizedBox()), + // const Spacer(), + ], + ), + const SizedBox(height: 5), + Row( + children: [ + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 0 : 0, + (gender == 'male') ? 40 : 30); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: first, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ), + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 41 : 31, + (gender == 'male') ? 60 : 50); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFFE00), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: second, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 61 : 51, + (gender == 'male') ? 100 : 100); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff8FD155), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'excellent', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: third, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'Try to stay in or beyond the standard range.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = { + "created_at": "", + "data": "month" + }; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return allDatesData!.authorisation!.userData!.isEmpty + ? SizedBox( + height: 100, + child: Center(child: Text("No Data Found"))) + : SizedBox( + height: 300, + width: Get.width, + child: + + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + ); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/chart/user_dashboard_chart.dart b/gsf/lib/views/pages/profile/chart/user_dashboard_chart.dart new file mode 100644 index 0000000..c2b6d23 --- /dev/null +++ b/gsf/lib/views/pages/profile/chart/user_dashboard_chart.dart @@ -0,0 +1,206 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; + +import '../../../../view_model/global_controller.dart'; + +class GraphDataModel { + final int index; + final String xAxisLabel; + final double yAxisValue; + + const GraphDataModel({ + required this.index, + required this.xAxisLabel, + required this.yAxisValue, + }); +} + +class DashboardChart extends StatelessWidget { + final double yAxisMaxValue; + final List graphElements; + + const DashboardChart({ + required this.yAxisMaxValue, + required this.graphElements, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return BarChart( + BarChartData( + barTouchData: barTouchData, + titlesData: titlesData(graphElements), + borderData: FlBorderData(show: false), + barGroups: graphElements + .map((graphElement) => BarChartGroupData( + x: graphElement.index, + barRods: [ + BarChartRodData( + width: 14, + toY: graphElement.yAxisValue, + gradient: _barsGradient, + ), + ], + showingTooltipIndicators: [0], + )) + .toList(), + gridData: FlGridData(show: false), + alignment: BarChartAlignment.spaceAround, + maxY: yAxisMaxValue, + ), + ); + } + + FlTitlesData titlesData(List graphElements) => FlTitlesData( + show: true, + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 30, + getTitlesWidget: (double value, TitleMeta meta) { + return SideTitleWidget( + axisSide: meta.axisSide, + space: 4, + child: Text( + graphElements[value.toInt()].xAxisLabel, + style: const TextStyle( + color: Color(0xff7589a2), + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + ); + }, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ); + + List get barGroups => [ + BarChartGroupData( + x: 0, + barRods: [ + BarChartRodData( + width: 14, + toY: 8, + gradient: _barsGradient, + ), + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 1, + barRods: [ + BarChartRodData( + width: 14, + toY: 10, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 2, + barRods: [ + BarChartRodData( + width: 14, + toY: 14, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 3, + barRods: [ + BarChartRodData( + width: 14, + toY: 15, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 4, + barRods: [ + BarChartRodData( + width: 14, + toY: 13, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 5, + barRods: [ + BarChartRodData( + width: 14, + toY: 10, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + BarChartGroupData( + x: 6, + barRods: [ + BarChartRodData( + width: 14, + toY: 16, + gradient: _barsGradient, + ) + ], + showingTooltipIndicators: [0], + ), + ]; + + BarTouchData get barTouchData { + GlobalController globalController = Get.find(); + return BarTouchData( + enabled: false, + touchTooltipData: BarTouchTooltipData( + tooltipBgColor: Colors.transparent, + tooltipPadding: EdgeInsets.zero, + tooltipMargin: 8, + getTooltipItem: ( + BarChartGroupData group, + int groupIndex, + BarChartRodData rod, + int rodIndex, + ) { + return BarTooltipItem( + rod.toY.round().toString(), + TextStyle( + color: !globalController.darkMode.value?ColorConstants.kBlack:Colors.white, + fontWeight: FontWeight.bold, + ), + ); + }, + ), + ); + } + + + + LinearGradient get _barsGradient => const LinearGradient( + colors: [ + Colors.lightBlueAccent, + Colors.greenAccent, + ], + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + ); +} diff --git a/gsf/lib/views/pages/profile/fat_index.dart b/gsf/lib/views/pages/profile/fat_index.dart new file mode 100644 index 0000000..d8b55f4 --- /dev/null +++ b/gsf/lib/views/pages/profile/fat_index.dart @@ -0,0 +1,259 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class FatIndex extends StatelessWidget { + const FatIndex({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/image/profileIcons/subcutaneous.jpg', + width: 94, + height: 94, + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 20), + Text( + 'Visceral Fat Index', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'The visceral fat level reflects the degree of abdominal visceral fat accumulation. Maintaining a standard visceral fat index can greatly reduce the risk of heart disease, high', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your visceral fat index is ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + children: [ + TextSpan( + text: ' 10', + style: TextStyle( + fontSize: 22, + color: Color(0xffFFBC04), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '8.6%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + Text( + '16.7%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff1CCB9A), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFBC04), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Alert', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Danger', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + Positioned( + top: -4, + // bottom: 0, + left: sliderdotInt * 0.45, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: const Color(0xffFFBC04), + ), + ), + ), + ) + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'High visceral fat is the root cause of obesity. Exercise more and eat more dietary fiber food.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/fat_mass.dart b/gsf/lib/views/pages/profile/fat_mass.dart new file mode 100644 index 0000000..36adb74 --- /dev/null +++ b/gsf/lib/views/pages/profile/fat_mass.dart @@ -0,0 +1,255 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class FatMass extends StatelessWidget { + const FatMass({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/image/profileIcons/subcutaneous.jpg', + width: 94, + height: 94, + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 20), + Text( + 'Subcutaneous Fat Mass', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Subcutaneous fat is the fat stored between the skin and muscle. It acts as a cushion to prevent external stimuli, such as cold and vibration If there is too much subcutaneous fat, it will in.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your subcutaneous fat rate ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: ' 11.30kg', + style: TextStyle( + fontSize: 22, + color: ColorConstants.kErroColor, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '5.9kg', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + Spacer(), + Text( + '11.40kg', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFBC04), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w600, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff10D49A), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w600, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Too Much', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w600, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + Positioned( + top: -4, + // bottom: 0, + left: sliderdotInt * 0.7, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: const Color(0xffFFBC04), + ), + ), + ), + ) + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'Your fat content is worthy of vigilance, you need to pay attention to your diet and strengthen exercise.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/fat_rate.dart b/gsf/lib/views/pages/profile/fat_rate.dart new file mode 100644 index 0000000..500d775 --- /dev/null +++ b/gsf/lib/views/pages/profile/fat_rate.dart @@ -0,0 +1,255 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class FatRate extends StatelessWidget { + const FatRate({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/image/profileIcons/subcutaneous.jpg', + width: 94, + height: 94, + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 20), + Text( + 'Subcutaneous Fat Rate', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Subcutaneous fat is the fat stored between the skin and muscle. It acts as a cushion to prevent external stimuli, such as cold and vibration If there is too much subcutaneous fat, it will in.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your subcutaneous fat rate ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: ' 18.0%', + style: TextStyle( + fontSize: 22, + color: ColorConstants.kErroColor, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '8.6%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + Spacer(), + Text( + '16.7%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFBC04), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff10D49A), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Too Much', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + Positioned( + top: -4, + // bottom: 0, + left: sliderdotInt * 0.7, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: const Color(0xffFFBC04), + ), + ), + ), + ) + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'Your fat content is worthy of vigilance, you need to pay attention to your diet and strengthen exercise.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/ideal_weight.dart b/gsf/lib/views/pages/profile/ideal_weight.dart new file mode 100644 index 0000000..dfe8a78 --- /dev/null +++ b/gsf/lib/views/pages/profile/ideal_weight.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class IdealWeight extends StatelessWidget { + const IdealWeight({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/idealWeight.svg'), + const SizedBox(height: 20), + Text( + 'Ideal Weight', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'An ideal weight is the perfect weight for you according to your height and metabolism. This is the weight that helps you maintain a healthy body fat percentage and hormonal levels. It is also easy to sustain without making any drastic changes to your diet.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 22, vertical: 25), + child: RichText( + text: TextSpan( + text: 'Your idea weight ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: ' 63.50kg', + style: TextStyle( + fontSize: 22, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/lean_body_mass.dart b/gsf/lib/views/pages/profile/lean_body_mass.dart new file mode 100644 index 0000000..7020a61 --- /dev/null +++ b/gsf/lib/views/pages/profile/lean_body_mass.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class LeanBodyMass extends StatelessWidget { + const LeanBodyMass({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/lean_body.svg'), + const SizedBox(height: 20), + Text( + 'Lean body mass', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Weight after removing fat.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 22, vertical: 25), + child: RichText( + text: TextSpan( + text: 'Weight after removing fat. ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: ' 54.50kg', + style: TextStyle( + fontSize: 22, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + // Spacer(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/moisture.dart b/gsf/lib/views/pages/profile/moisture.dart new file mode 100644 index 0000000..90df74b --- /dev/null +++ b/gsf/lib/views/pages/profile/moisture.dart @@ -0,0 +1,586 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class Moisture extends StatefulWidget { + final String water; + const Moisture({required this.water, Key? key}) : super(key: key); + + @override + State createState() => _MoistureState(); +} + +class _MoistureState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].water!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + + // value from scale + final double waterScale = double.parse( + (aControllerFind.localWater.value == '- -') + ? '0' + : aControllerFind.localWater.value); + double wterInPercentageScale = 100.0 / 100; + // waterScale / 100; + print('WATER waterApi scale $wterInPercentageScale'); + + // value Date wise from API + double waterApi = double.parse(widget.water.toString().replaceAll('%', '')); + var waterInPercentageApi = waterApi / 100; + print('WATER waterApi $waterApi'); + + final gender = appDataController.gender; + // String rangeTxt = ''; + String rangeColor = ''; + bool first = false; + bool second = false; + bool third = false; + + final newWater = (aControllerFind.localWater.value == '- -') + ? '0.0' + : aControllerFind.localWater.value; + + final newWaterValue = + (aControllerFind.checDate.value) ? double.parse(newWater) : waterApi; + + if (gender == 'male') { + if ((newWaterValue) >= 0.00 && (newWaterValue) <= 55.00) { + // rangeTxt = 'Low'; + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + } else if ((newWaterValue) > 55.00 && (newWaterValue) <= 65.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + } else if ((newWaterValue) > 65.00 && (newWaterValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + } + } else if (gender == 'female') { + if ((newWaterValue) >= 0.00 && (newWaterValue) <= 45.00) { + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + } else if ((newWaterValue) > 45.00 && (newWaterValue) <= 60.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + } else if ((newWaterValue) > 60.00 && (newWaterValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + } + } + + // first range calcultaion -start + rangeSliderCalulation(start, end) { + double mainValue = double.parse(newWaterValue.toString()); + + double rangeValue = end - start.toDouble(); + + double dividedValue = 100 / rangeValue; + // print('DIVIDED VALUE $dividedValue'); + + double remaivalue = mainValue - start; + // print('DIVIDED Value ${remaivalue}'); + + double finalSliderValue = remaivalue * dividedValue; + // print('DIVIDED Value FINAL RANGE VALUE $finalSliderValue'); + return finalSliderValue.toDouble(); + } + + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/moisture.svg'), + const SizedBox(height: 20), + Text( + 'Moisture', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Hydration is key to digestion, blood circulation, body temperature regulation, cell function and weight management.\n\nSo drop the phone and sip some water. ', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your moisture is ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: + '${aControllerFind.checDate.value ? waterScale.toString() : waterApi.toString()}%', + // ' ${waterScale}%', + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + const Spacer(), + Text( + '${(gender == 'male') ? 55 : 45}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + Text( + '${(gender == 'male') ? 65 : 60}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9)), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Row( + children: [ + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 0 : 0, + (gender == 'male') ? 55 : 45); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: first, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ), + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 56 : 46, + (gender == 'male') ? 65 : 60); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFFE00), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: second, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 66 : 61, + (gender == 'male') ? 100 : 100); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff8FD155), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'excellent', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: third, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + 'If your urine colour is yellow it means you’re dehydrated. Sip some water immediately ', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = { + "created_at": "", + "data": "month" + }; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return allDatesData!.authorisation!.userData!.isEmpty + ? SizedBox( + height: 100, + child: Center(child: Text("No Data Found"))) + : SizedBox( + height: 300, + width: Get.width, + child: + + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + ); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/muscle_rate.dart b/gsf/lib/views/pages/profile/muscle_rate.dart new file mode 100644 index 0000000..5aa5a9f --- /dev/null +++ b/gsf/lib/views/pages/profile/muscle_rate.dart @@ -0,0 +1,567 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, unrelated_type_equality_checks + +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class MuscleRate extends StatefulWidget { + final String mrValueDateWise; + const MuscleRate({required this.mrValueDateWise, Key? key}) : super(key: key); + + @override + State createState() => _MuscleRateState(); +} + +class _MuscleRateState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].muscleRate!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + // final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + + final double mrValueScale = double.parse( + (aControllerFind.localMusclerate.value == '- -') + ? '0' + : aControllerFind.localMusclerate.value); + + // value Date wise from API + double newValuesss = + double.parse(widget.mrValueDateWise.toString().replaceAll('%', '')); + + final gender = appDataController.gender; + + String rangeTxt = ''; + String rangeColor = ''; + bool first = false; + bool second = false; + bool third = false; + String desc = ''; + + final newMuscle = (aControllerFind.localMusclerate.value == '- -') + ? '0.0' + : aControllerFind.localMusclerate.value; + + final newMrValue = (aControllerFind.checDate.value == true) + ? double.parse(newMuscle) + : newValuesss; + + if (gender == 'male') { + if (newMrValue >= 0 && newMrValue <= 60.00) { + rangeTxt = 'Low'; + rangeColor = '0xFFF44336'; + first = true; + second = false; + third = false; + desc = 'Buddy we need to put on some muscle. Let’s go strength train. '; + } else if (newMrValue > 60.00 && newMrValue <= 74.00) { + rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + desc = + 'Your muscle range is standard, which is better than insufficient and less better than excellent.'; + } else if (newMrValue > 74.00 && newMrValue <= 100) { + rangeTxt = 'Excellent'; + rangeColor = '0xFF8ED34A'; + first = false; + second = false; + third = true; + desc = + 'Your muscle range is excellent, continue with whatever you are doing. '; + } + } else if (gender == 'female') { + if (newMrValue >= 0 && newMrValue <= 56.00) { + rangeTxt = + (aControllerFind.localMusclerate.value == '- -') ? '- -' : 'Low'; + rangeColor = '0xFFF44336'; + first = true; + second = false; + third = false; + desc = 'Buddy we need to put on some muscle. Let’s go strength train. '; + } else if (newMrValue > 56.00 && newMrValue <= 70.00) { + rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + desc = + 'Your muscle range is standard, which is better than insufficient and less better than excellent.'; + } else if (newMrValue > 70.00 && newMrValue <= 100) { + rangeTxt = 'Excellent'; + rangeColor = '0xFF8ED34A'; + first = false; + second = false; + third = true; + desc = + 'Your muscle range is excellent, continue with whatever you are doing. '; + } + } + + // range calcultaion - starts + rangeSliderCalulation(start, end) { + double mainValue = double.parse(newMrValue.toString()); + + double rangeValue = end - start.toDouble(); + + double dividedValue = 100 / rangeValue; + // print('DIVIDED VALUE $dividedValue'); + + double remaivalue = mainValue - start; + // print('DIVIDED Value ${remaivalue}'); + + double finalSliderValue = remaivalue * dividedValue; + print('DIVIDED Value FINAL RANGE VALUE $finalSliderValue'); + return finalSliderValue.toDouble(); + } + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/muscle_rate.svg'), + const SizedBox(height: 20), + Text( + 'Muscle Rate', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Do you want a faster metabolism? Stronger bones? Improved insulin sensitivity? Better posture? Live longer? Build muscles my friend. As the coach says “lift heavier” and you will look prettier not bulkier. ', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400, + ), + ), + const SizedBox(height: 30), + Container( + // height: 128, + // width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your muscle rate ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + children: [ + TextSpan( + text: newMrValue.toString(), + // (mrValuePercenategDateWise.toString() ?? + // mrValueScale.toString()), + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '${(gender == 'male') ? 60 : 56}%', + // '72.3%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + Spacer(), + Text( + '${(gender == 'male') ? 74 : 70}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Row( + children: [ + Expanded( + flex: 4, + child: Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: first, + child: Positioned( + top: -4, + // bottom: 0, + left: rangeSliderCalulation( + (gender == 'male') ? 0 : 0, + (gender == 'male') ? 60 : 56), + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ), + ], + ), + ), + Expanded( + flex: 4, + child: Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFFE00), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: second, + child: Positioned( + top: -4, + // bottom: 0, + left: rangeSliderCalulation( + (gender == 'male') ? 61 : 57, + (gender == 'male') ? 74 : 70), + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ), + ), + Expanded( + flex: 4, + child: Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff8FD155), + borderRadius: BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'excellent', + style: TextStyle( + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: third, + child: Positioned( + top: -4, + // bottom: 0, + left: rangeSliderCalulation( + (gender == 'male') ? 75 : 71, + (gender == 'male') ? 100 : 100), + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ), + ), + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + desc, + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ], + ), + ), + ), + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = {"created_at": "", "data": "month"}; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return SizedBox( + height: 300, + width: Get.width, + child: SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + // SampleChart( + // // lastMonthDate: priceData.table!.first.date!, + // dateList: dateList, + // priceList: priceList, + // ), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/pages/SampleChart2.dart b/gsf/lib/views/pages/profile/pages/SampleChart2.dart new file mode 100644 index 0000000..196d8a8 --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/SampleChart2.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; + +// ignore: must_be_immutable +class ColumnChartSample extends StatefulWidget { + ColumnChartSample({Key? key, this.dateList, this.priceList}) + : super(key: key); + + List? dateList; + List? priceList; + @override + State createState() => _ColumnChartSampleState(); +} + +class _ColumnChartSampleState extends State { + late TooltipBehavior _tooltipBehavior; + + @override + void initState() { + print("list of date is ${widget.dateList!}"); + // _chartData = getChartData(); + _tooltipBehavior = TooltipBehavior(enable: true); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: SfCartesianChart( + tooltipBehavior: _tooltipBehavior, + primaryXAxis: DateTimeCategoryAxis(), + primaryYAxis: NumericAxis(), + series: _getDefaultDateTimeSeries() + + // >[ + + // ColumnSeries<_ChartData, DateTime>( + // dataSource: chartData, + // xValueMapper: (_ChartData data, _) => data.date, + // yValueMapper: (_ChartData data, _) => data.value, + // width: 0.3, + // color: Color(0xFF8ED34A)), + // ], + ), + ), + ); + } + + List> _getDefaultDateTimeSeries() { + // DateFormat inputFormat = DateFormat('MM/dd/yyyy hh:mm:ss a'); + + //DateTime kk = inputFormat.parse(widget.dateList!.last); + + List<_ChartData> dynamicdata = []; + List upDate = []; + for (var i = 0; i < widget.dateList!.length; i++) { + upDate.add(DateFormat("dd-MM-yyyy HH:mm:ss").parse(widget.dateList![i])); + // uplist.add(LineSeries( + // dataSource: [ + // ChartSampleData( + // x: upDate[i], yValue: double.parse(widget.priceList![i])), + // ], + // xValueMapper: (ChartSampleData data, _) => data.x as DateTime, + // yValueMapper: (ChartSampleData data, _) => data.yValue, + // color: const Color.fromRGBO(242, 117, 7, 1), + // ) + // ); + dynamicdata.add( + _ChartData(upDate[i], double.parse(widget.priceList![i])), + ); + } + return >[ + // Use ColumnSeries instead of BarSeries + ColumnSeries<_ChartData, DateTime>( + dataSource: dynamicdata, + xValueMapper: (_ChartData data, _) => data.date, + yValueMapper: (_ChartData data, _) => data.value, + width: 0.3, + color: Color(0xFF8ED34A)), + ]; + } +} + +class _ChartData { + _ChartData(this.date, this.value); + final DateTime date; + final double value; +} + +List<_ChartData> chartData = [ + _ChartData(DateTime(2023, 10, 1), 25), + _ChartData(DateTime(2023, 10, 2), 40), + _ChartData(DateTime(2023, 10, 3), 60), + _ChartData(DateTime(2023, 10, 4), 30), +]; diff --git a/gsf/lib/views/pages/profile/pages/company_profile.dart b/gsf/lib/views/pages/profile/pages/company_profile.dart new file mode 100644 index 0000000..1b2ca27 --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/company_profile.dart @@ -0,0 +1,277 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../components/appbar.dart'; +import '../../../components/leaderboard_element.dart'; +import '../../../components/mood_meter.dart'; +import '../../../theme.dart'; + +class CompanyProfile extends StatefulWidget { + const CompanyProfile({Key? key}) : super(key: key); + + @override + State createState() => _CompanyProfileState(); +} + +class _CompanyProfileState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Company Profile'), + ), + body: Align( + alignment: Alignment.topCenter, + child: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 15), + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + Container( + decoration: const BoxDecoration( + color: Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 2, + ), + shape: BoxShape.circle, + ), + child: Image.asset( + "assets/image/avatar.png", + fit: BoxFit.fill, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 4), + Text( + "WDIPL", + style: QuizTextStyles.heading, + ), + Text( + "Mumbai", + style: QuizTextStyles.heading, + ), + const SizedBox(height: 24), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "About WDIPL", + style: QuizTextStyles.heading.copyWith(fontSize: 20), + ), + ), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "I am a lead business analyst at WDIPL and have a busy day. GSF has helped me implement small workouts into my lifestyle. I am also more conscious about my water intake and the GSF app reminds me every time I need to take a sip of water", + style: QuizTextStyles.body.copyWith(fontSize: 14), + ), + ), + ), + const SizedBox(height: 18), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Table( + border: TableBorder.all( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + ), + children: [ + TableRow(children: [ + Container( + decoration: const BoxDecoration( + border: Border( + right: BorderSide(color: Colors.white), + ), + ), + height: 54, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.people_alt_rounded, + color: Colors.white, + ), + SizedBox(width: 4), + Text( + "300+", + style: QuizTextStyles.heading, + ) + ], + ), + ), + SizedBox( + height: 54, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.location_on_outlined, + color: Colors.white, + ), + SizedBox(width: 4), + Text( + "Mumbai", + style: QuizTextStyles.heading, + ) + ], + ), + ), + ]), + TableRow(children: [ + Container( + decoration: const BoxDecoration( + border: Border( + right: BorderSide(color: Colors.white), + ), + ), + height: 54, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.flag_outlined, + color: Colors.white, + ), + SizedBox(width: 4), + Text( + "2001", + style: QuizTextStyles.heading, + ) + ], + ), + ), + SizedBox( + height: 54, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.public, + color: Colors.white, + ), + SizedBox(width: 6), + Text( + "IT-Sector", + style: QuizTextStyles.heading, + ) + ], + ), + ), + ]), + ], + ), + ), + const SizedBox(height: 42), + Padding( + padding: EdgeInsets.symmetric(horizontal: 22.0), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "Mood O Meter", + style: QuizTextStyles.heading, + ), + ), + ), + const SizedBox(height: 16), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 22.0), + child: MoodOMeter(), + ), + const SizedBox(height: 42), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Row( + children: [ + Expanded( + child: Text( + "WDI Leaderboard", + style: QuizTextStyles.heading, + )), + Icon( + Icons.navigate_next_rounded, + color: Colors.white, + ) + ], + ), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Column( + children: leaderboardJson + .map( + (e) => LeaderboardElement( + id: e["id"], + rank: e["rank"], + points: e["points"], + leaderboardArrowIconPath: + e["leaderboardArrowIconPath"], + imgPath: e["imgPath"], + userName: e["userName"], + ), + ) + .toList(), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22.0), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "WDI Champs", + style: QuizTextStyles.heading, + ), + ), + ), + const SizedBox(height: 12), + SizedBox( + height: 120, + child: ListView.builder( + itemCount: 20, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: SizedBox( + width: 160, + child: Image.asset( + 'assets/image/activity.png', + width: Get.width * 0.9, + fit: BoxFit.cover, + ), + ), + ), + ), + ), + ), + const SizedBox(height: 12), + ], + ), + ), + )); + } +} diff --git a/gsf/lib/views/pages/profile/pages/edit_profile.dart b/gsf/lib/views/pages/profile/pages/edit_profile.dart new file mode 100644 index 0000000..d692bc0 --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/edit_profile.dart @@ -0,0 +1,1455 @@ +// ignore_for_file: must_be_immutable + +import 'dart:io'; + +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; + +import '../../../components/appbar.dart'; +import '../../../components/btn.dart'; +import '../../../components/const.dart'; +import '../../../../modals/edit_profile_model.dart'; +import '../../../../repository/services/complete_profile_service.dart'; +import '../../../../repository/services/edit_profile_service.dart'; +import '../../../theme.dart'; + +class EditProfile extends StatefulWidget { + EditProfile({ + Key? key, + this.fromUserProfile = false, + }) : super(key: key); + + bool fromUserProfile; + + @override + State createState() => _EditProfileState(); +} + +class _EditProfileState extends State { + final CompleteProfileController completeProfileController = + Get.put(CompleteProfileController(), permanent: true); + final EditProfileController getProfileDatas = + Get.put(EditProfileController()); + GlobalKey formKey = GlobalKey(); + final List items = [ + 'male', + 'female', + ]; + final box = GetStorage(); + + String? selectedValue; + + String assetImgPath = ""; + + @override + Widget build(BuildContext context) { + print( + 'isFileNetwork bool value ${completeProfileController.isFileNetwork.value}'); + print( + 'profile image path value ${completeProfileController.selectedImagePath.value}'); + final brightness = Get.theme.brightness; + return WillPopScope( + child: Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'Edit Profilesss', + editProfileFromUserProfile: true, + ), + ), + body: GestureDetector( + onTap: () => FocusManager.instance.primaryFocus?.unfocus(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 22), + child: Align( + alignment: Alignment.topCenter, + child: SingleChildScrollView( + child: FutureBuilder( + future: getProfileDatas.fetchUserData(), + builder: (context, snapshot) { + // print('fetchdata ${snapshot}'); + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // setState(() {}); + var value = snapshot.data!; + getProfileDatas.nameController.value.text = + value.fullName; + getProfileDatas.bioController.value.text = value.userBio; + getProfileDatas.ageController.value.text = value.age; + getProfileDatas.phoneNumberController.value.text = + value.contactNumber; + getProfileDatas.emailProfileController.value.text = + value.emailId; + getProfileDatas.fullAdrsessController.value.text = + value.fullAddress; + getProfileDatas.cityController.value.text = value.city; + getProfileDatas.heightController.value.text = + value.height; + getProfileDatas.weightController.value.text = + value.weight; + selectedValue = value.gender; + completeProfileController.selectedImagePath.value = + value.profilePicture ?? ''; + debugPrint( + "completeProfileController.selectedImagePath.value: ${completeProfileController.selectedImagePath.value}"); + debugPrint( + "value.profilePicture ${value.profilePicture}"); + + return Column( + children: [ + const SizedBox(height: 15), + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + Container( + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: + // Obx( + // () => + Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 1, + ), + shape: BoxShape.circle, + ), + // child: completeProfileController + // .selectedImagePath.value == + // '' + // ? Image.asset( + // "assets/image/avatar.png", + // fit: BoxFit.cover, + // ) + // : + child: ClipRRect( + borderRadius: + BorderRadius.circular( + 100, + ), + child: assetImgPath.isNotEmpty + ? Image.file( + File(assetImgPath), + fit: BoxFit.cover, + ) + : Image.network( + completeProfileController + .selectedImagePath + .value, + fit: BoxFit.cover, + )) + /* + ClipRRect( + borderRadius: BorderRadius.circular( + 100, + ), + child: FlutterLogo() + // completeProfileController + // .isFileNetwork.value + // ? Image.network( + // completeProfileController + // .selectedImagePath.value, + // fit: BoxFit.cover, + // ) + // : Image.file( + // File( + // completeProfileController + // .selectedImagePath.value, + // ), + // width: 50, + // height: 50, + // fit: BoxFit.cover, + // ), + // child: + ), + */ + ), + ), + // ), + ), + // GestureDetector( + // onTap: () => Get.to(const CompanyProfile()), + // child: + // Image.asset("assets/image/badges/wdi_badge.png")), + Positioned( + right: -8, + top: 38, + child: GestureDetector( + onTap: () => modaBottomSheets(), + child: Container( + width: 32, + height: 32, + decoration: const BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.camera_alt_rounded, + size: 18, + color: Color.fromARGB(255, 82, 82, 82), + ), + ), + ), + ) + ], + ), + const SizedBox(height: 4), + Text( + '${value.fullName}', + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + Text( + '${value.city}', + textAlign: TextAlign.center, + style: QuizTextStyles.heading.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + // Text( + // "Global Ranking-15", + // textAlign: TextAlign.center, + // style: QuizTextStyles.heading.copyWith( + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite), + // ), + const SizedBox(height: 24), + // Container( + // height: 48, + // width: 242, + // color: Colors.transparent, + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Expanded( + // child: Row( + // children: [ + // Expanded( + // child: InkWell( + // onTap: () => Get.to(const BadgesPage()), + // child: Column( + // children: [ + // const SizedBox(height: 3), + // Row( + // mainAxisAlignment: + // MainAxisAlignment.center, + // children: [ + // SvgPicture.asset( + // 'assets/image/profile/crown.svg', + // width: 14, + // height: 14, + // ), + // const SizedBox(width: 8), + // SvgPicture.asset( + // 'assets/image/profile/dumbell.svg', + // width: 14, + // height: 14, + // ), + // const SizedBox(width: 8), + // SvgPicture.asset( + // 'assets/image/profile/runner.svg', + // width: 14, + // height: 14, + // ), + // ], + // ), + // const SizedBox(height: 3), + // const Text("My Badges", + // style: QuizTextStyles.heading), + // ], + // ), + // ), + // ), + // const VerticalDivider( + // color: Colors.white, + // width: 2, + // thickness: 2, + // ), + // Expanded( + // child: Column( + // children: const [ + // Text("0", style: QuizTextStyles.heading), + // Text("Days Streak", + // style: QuizTextStyles.heading), + // ], + // ), + // ) + // ], + // ), + // ), + // const Divider( + // color: Colors.white, + // thickness: 2, + // height: 2, + // ) + // ], + // ), + // ), + + const SizedBox(height: 42), + Form( + key: formKey, + child: Obx( + () => Column( + children: [ + //name + Align( + alignment: Alignment.centerLeft, + child: Text( + "Name", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // enabled: false, + // initialValue: '${SignInData.name}', + controller: + getProfileDatas.nameController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Name'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Bio + Align( + alignment: Alignment.centerLeft, + child: Text( + "Bio", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // controller: , + controller: + getProfileDatas.bioController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + minLines: 4, + maxLines: 8, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Name'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Gender + Align( + alignment: Alignment.centerLeft, + child: Text( + "Gender", + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + const SizedBox(height: 6), + StatefulBuilder( + builder: (context, setDropdown) { + return DropdownButtonFormField2( + hint: Text( + "Please select the gender", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + isExpanded: true, + items: items + .map((item) => + DropdownMenuItem( + value: item, + child: Padding( + padding: + const EdgeInsets.only( + left: 0.0, + top: 0, + bottom: 0), + child: Text( + item, + style: QuizTextStyles.body + .copyWith( + color: (brightness == + Brightness.light) + ? ColorConstants + .kBlack + : ColorConstants + .kWhite, + fontSize: 16, + fontWeight: + FontWeight.w500, + ), + overflow: + TextOverflow.ellipsis, + ), + ), + )) + .toList(), + autovalidateMode: + AutovalidateMode.onUserInteraction, + validator: (value) { + if (value == null) { + return 'Please select gender.'; + } + return null; + }, + value: selectedValue, + onChanged: (value) { + setDropdown(() { + selectedValue = value.toString(); + EditProfileData.gender = + selectedValue; + }); + }, + onSaved: (value) { + setDropdown(() { + selectedValue = value.toString(); + }); + }, + decoration: const InputDecoration( + border: InputBorder.none), + iconStyleData: const IconStyleData( + icon: Icon( + Icons.arrow_drop_down_rounded, + size: 32), + iconSize: 14, + // iconEnabledColor: Colors.yellow, + iconDisabledColor: Colors.grey, + ), + buttonStyleData: ButtonStyleData( + height: 58, + padding: + const EdgeInsets.only(right: 8), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(12), + color: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: Border.all( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + dropdownStyleData: DropdownStyleData( + elevation: 8, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(12), + color: + (brightness == Brightness.light) + ? Colors.white + : const Color(0xff212121), + ), + offset: const Offset(0, 1), + ), + menuItemStyleData: + const MenuItemStyleData( + height: 40, + padding: EdgeInsets.only( + left: 14, right: 14), + ), + ); + }), + const SizedBox(height: 18), + //age + Align( + alignment: Alignment.centerLeft, + child: Text( + "Age", + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: + getProfileDatas.ageController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.number, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your age'; + } + return null; + }, + ), + const SizedBox(height: 18), + //phone number + Align( + alignment: Alignment.centerLeft, + child: Text( + "Phone Number", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // enabled: false, + controller: getProfileDatas + .phoneNumberController.value, + // initialValue: '${SignInData.mobileNumber}', + keyboardType: TextInputType.number, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Phone Number'; + } + return null; + }, + ), + const SizedBox(height: 18), + //email + Align( + alignment: Alignment.centerLeft, + child: Text( + "Email", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + enabled: false, + // initialValue: '${SignInData.emailId}', + controller: getProfileDatas + .emailProfileController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Email'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Full Address + Align( + alignment: Alignment.centerLeft, + child: Text( + "Full Address", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: getProfileDatas + .fullAdrsessController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Address'; + } + return null; + }, + ), + const SizedBox(height: 18), + //City + Align( + alignment: Alignment.centerLeft, + child: Text( + "City", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: + getProfileDatas.cityController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your city name'; + } + return null; + }, + ), + const SizedBox(height: 18), + //height + Align( + alignment: Alignment.centerLeft, + child: Text( + "Height(in cm)", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: + getProfileDatas.heightController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.number, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your height'; + } + + double height; + try { + height = double.parse(value); + } catch (e) { + return 'Please enter a valid number'; + } + + if (height < 120 || height > 250) { + return '120 cm to 250 cm'; + } + + return null; // Return null to indicate that the input is valid + }, + ), + const SizedBox(height: 18), + //weight + Align( + alignment: Alignment.centerLeft, + child: Text( + "Weight(in kg)", + style: QuizTextStyles.body.copyWith( + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: + getProfileDatas.weightController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.number, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: + (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: + (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your weight'; + } + return null; + }, + ), + const SizedBox(height: 18), + FullWdtBtn( + btnText: "Done", + onTap: () { + Get.focusScope!.unfocus(); + if (formKey.currentState!.validate()) { + // formKey.currentState!.save(); + // debugPrint(getProfileDatas + // .nameController.value.text); + // debugPrint(completeProfileController + // .bioController.value.text); + // debugPrint(selectedValue); + // debugPrint(completeProfileController + // .ageController.value.text); + // debugPrint(completeProfileController + // .phoneNumberController.value.text); + // debugPrint(completeProfileController + // .emailController.value.text); + // debugPrint(completeProfileController + // .fullAdrsessController.value.text); + // debugPrint(completeProfileController + // .cityController.value.text); + // debugPrint(completeProfileController + // .heightController.value.text); + // debugPrint(completeProfileController + // .weightController.value.text); + + getProfileDatas + .postEditProfileData( + genderValue: selectedValue, + imgPath: assetImgPath) + .then((value) { + // completeProfileController + // .isFileNetwork.value = true; + // setState(() {}); + }); + completeProfileController + .selectedImagePath + .value = value.profilePicture ?? ''; + debugPrint( + ' final calue of selected path value image ${completeProfileController.selectedImagePath.value}'); + } + // Get.to( + // () => const HomePage(), + // ); + }, + ), + const SizedBox(height: 18), + ], + ), + ), + ), + const SizedBox(height: 18), + ], + ); + } + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + CircularProgressIndicator(), + ], + ), + ); + }, + ), + ), + ), + ), + ), + ), + onWillPop: () { + Get.off(const HomePage()); + return Future.value(false); + }, + ); + } + + modaBottomSheets() { + final brightness = Theme.of(context).brightness; + // final controller = Get.find(completeProfileController()); + return Get.bottomSheet( + Padding( + padding: const EdgeInsets.only( + top: 0.0, bottom: 30.0, right: 20.0, left: 20.0), + child: Container( + decoration: BoxDecoration( + color: (brightness == Brightness.dark) + ? const Color(0xff1C1C1C) + : const Color(0xffcccccc), + borderRadius: BorderRadius.circular(20), + ), + // height: 250, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 30), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Add Photo', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff) + : const Color(0xff000000), + ), + ), + const SizedBox( + height: 20, + ), + Divider( + thickness: 1, + height: 1, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff).withOpacity(0.5) + : const Color(0xff000000).withOpacity(0.5), + ), + spacing(), + InkWell( + onTap: () async { + // print( + // 'image path1 ${completeProfileController.selectedImagePath.value}'); + // completeProfileController.getImage(ImageSource.camera); + // print( + // 'image path2 ${completeProfileController.selectedImagePath.value}'); + // Navigator.of(context).pop(); + // Get.back(); + final pickedFile = await ImagePicker() + .pickImage(source: ImageSource.camera); + if (pickedFile != null) { + final cropImageFile = await ImageCropper().cropImage( + sourcePath: pickedFile.path, + maxWidth: 512, + maxHeight: 512, + compressFormat: ImageCompressFormat.jpg, + compressQuality: 100, + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'Cropper', + toolbarColor: ColorConstants.kPrimaryColor, + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: false, + activeControlsWidgetColor: + ColorConstants.kPrimaryColor, + ), + IOSUiSettings( + title: 'Cropper', + ), + ], + ); + if (cropImageFile != null) { + Get.back(); + // debugPrint("cropImageFile ${cropImageFile.path}"); + setState(() { + assetImgPath = cropImageFile.path; + }); + } + } + }, + child: Text( + 'Camera', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff) + : const Color(0xff000000), + ), + ), + ), + spacing(), + Divider( + thickness: 1, + height: 1, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff).withOpacity(0.5) + : const Color(0xff000000).withOpacity(0.5), + ), + spacing(), + InkWell( + onTap: () { + completeProfileController.getImage(ImageSource.gallery); + // Navigator.of(context).pop(); + // Get.back(); + }, + child: Text( + 'Gallery', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff) + : const Color(0xff000000), + ), + ), + ), + spacing(), + Divider( + thickness: 1, + height: 1, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff).withOpacity(0.5) + : const Color(0xff000000).withOpacity(0.5), + ), + spacing(), + InkWell( + onTap: () { + // Navigator.pop(context); + // Navigator.of(context).pop(); + Get.back(); + // controller.onClose(); + }, + child: Text( + 'Cancel', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.dark) + ? const Color(0xffffffff) + : const Color(0xff000000), + ), + ), + ), + // spacing(), + ], + ), + ), + ), + ), + ); + } + + spacing() { + return const SizedBox( + height: 15, + ); + } +} diff --git a/gsf/lib/views/pages/profile/pages/profile_page.dart b/gsf/lib/views/pages/profile/pages/profile_page.dart new file mode 100644 index 0000000..9ffe739 --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/profile_page.dart @@ -0,0 +1,329 @@ +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:skeletons/skeletons.dart'; + +import '../../../../modals/user_dashboard_chart_model.dart'; +import '../../../../repository/response_data.dart'; +import '../../../../repository/services/cj/leader_board_ranking.dart'; +import '../../../../repository/services/cj/user_dashboard_chart_service.dart'; +import '../../../components/appbar.dart'; +import '../../../components/bottom_navigation.dart'; +import '../../../../view_model/bottom_navigation_controller.dart'; +import '../../../../modals/edit_profile_model.dart'; +import '../../../../repository/services/complete_profile_service.dart'; +import '../../../../repository/services/edit_profile_service.dart'; +import '../../../../repository/services/view_profile_services.dart'; +import '../../../theme.dart'; +import '../../../components/custom_skeleton.dart'; +import 'user_dashboard.dart'; +import 'user_profile.dart'; + +import 'package:async/async.dart'; + +class ProfilePage extends StatefulWidget { + const ProfilePage({Key? key}) : super(key: key); + + @override + State createState() => _ProfilePageState(); +} + +class _ProfilePageState extends State + with TickerProviderStateMixin { + late AnimationController _animationController; + final ViewProfileController getProfileDatas = + Get.put(ViewProfileController()); + + GlobalController globalController = Get.find(); + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 600), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + ); + RankingLeaderboard().setLeaderBoardRankYearlyPositions(); + } + + @override + Widget build(BuildContext context) { + _animationController.forward(); + // final brightness = Get.theme.brightness; + + TabController tabController = TabController(length: 2, vsync: this); + return Scaffold( + // backgroundColor: ColorConstants.kWhite, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + showLeading: true, + titleHead: 'Profile', + // rightAction: IconButton( + // onPressed: () {}, + // icon: Container( + // decoration: const BoxDecoration( + // color: Color(0xff333333), + // shape: BoxShape.circle, + // ), + // child: SvgPicture.asset("assets/image/share.svg")), + // ), + ), + ), + body: AnimatedBuilder( + child: Column( + children: [ + const SizedBox(height: 12), + Obx( + () => Padding( + padding: const EdgeInsets.symmetric(horizontal: 58.0), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff2B2B2B), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ], + borderRadius: BorderRadius.circular(28), + ), + child: TabBar( + isScrollable: false, + labelPadding: EdgeInsets.symmetric( + horizontal: Get.size.width * 0.0, + ), + labelColor: !globalController.darkMode.value + ? ColorConstants.kPrimaryColor + : ColorConstants.kBlack, + unselectedLabelColor: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + labelStyle: const TextStyle( + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontSize: 13, + ), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + ), + indicator: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + borderRadius: BorderRadius.circular(50), + ), + controller: tabController, + tabs: const [ + Tab( + text: 'Edit Profile', + ), + Tab( + text: 'My Profile', + ), + ], + ), + ), + ], + ), + ), + ), + const SizedBox(height: 12), + Expanded( + child: TabBarView( + controller: tabController, + children: [ + // FutureBuilder( + // future: UserDashboardChartService().userDashboardChart(), + // builder: (context, snapshot) { + // if(snapshot.connectionState == ConnectionState.done && snapshot.hasData){ + // UserDashboardChartModel data = snapshot.data!.data; + // return Padding( + // padding: const EdgeInsets.only(right: 12), + // child: DashboardChart( + // yAxisMaxValue: 19 + 4, + // graphElements: initialGraphElements, + // ), + // ); + // } + + // },) + const UserProfile(), + FutureBuilder( + future: UserDashboardChartService().userDashboardChart(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + UserDashboardChartModel data = snapshot.data!.data; + // print('New all data ${data}'); + return UserDashboard(data: data); + } + + return userProfileSkeleton(); + }, + ), + ], + )), + /* + Expanded( + child: FutureBuilder( + future: getProfileDatas.fetchUserData(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + return TabBarView( + controller: tabController, + children: [ + UserProfile(editProfileModel: snapshot.data!), + UserDashboard(editProfileModel: snapshot.data!), + ], + ); + } + return const ProfileSkeleton(); + }, + ), + ), + */ + ], + ), + animation: _animationController, + builder: (context, child) => FadeScaleTransition( + animation: _animationController, + child: child, + ), + ), + // bottomNavigationBar: const BottomNavigation( + // // three: BottomNavigationController.three, + // // four: BottomNavigationController.four, + // // five: BottomNavigationController.five, + // // six: BottomNavigationController.six, + // // seven: BottomNavigationController.seven, + // ), + ); + } + + userProfileSkeleton() { + return ListView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + children: [ + const SizedBox(height: 20), + Align( + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: 120, + height: 120, + borderRadius: BorderRadius.circular(100), + ), + ), + ), + const SizedBox(height: 5), + SkeletonParagraph( + style: SkeletonParagraphStyle( + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 8), + lines: 2, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: false, + width: 130, + height: 12, + borderRadius: BorderRadius.circular(8), + alignment: Alignment.center), + ), + ), + const SizedBox(height: 50), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width - 40, + height: 190, + borderRadius: BorderRadius.circular(10), + ), + ), + const SizedBox(height: 20), + SkeletonParagraph( + style: SkeletonParagraphStyle( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + lines: 1, + spacing: 10, + lineStyle: SkeletonLineStyle( + randomLength: false, + width: 190, + height: 12, + borderRadius: BorderRadius.circular(8), + // alignment: Alignment.center + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 7, + height: Get.width / 7, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 7, + height: Get.width / 7, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 7, + height: Get.width / 7, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 7, + height: Get.width / 7, + borderRadius: BorderRadius.circular(100), + ), + ), + SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width / 7, + height: Get.width / 7, + borderRadius: BorderRadius.circular(100), + ), + ), + ], + ), + ), + ], + ); + } + + @override + void dispose() { + super.dispose(); + _animationController.dispose(); + } +} diff --git a/gsf/lib/views/pages/profile/pages/user_dashboard.dart b/gsf/lib/views/pages/profile/pages/user_dashboard.dart new file mode 100644 index 0000000..7152745 --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/user_dashboard.dart @@ -0,0 +1,582 @@ +// ignore_for_file: must_be_immutable + +import 'dart:async'; +import 'dart:developer'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/view_model/StepcountController.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:gsp_app/views/pages/Sessions/count_me.dart'; +import 'package:gsp_app/views/pages/StepCount/HealthApp.dart'; +import 'package:gsp_app/views/pages/home/home.dart'; +import 'package:health/health.dart'; +import 'package:pedometer/pedometer.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:skeletons/skeletons.dart'; + +import '../../../../modals/upcoming_session_model.dart'; +import '../../../../modals/user_dashboard_chart_model.dart'; +import '../../../../repository/services/cj/upcoming_activity_service.dart'; +import '../../../../view_model/global_controller.dart'; +import '../../../components/mood_meter.dart'; +import '../../../../view_model/home_page_controller.dart'; +import '../../../components/upcoming_session.dart'; +import '../../../theme.dart'; +import '../chart/user_dashboard_chart.dart'; + +class UserDashboard extends StatefulWidget { + UserDashboardChartModel data; + UserDashboard({Key? key, required this.data}) : super(key: key); + + @override + State createState() => _UserDashboardState(); +} + +HomePageController homePageController = Get.put(HomePageController()); + +class _UserDashboardState extends State { + // late UserDashboardChartModel newData; + // late List> graphSets; // Move the declaration here + late UserDashboardChartModel newData; + late List> graphSets; + late List initialGraphElements; + + AppDataController appDataController = Get.find(); + GlobalController globalController = Get.find(); + + Timer? _timer; + StepCountController stepController = Get.put(StepCountController()); + + @override + void initState() { + super.initState(); + newData = widget.data; + graphSets = [ + [ + GraphDataModel( + index: 0, + xAxisLabel: "Jan", + yAxisValue: (newData.monthlyData[0].position == null) + ? 0 + : newData.monthlyData[0].position), + GraphDataModel( + index: 1, + xAxisLabel: "Feb", + yAxisValue: (newData.monthlyData[1].position == null) + ? 0 + : newData.monthlyData[1].position), + GraphDataModel( + index: 2, + xAxisLabel: "Mar", + yAxisValue: (newData.monthlyData[2].position == null) + ? 0 + : newData.monthlyData[2].position), + GraphDataModel( + index: 3, + xAxisLabel: "Apr", + yAxisValue: (newData.monthlyData[3].position == null) + ? 0 + : newData.monthlyData[3].position), + GraphDataModel( + index: 4, + xAxisLabel: "May", + yAxisValue: (newData.monthlyData[4].position == null) + ? 0 + : newData.monthlyData[4].position), + GraphDataModel( + index: 5, + xAxisLabel: "Jun", + yAxisValue: (newData.monthlyData[5].position == null) + ? 0 + : newData.monthlyData[5].position), + ], + [ + GraphDataModel( + index: 0, + xAxisLabel: "Jul", + yAxisValue: (newData.monthlyData[6].position == null) + ? 0 + : newData.monthlyData[6].position), + GraphDataModel( + index: 1, + xAxisLabel: "Aug", + yAxisValue: (newData.monthlyData[7].position == null) + ? 0 + : newData.monthlyData[7].position), + GraphDataModel( + index: 2, + xAxisLabel: "Sep", + yAxisValue: (newData.monthlyData[8].position == null) + ? 0 + : newData.monthlyData[8].position), + GraphDataModel( + index: 3, + xAxisLabel: "Oct", + yAxisValue: (newData.monthlyData[9].position == null) + ? 0 + : newData.monthlyData[9].position), + GraphDataModel( + index: 4, + xAxisLabel: "Nov", + yAxisValue: (newData.monthlyData[10].position == null) + ? 0 + : newData.monthlyData[10].position), + GraphDataModel( + index: 5, + xAxisLabel: "Dec", + yAxisValue: (newData.monthlyData[11].position == null) + ? 0 + : newData.monthlyData[11].position), + ], + ]; + + // if (Platform.isIOS) { + // _startTimer(); + // } + + // if (Platform.isAndroid) { + // permissionDialog(); + // getStepCountFromStorage(); + // checkAndUpdateDate(); + // } + + calculateButtonLogin(); + } + + // permissionDialog() async { + // Map statuses = await [ + // Permission.activityRecognition, + // ].request(); + // if (statuses[Permission.activityRecognition]!.isGranted) { + // initPlatformState(); + // } + // } + + // void _startTimer() { + // _timer = Timer.periodic(const Duration(seconds: 2), (timer) { + // stepscontroller.fetchStepData(); + // }); + // } + + @override + void dispose() { + _timer?.cancel(); // Cancel the Timer if it is not null + super.dispose(); + } + + bool? showGraphNextBtn; + bool? showGraphPrevBtn; + final calculateStepsFromHealthApp stepscontroller = + Get.put(calculateStepsFromHealthApp()); + late Stream _stepCountStream; + + calculateButtonLogin() { + DateTime currentDate = DateTime.now(); + int currentMonth = currentDate.month; + + if (currentMonth <= 6) { + showGraphNextBtn = true; + showGraphPrevBtn = false; + initialGraphElements = graphSets[0]; + } else { + showGraphNextBtn = false; + showGraphPrevBtn = true; + initialGraphElements = graphSets[1]; + } + } + + @override + Widget build(BuildContext context) { + // print('widget.data.monthlyData ${widget.data.monthlyData[1].position}'); + // Highest position of the month + List newAdd = []; + List newDataofPosition = + widget.data.monthlyData.where((item) => item.position != null).toList(); + // log('newDataofPosition $newDataofPosition'); + for (var element in newDataofPosition) { + newAdd.add(element.position); + } + // print('New Data of Lists $newAdd'); + // var highestPositionRank = newAdd.reduce( + // (currentMax, element) => currentMax > element ? currentMax : element, + // ); + + var highestPositionRank = newAdd.isNotEmpty + ? newAdd.reduce( + (currentMax, element) => + currentMax > element ? currentMax : element, + ) + : 0.0; // You can set a default value or null when the list is empty + // print('highestPositionRank $highestPositionRank'); + + // print(" null data ${newDataofPosition}"); + + // dynamic maxValue = newDataofPosition.reduce((currentMax, element) => currentMax > element ? currentMax : element); + // log(maxValue); + + // final brightness = Get.theme.brightness; + return SingleChildScrollView( + child: Obx( + () => Column( + children: [ + const SizedBox(height: 15), + Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 106, + height: 106, + decoration: const BoxDecoration( + color: Color(0xff212121), + // border: Border.all( + // color: Colors.green, + // width: 1, + // ), + shape: BoxShape.circle, + ), + child: + // Obx( + // () => + Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 2, + ), + shape: BoxShape.circle, + ), + child: appDataController.profilePicUrl.value.isEmpty + ? const Icon( + Icons.person_rounded, + size: 36, + color: Colors.white, + ) + : CircleAvatar( + backgroundImage: NetworkImage( + correctImgUrl( + appDataController.profilePicUrl.value), + ), + backgroundColor: Colors.transparent, + ), + // ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: FlutterLogo() + // Image.network( + // widget.editProfileModel.profilePicture!, + // fit: BoxFit.cover, + // ), + // ) + + // (completeProfileController.isFileNetwork.value == + // true) + // ? ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: Image.network( + // completeProfileController + // .selectedImagePath.value, + // // height: 50, + // // width: 50, + // fit: BoxFit.cover, + // ), + // ) + // : ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: Image.file( + // File( + // completeProfileController + // .selectedImagePath.value, + // ), + // // width: 50, + // // height: 50, + // fit: BoxFit.cover, + // ), + // ), + ), + // ), + ), + ), + ), + // GestureDetector( + // onTap: () => Get.to(() => const CompanyProfile()), + // child: Image.asset("assets/image/badges/wdi_badge.png"), + // ) + ], + ), + const SizedBox(height: 9), + Text( + appDataController.name.value, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + Text( + appDataController.city.value, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + // const SizedBox(height: 12), + const SizedBox(height: 34), + StatefulBuilder( + builder: (context, setGraphState) => Container( + margin: const EdgeInsets.symmetric(horizontal: 22), + padding: const EdgeInsets.all(8), + height: 190, + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 4, + spreadRadius: 5, + ) + ]), + child: Row(children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "You are at", + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 18, + ), + ), + Text( + '${appDataController.selfPosition.value}', + style: const TextStyle( + color: Colors.yellow, + fontSize: 48, + fontWeight: FontWeight.bold, + ), + ), + Text( + "Global", + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 18, + ), + ), + //garph nav btns + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + //PREV BTN + Visibility( + visible: showGraphPrevBtn!, + child: GestureDetector( + onTap: () { + setGraphState(() { + showGraphPrevBtn = false; + showGraphNextBtn = true; + if (initialGraphElements == graphSets[1]) { + initialGraphElements = graphSets[0]; + } + }); + }, + child: const RotatedBox( + quarterTurns: 2, + child: Icon( + Icons.play_arrow_outlined, + size: 30, + color: Colors.yellow, + )), + ), + ), + //NEXT BTN + Visibility( + visible: showGraphNextBtn!, + child: GestureDetector( + onTap: () { + setGraphState(() { + showGraphPrevBtn = true; + showGraphNextBtn = false; + if (initialGraphElements == graphSets[0]) { + initialGraphElements = graphSets[1]; + } + }); + }, + child: const Icon( + Icons.play_arrow_outlined, + size: 30, + color: Colors.yellow, + ), + ), + ) + ], + ) + ], + )), + //graph + Expanded( + flex: 2, + child: Padding( + padding: const EdgeInsets.only(right: 12), + child: DashboardChart( + yAxisMaxValue: highestPositionRank + 7, + graphElements: initialGraphElements, + ), + )), + ]), + ), + ), + const SizedBox(height: 34), + Padding( + padding: const EdgeInsets.only(left: 22), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "Mood O Meter", + textAlign: TextAlign.start, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + ), + const SizedBox(height: 8), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 22), + child: MoodOMeter(), + ), + const SizedBox(height: 28), + + Padding( + padding: const EdgeInsets.only(left: 22), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "Foot Steps", + textAlign: TextAlign.start, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + ), + const SizedBox( + height: 20, + ), + if (Platform.isAndroid) + Obx( + () => Padding( + padding: const EdgeInsets.only(left: 22), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + stepController.appStepCountGlobal.value.toString(), + textAlign: TextAlign.start, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + ), + ), + if (Platform.isIOS) + Obx( + () => stepscontroller.finalSteps.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(left: 22), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + stepscontroller.finalSteps.value, + textAlign: TextAlign.start, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + ) + : Padding( + padding: const EdgeInsets.only(left: 22), + child: Align( + alignment: Alignment.centerLeft, + child: ElevatedButton.icon( + onPressed: () { + stepscontroller.fetchStepData(); + }, + icon: const Icon( + Icons.replay_outlined, + color: Colors.black, + ), + label: Text("Fetch step count"), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + Color(0xFFBBF046)), + ), + ), + ), + ), + ), + + const SizedBox(height: 24), + InkWell( + onTap: () {}, + child: Row( + children: [ + const SizedBox(width: 22), + Expanded( + child: Text( + "Upcoming Activities", + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + InkWell( + onTap: () { + HomePageController.SessionsActiveTabIndex = 1; + homePageController.updateBottomNavIndex(1); + }, + child: const Icon( + Icons.navigate_next_rounded, + color: Colors.white, + ), + ), + const SizedBox(width: 22), + ], + ), + ), + const SizedBox(height: 16), + const UpcomingSession(), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/pages/user_profile.dart b/gsf/lib/views/pages/profile/pages/user_profile.dart new file mode 100644 index 0000000..4bb587e --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/user_profile.dart @@ -0,0 +1,505 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/views/pages/signIn/complete_profile_before_sign_in.dart'; +import '../../../../view_model/global_controller.dart'; +import '../../../theme.dart'; +import '../../home/home.dart'; + +class UserProfile extends StatefulWidget { + // final String groupLevel; + const UserProfile({ + Key? key, + //required this.groupLevel, + }) : super(key: key); + // final EditProfileModel editProfileModel; + + @override + State createState() => _UserProfileState(); +} + +class _UserProfileState extends State { + final box = GetStorage(); + GlobalController globalController = Get.find(); + + // final ViewProfileController getProfileDatas = + // Get.put(ViewProfileController()); + // final CompleteProfileController completeProfileController = + // Get.put(CompleteProfileController(), permanent: true); + + // @override + // void initState() { + // super.initState(); + // } + + AppDataController appDataController = Get.find(); + + @override + Widget build(BuildContext context) { + // print('user profil image ${widget.editProfileModel.profilePicture}'); + // print( + // 'isFileNetwork value ${completeProfileController.isFileNetwork.value}'); + + // final brightness = Get.theme.brightness; + return Center( + child: SingleChildScrollView( + child: Obx( + () => Column( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + Container( + height: 72 + 264, + ), + Container( + height: 264, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.2) + : const Color(0xff212121), + ), + Container( + height: 234, + width: double.infinity, + padding: const EdgeInsets.only( + left: 32, + right: 32, + top: 32, + bottom: 16, + ), + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0) + : const Color(0xff212121), + child: Column( + children: [ + Text( + appDataController.name.value, + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + Text( + "${groupLevelNameGlobal}", + style: QuizTextStyles.label.copyWith( + fontWeight: FontWeight.w400, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + const SizedBox(height: 20), + Container( + height: 38, + decoration: ShapeDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0) + : const Color(0xff171616), + shape: StadiumBorder( + side: BorderSide( + color: Color(0xffBBF046), + ), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "${appDataController.selfPosition.value}", + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffBBF046)), + ), + const SizedBox(width: 6), + Text( + "Global Ranking", + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white), + ), + ], + ), + ), + const SizedBox(height: 20), + Expanded( + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + // const SizedBox(height: 18), + Row( + children: [ + SvgPicture.asset( + "assets/image/profile/location.svg", + ), + const SizedBox(width: 8), + Text( + appDataController.city.value, + style: TextStyle( + fontSize: 12, + color: + !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ) + ], + ), + const SizedBox(height: 4), + Row( + children: [ + SvgPicture.asset( + "assets/image/profile/gender.svg", + ), + const SizedBox(width: 8), + Text( + appDataController.gender.value, + style: TextStyle( + fontSize: 12, + color: + !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ) + ], + ), + ])), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + // Container( + // height: 38, + // decoration: ShapeDecoration( + // color: !globalController.darkMode.value + // ? ColorConstants.kWhite + // : Color(0xff171616), + // shape: StadiumBorder( + // side: BorderSide( + // color: Color(0xffBBF046), + // ), + // ), + // ), + // child: Row( + // mainAxisAlignment: + // MainAxisAlignment.center, + // children: [ + // Text( + // "0", + // style: TextStyle( + // color: (brightness == + // Brightness.light) + // ? ColorConstants.kBlack + // : Color(0xffBBF046)), + // ), + // SizedBox(width: 6), + // Text( + // "Days Streak", + // style: TextStyle( + // color: (brightness == + // Brightness.light) + // ? ColorConstants.kBlack + // : Colors.white), + // ), + // ], + // ), + // ), + // const SizedBox(height: 18), + Row( + children: [ + SvgPicture.asset( + "assets/image/profile/age.svg", + ), + const SizedBox(width: 8), + Text( + "${appDataController.age.value} Year Old", + style: TextStyle( + fontSize: 12, + color: + !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ) + ], + ), + // Row( + // children: [ + // SvgPicture.asset( + // "assets/image/profile/call.svg", + // ), + // const SizedBox(width: 8), + // const Text( + // "9303982588", + // style: TextStyle( + // fontSize: 12, + // color: Colors.white, + // ), + // ) + // ], + // ), + // const SizedBox(height: 4), + // Row( + // children: [ + // SvgPicture.asset( + // "assets/image/profile/mail.svg", + // ), + // const SizedBox(width: 8), + // const Text( + // "kartikey123@gmail.com", + // overflow: TextOverflow.ellipsis, + // style: TextStyle( + // fontSize: 12, + // color: Colors.white, + // ), + // maxLines: 1, + // ) + // ], + // ), + const SizedBox(height: 4), + Row( + children: [ + SvgPicture.asset( + "assets/image/profile/height.svg", + ), + const SizedBox(width: 8), + Text( + "${appDataController.height.value}cm", + style: TextStyle( + fontSize: 12, + color: + !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ) + ], + ), + ])), + ], + ), + ), + ], + ), + ), + Positioned( + top: 12, + child: Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: + // Obx( + // () => + GestureDetector( + onTap: () => Get.to( + () => const CompleteProfileBeforeSignIn( + editProfile: true), + ), + child: Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 2, + ), + shape: BoxShape.circle, + ), + child: appDataController.profilePicUrl.value.isEmpty + ? const Icon( + Icons.person_rounded, + size: 36, + color: Colors.white, + ) + : CircleAvatar( + backgroundImage: NetworkImage( + correctImgUrl( + appDataController.profilePicUrl.value), + ), + backgroundColor: Colors.transparent, + ), + // ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: FlutterLogo() + // Image.network( + // widget.editProfileModel.profilePicture!, + // fit: BoxFit.cover, + // ), + // ) + // completeProfileController.isFileNetwork.value + // ? ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: Image.network( + // '${widget.editProfileModel.profilePicture}', + // fit: BoxFit.cover, + // ), + // ) + // : ClipRRect( + // borderRadius: BorderRadius.circular(100), + // child: Image.file( + // File( + // completeProfileController + // .selectedImagePath.value, + // ), + // fit: BoxFit.cover, + // ), + // ), + ), + ), + // ), + ), + ), + ), + Positioned( + top: 9, + right: 122, + child: InkWell( + onTap: () => Get.to( + () => + const CompleteProfileBeforeSignIn(editProfile: true), + ), + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + border: Border.all( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + width: 2, + ), + shape: BoxShape.circle, + ), + child: Icon( + Icons.edit_rounded, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + size: 10, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 16), + Text( + "More About ${appDataController.name.value}", + style: QuizTextStyles.label.copyWith( + fontWeight: FontWeight.w400, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: appDataController.bio.value, + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only( + left: 8.0, + top: 10, + ), + child: + SvgPicture.asset("assets/image/profile/quote.svg"), + ), + ), + ], + ), + textAlign: TextAlign.center, + ), + ), + /* + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + const Padding( + padding: EdgeInsets.symmetric(horizontal: 14.0), + child: Text( + "I am a lead business analyst at WDIPL and have a busy day. GSF has helped me implement small workouts into my lifestyle.", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14, + color: Colors.white, + ), + ), + ), + Positioned( + right: 84, + bottom: -6, + child: SvgPicture.asset("assets/image/profile/quote.svg"), + ) + ], + ), + */ + // const SizedBox(height: 28), + // Text( + // "Badges", + // style: TextStyle( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : Colors.white, + // fontSize: 20, + // ), + // ), + // const SizedBox(height: 28), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: const [ + // BadgeWidget( + // label: "Workout\nMilestone", + // badgeImgPath: "assets/image/quiz_imgs/milestone.png", + // ), + // BadgeWidget( + // label: "App Usages", + // badgeImgPath: "assets/image/quiz_imgs/app_usage.png", + // ), + // BadgeWidget( + // label: "Streaks", + // badgeImgPath: "assets/image/quiz_imgs/streaks.png", + // ), + // ], + // ), + const SizedBox(height: 48), + ], + ), + )), + ); + } +} diff --git a/gsf/lib/views/pages/profile/pages/view_profile.dart b/gsf/lib/views/pages/profile/pages/view_profile.dart new file mode 100644 index 0000000..13e13ae --- /dev/null +++ b/gsf/lib/views/pages/profile/pages/view_profile.dart @@ -0,0 +1,262 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/components/appbar.dart'; + +import '../../../../modals/leaderboard_ranking_model.dart'; +import '../../../theme.dart'; + +String groupLevelN = ''; + +class ViewProfile extends StatefulWidget { + final RankingLeaderBoard viewFrndProfileModels; + final String groupLevel; + const ViewProfile({ + required this.viewFrndProfileModels, + required this.groupLevel, + Key? key, + }) : super(key: key); + + @override + State createState() => _ViewProfileState(); +} + +class _ViewProfileState extends State { + @override + void initState() { + super.initState(); + returnOfText(); + } + + // String groupLevelN = ''; + + returnOfText() { + if (widget.groupLevel == 'elites') { + groupLevelN = "Swole"; + } else if (widget.groupLevel == 'gameChangers') { + groupLevelN = "Up Steppers"; + } else if (widget.groupLevel == 'underdogs') { + groupLevelN = "Rookie"; + } + } + + @override + Widget build(BuildContext context) { + print('Mumbai new s${widget.viewFrndProfileModels.userData!.city}'); + // final brightness = Get.theme.brightness; + GlobalController globalController = Get.find(); + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars(titleHead: 'Profile'), + ), + body: SingleChildScrollView( + child: Obx( + () => Column( + children: [ + Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + Container( + height: 72 + 180, + ), + Container( + height: 180, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.13) + : const Color(0xff212121), + ), + Container( + height: 150, + width: double.infinity, + padding: const EdgeInsets.only( + left: 32, + right: 32, + top: 32, + bottom: 16, + ), + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0) + : const Color(0xff212121), + child: Column( + children: [ + const SizedBox(height: 10), + // Text('${widget.viewFrndProfileModels.totalScore}'), + Text( + widget.viewFrndProfileModels.user!.fullName + .toUpperCase(), + style: QuizTextStyles.heading.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + const SizedBox(height: 5), + Text( + groupLevelN, + style: QuizTextStyles.label.copyWith( + fontWeight: FontWeight.w400, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor), + ), + const SizedBox(height: 5), + Text( + widget.viewFrndProfileModels.userData?.city ?? '- -', + style: QuizTextStyles.label.copyWith( + fontWeight: FontWeight.w400, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + // const SizedBox(height: 32), + ], + ), + ), + Positioned( + top: 12, + child: Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + border: Border.all( + color: Colors.green, + width: 2, + ), + shape: BoxShape.circle, + ), + child: + // widget.viewFrndProfileModels.userData! + // .profilePicture + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: (widget.viewFrndProfileModels.userData + ?.profilePicture == + null) + ? Image.network( + 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I=', + fit: BoxFit.fill, + ) + : Image.network( + correctImgUrl( + '${widget.viewFrndProfileModels.userData?.profilePicture}', + ), + ), + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 16), + Text( + "More About ${widget.viewFrndProfileModels.user!.fullName}", + style: QuizTextStyles.label.copyWith( + fontWeight: FontWeight.w400, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: + '${widget.viewFrndProfileModels.userData?.description}', + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only( + left: 8.0, + top: 10, + ), + child: SvgPicture.asset( + "assets/image/profile/quote.svg"), + ), + ), + ], + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox(height: 28), + // Text( + // "Badges", + // style: TextStyle( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : Colors.white, + // fontSize: 20, + // ), + // ), + // const SizedBox(height: 28), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: const [ + // BadgeWidget( + // label: "Workout\nMilestone", + // badgeImgPath: "assets/image/quiz_imgs/milestone.png", + // ), + // BadgeWidget( + // label: "App Usages", + // badgeImgPath: "assets/image/quiz_imgs/app_usage.png", + // ), + // BadgeWidget( + // label: "Streaks", + // badgeImgPath: "assets/image/quiz_imgs/streaks.png", + // ), + // ], + // ), + // const SizedBox(height: 48), + + widget.viewFrndProfileModels.user?.stepCountList != null && + widget + .viewFrndProfileModels.user!.stepCountList.isNotEmpty + ? Text( + "Footsteps : ${widget.viewFrndProfileModels.user?.stepCountList.first.stepCount ?? 0} ", + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + )) + : Text( + "Footsteps : 0 ", + style: TextStyle( + fontSize: 14, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : Colors.white, + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/profile_exports.dart b/gsf/lib/views/pages/profile/profile_exports.dart new file mode 100644 index 0000000..7d35a52 --- /dev/null +++ b/gsf/lib/views/pages/profile/profile_exports.dart @@ -0,0 +1,13 @@ +export 'ideal_weight.dart'; +export 'basal_metabolism.dart'; +export 'body_age.dart'; +export 'body_fat.dart'; +export 'body_type.dart'; +export 'bone_mass.dart'; +export 'fat_index.dart'; +export 'fat_mass.dart'; +export 'fat_rate.dart'; +export 'lean_body_mass.dart'; +export 'moisture.dart'; +export 'muscle_rate.dart'; +export 'protein_rate.dart'; diff --git a/gsf/lib/views/pages/profile/profile_slider.dart b/gsf/lib/views/pages/profile/profile_slider.dart new file mode 100644 index 0000000..7343bf1 --- /dev/null +++ b/gsf/lib/views/pages/profile/profile_slider.dart @@ -0,0 +1,111 @@ +// ignore_for_file: prefer_const_constructors + +import 'dart:async'; + +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/profile_slider_controller.dart'; +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class ProfileSlider extends StatefulWidget { + const ProfileSlider({Key? key}) : super(key: key); + + @override + State createState() => _ProfileSliderState(); +} + +class _ProfileSliderState extends State { + int tabIndex = Get.arguments; + @override + void initState() { + super.initState(); + Timer(Duration(milliseconds: 1), () { + slidercontrollers.sliderController + .animateToPage(tabIndex, duration: Duration(milliseconds: 1)); + }); + } + + int _current = 0; + final ProfileSliderController slidercontrollers = + Get.put(ProfileSliderController()); + + @override + Widget build(BuildContext context) { + List l1 = slidercontrollers.setvaluesofList(); + final brightness = Get.theme.brightness; + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: ''), + ), + // backgroundColor: ColorConstants.kBlack, + body: SizedBox( + height: Get.size.height * 1, + width: Get.size.width * 1, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 5, + ), + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 20), + CarouselSlider( + carouselController: slidercontrollers.sliderController, + options: CarouselOptions( + height: Get.size.height - 150, + viewportFraction: 1.0, + // autoPlay: true, + enableInfiniteScroll: false, + // autoPlayCurve: Curves.linear, + autoPlayInterval: const Duration(seconds: 3), + onPageChanged: (index, reason) { + setState(() { + _current = index; + }); + }), + items: l1 + .map( + (item) => item, + ) + .toList(), + ), + Align( + alignment: Alignment.bottomRight, + child: RichText( + text: TextSpan( + text: (_current + 1 > 9) + ? '${_current + 1}' + : '0${_current + 1}', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + children: [ + TextSpan( + text: '/' + l1.length.toString(), + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? Colors.grey + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/protein_rate.dart b/gsf/lib/views/pages/profile/protein_rate.dart new file mode 100644 index 0000000..1f6a9e2 --- /dev/null +++ b/gsf/lib/views/pages/profile/protein_rate.dart @@ -0,0 +1,593 @@ +// ignore_for_file: unrelated_type_equality_checks + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/BioscaleOverview.dart'; +import 'package:gsp_app/views/pages/profile/SampleChart.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../theme.dart'; +import '../bioMaker/controller.dart'; +import 'pages/SampleChart2.dart'; + +class ProteinRate extends StatefulWidget { + final String proteinApi; + const ProteinRate({required this.proteinApi, Key? key}) : super(key: key); + + @override + State createState() => _ProteinRateState(); +} + +class _ProteinRateState extends State { + List dateList = []; + List priceList = []; + String selectedChoice = 'Yearly'; + Map defaultupdata = {"created_at": "", "data": "year"}; + @override + void initState() { + super.initState(); + } + + setValues() { + // if (isonce) { + dateList.clear(); + priceList.clear(); + for (var i = 0; i < allDatesData!.authorisation!.userData!.length; i++) { + dateList.add(allDatesData!.authorisation!.userData![i].createdAt!); + priceList.add(allDatesData!.authorisation!.userData![i].protein!); + } + print("date val is ${dateList.length}"); + // isonce = false; + // + } + + @override + Widget build(BuildContext context) { + // final sliderdotInt = Get.size.width * 0.75; + final brightness = Get.theme.brightness; + AppDataController appDataController = Get.find(); + final aControllerFind = Get.put(AController()); + // value from scale + final double proteinScale = double.parse( + (aControllerFind.localProtein.value == '- -') + ? '0' + : aControllerFind.localProtein.value); + // double proteinValuePercenateg = proteinScale / 100; + + // value Date wise from API + double proteinApiParse = + double.parse(widget.proteinApi.toString().replaceAll('%', '')); + // var proteinInPercentage = proteinApiParse / 100; + // range calculations + final gender = appDataController.gender; + // String rangeTxt = ''; + String rangeColor = ''; + bool first = false; + bool second = false; + bool third = false; + String desc = ''; + + final newProtein = (aControllerFind.localProtein.value == '- -') + ? '0.0' + : aControllerFind.localProtein.value; + + final newProtienValue = (aControllerFind.checDate.value) + ? double.parse(newProtein) + : proteinApiParse; + + if (gender == 'male') { + if ((newProtienValue) >= 0 && (newProtienValue) <= 16.00) { + // rangeTxt = 'Low'; + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + desc = 'Your protein content is low, try to eat more protein.'; + } else if ((newProtienValue) > 16.00 && (newProtienValue) <= 18.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + desc = + 'Your protein content is standard. You can focus on more protein in any major meal. '; + } else if ((newProtienValue) > 18.00 && (newProtienValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + desc = 'Your protein content is excellent. Well done! '; + } + } else if (gender == 'female') { + if ((newProtienValue) >= 0 && (newProtienValue) <= 14.00) { + rangeColor = '0xffE90000'; + first = true; + second = false; + third = false; + desc = 'Your protein content is low, try to eat more protein.'; + } else if ((newProtienValue) > 14.00 && (newProtienValue) <= 16.00) { + // rangeTxt = 'Standard'; + rangeColor = '0xffFFFE00'; + first = false; + second = true; + third = false; + desc = + 'Your protein content is standard. You can focus on more protein in any major meal. '; + } else if ((newProtienValue) > 16.00 && (newProtienValue) <= 100) { + // rangeTxt = 'Excellent'; + rangeColor = '0xff8FD155'; + first = false; + second = false; + third = true; + desc = 'Your protein content is excellent. Well done! '; + } + } + + // first range calcultaion -start + rangeSliderCalulation(start, end) { + double mainValue = double.parse(newProtienValue.toString()); + + double rangeValue = end - start.toDouble(); + + double dividedValue = 100 / rangeValue; + // print('DIVIDED VALUE $dividedValue'); + + double remaivalue = mainValue - start; + // print('DIVIDED Value ${remaivalue}'); + + double finalSliderValue = remaivalue * dividedValue; + // print('DIVIDED Value FINAL RANGE VALUE $finalSliderValue'); + return finalSliderValue.toDouble(); + } + + return SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/protein_rate.svg'), + const SizedBox(height: 20), + Text( + 'Protein Rate', + style: TextStyle( + fontSize: 20, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 25), + Text( + 'Talk about your hair, skin, looking younger, better hormonal health, better muscle ratio, more energy, lesser cravings- THINK PROTEIN ?\nDid you know- Carbs and proteins have the same amount of calories & yet- Proteins are recommended for weight loss or gain or for treating Hormonal problems.\nMake sure you have a portion of protein in every meal you eat.', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + const SizedBox(height: 30), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff333333), + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.15), + spreadRadius: 2, + blurRadius: 10, + ) + ]), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: 'Your protein rate ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + children: [ + TextSpan( + text: + ' ${aControllerFind.checDate.value ? proteinScale : proteinApiParse}%', + style: TextStyle( + fontSize: 22, + color: Color(int.parse(rangeColor)), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Spacer(), + Text( + '${(gender == 'male') ? 16 : 14}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + Text( + '${(gender == 'male') ? 18 : 16}%', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + ], + ), + const SizedBox(height: 5), + Row( + children: [ + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 0 : 0, + (gender == 'male') ? 16 : 14); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffE90000), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Insufficient', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: first, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ), + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 17 : 15, + (gender == 'male') ? 18 : 16); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xffFFFE00), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: second, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + Expanded( + // flex: 4, + child: + LayoutBuilder(builder: (context, constrants) { + final percentWidth = constrants.maxWidth; + final finalRangeVAlue = rangeSliderCalulation( + (gender == 'male') ? 19 : 17, + (gender == 'male') ? 100 : 100); + final finalPosiotion = + (finalRangeVAlue * percentWidth) / 100; + return Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: const Color(0xff8FD155), + borderRadius: + BorderRadius.circular(5), + ), + ), + const SizedBox(height: 5), + Text( + 'excellent', + style: TextStyle( + fontSize: 12, + color: + (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + Visibility( + visible: third, + child: Positioned( + top: -4, + // bottom: 0, + left: finalPosiotion - 20, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(int.parse(rangeColor)), + ), + ), + ), + ), + ) + ], + ); + }), + ), + ], + ), + const SizedBox(height: 30), + const Divider( + color: Color(0xff707070), + thickness: 1, + ), + const SizedBox(height: 20), + Text( + desc, + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + SizedBox( + height: 25, + ), + Row( + // mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.white), // White border + borderRadius: BorderRadius.circular( + 8.0), // Optional: Add border radius + ), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(selectedChoice), + ), + PopupMenuButton( + initialValue: '/yearly', + offset: const Offset(0, 155), + color: Colors.white, + tooltip: '', + icon: const Icon(Icons.more_vert), + onSelected: (value) { + if (value == '/weekly') { + setState(() { + selectedChoice = "Weekly"; + var updata = {"created_at": "", "data": "week"}; + defaultupdata = updata; + }); + } else if (value == "/monthly") { + setState(() { + selectedChoice = "Monthly"; + var updata = { + "created_at": "", + "data": "month" + }; + defaultupdata = updata; + }); + } else if (value == "/yearly") { + setState(() { + selectedChoice = "Yearly"; + var updata = {"created_at": "", "data": "year"}; + defaultupdata = updata; + }); + } + }, + itemBuilder: (BuildContext bc) { + return const [ + PopupMenuItem( + child: Text( + "Weekly", + style: TextStyle(color: Colors.black), + ), + value: '/weekly', + ), + PopupMenuItem( + child: Text( + "Monthly", + style: TextStyle(color: Colors.black), + ), + value: '/monthly', + ), + PopupMenuItem( + child: Text( + "Yearly", + style: TextStyle(color: Colors.black), + ), + value: '/yearly', + ), + ]; + }, + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + FutureBuilder( + future: BioScaleOverview().dataForallDAtes(defaultupdata), + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return CircularProgressIndicator(); + } + if (snapshot.connectionState == ConnectionState.done) { + allDatesData!.authorisation!.userData!.isEmpty + ? null + : setValues(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return allDatesData!.authorisation!.userData!.isEmpty + ? SizedBox( + height: 100, + child: Center(child: Text("No Data Found"))) + : SizedBox( + height: 300, + width: Get.width, + child: + + // ColumnChartSample( + // dateList: dateList, + // priceList: priceList, + // ) + SampleChart( + // lastMonthDate: priceData.table!.first.date!, + dateList: dateList, + priceList: priceList, + ), + ); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/profile/testprofile.dart b/gsf/lib/views/pages/profile/testprofile.dart new file mode 100644 index 0000000..845952a --- /dev/null +++ b/gsf/lib/views/pages/profile/testprofile.dart @@ -0,0 +1,295 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class ProlieTest extends StatelessWidget { + const ProlieTest({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final sliderdotInt = Get.size.width * 0.75; + return Scaffold( + appBar: PreferredSize( + preferredSize: Size.fromHeight(60), + child: CustomAppBars(titleHead: ''), + ), + backgroundColor: ColorConstants.kBlack, + body: SizedBox( + width: Get.size.width, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/image/profileIcons/bodyFat.svg'), + SizedBox(height: 20), + Text( + 'Body fat', + style: TextStyle( + fontSize: 20, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + SizedBox(height: 25), + Text( + 'Body fat is not only an energy source for activities, but also has important functions such as maintaining body temperature, reducing external impact, moisturizing the skin.', + style: TextStyle( + fontSize: 14, + color: Color(0xffd9d9d9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w400), + ), + SizedBox(height: 20), + Container( + // height: 128, + width: double.infinity, + decoration: BoxDecoration( + color: Color(0xff333333), + borderRadius: BorderRadius.circular(18), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Column( + children: [ + RichText( + text: TextSpan( + text: 'Your body fat mass is ', + style: TextStyle( + fontSize: 16, color: ColorConstants.kWhite), + children: const [ + TextSpan( + text: ' 14kg', + style: TextStyle( + fontSize: 22, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + SizedBox(height: 12), + Row( + children: const [ + SizedBox(width: 20), + Text( + '7.50kg', + style: TextStyle( + fontSize: 14, color: Color(0xffD9D9D9)), + ), + SizedBox(width: 20), + Text( + '11.60kg', + style: TextStyle( + fontSize: 14, color: Color(0xffD9D9D9)), + ), + SizedBox(width: 20), + Text( + '15.10kg', + style: TextStyle( + fontSize: 14, color: Color(0xffD9D9D9)), + ), + Spacer(), + Text( + '18.50kg', + style: TextStyle( + fontSize: 14, color: Color(0xffD9D9D9)), + ), + Spacer(), + ], + ), + SizedBox(height: 5), + Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: Color(0xff31AADF), + borderRadius: + BorderRadius.circular(5), + ), + ), + SizedBox(height: 5), + Text( + 'Thin', + style: TextStyle( + fontSize: 12, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: Color(0xff2BC497), + borderRadius: + BorderRadius.circular(5), + ), + ), + SizedBox(height: 5), + Text( + 'Standard', + style: TextStyle( + fontSize: 12, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: Color(0xffFFBC04), + borderRadius: + BorderRadius.circular(5), + ), + ), + SizedBox(height: 5), + Text( + 'alert', + style: TextStyle( + fontSize: 12, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 5, + child: Padding( + padding: const EdgeInsets.only(right: 5.0), + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: Color(0xffF56506), + borderRadius: + BorderRadius.circular(5), + ), + ), + SizedBox(height: 5), + Text( + 'Overweight', + style: TextStyle( + fontSize: 12, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ), + Expanded( + flex: 6, + child: Column( + children: [ + Container( + height: 13, + decoration: BoxDecoration( + color: Color(0xffE90000), + borderRadius: BorderRadius.circular(5), + ), + ), + SizedBox(height: 5), + Text( + 'obesity', + style: TextStyle( + fontSize: 12, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w700, + fontFamily: 'SFPRO', + ), + ), + ], + ), + ), + ], + ), + Positioned( + top: -4, + // bottom: 0, + left: sliderdotInt * 0.45, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: ColorConstants.kWhite, + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: Color(0xffFFBC04), + ), + ), + ), + ) + ], + ), + SizedBox(height: 30), + Divider( + color: Color(0xff707070), + thickness: 1, + ), + SizedBox(height: 20), + Text( + 'Your fat content is worthy of vigilance, you need to pay attention to your diet and strengthen exercise.', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ) + ], + ), + ), + ), + // Spacer(), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/quiz/badges_page.dart b/gsf/lib/views/pages/quiz/badges_page.dart new file mode 100644 index 0000000..5f6cb96 --- /dev/null +++ b/gsf/lib/views/pages/quiz/badges_page.dart @@ -0,0 +1,234 @@ +import 'dart:async'; +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class BadgesPage extends StatefulWidget { + const BadgesPage({Key? key}) : super(key: key); + + @override + State createState() => _BadgesPageState(); +} + +class _BadgesPageState extends State { + List> badgeJsonList = [ + { + "label": "Workout Milestone", + "imgPath": "assets/image/quiz_imgs/milestone.png", + "isLocked": false + }, + { + "label": "App Usages", + "imgPath": "assets/image/quiz_imgs/app_usage.png", + "isLocked": false + }, + { + "label": "Streaks", + "imgPath": "assets/image/quiz_imgs/streaks.png", + "isLocked": false + }, + { + "label": "Workout Milestone", + "imgPath": "assets/image/quiz_imgs/milestone.png", + "isLocked": false + }, + { + "label": "App Usages", + "imgPath": "assets/image/quiz_imgs/app_usage.png", + "isLocked": false + }, + { + "label": "Streaks", + "imgPath": "assets/image/quiz_imgs/streaks.png", + "isLocked": false + }, + { + "label": "Workout Milestone", + "imgPath": "assets/image/quiz_imgs/milestone.png", + "isLocked": true + }, + { + "label": "App Usages", + "imgPath": "assets/image/quiz_imgs/app_usage.png", + "isLocked": true + }, + { + "label": "Streaks", + "imgPath": "assets/image/quiz_imgs/streaks.png", + "isLocked": true + }, + ]; + + @override + void initState() { + super.initState(); + Timer.periodic(const Duration(seconds: 1), (timer) { + Get.dialog( + BackdropFilter( + filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), + child: badgeDialogBody(), + ), + ); + timer.cancel(); + }); + } + + Widget badgeDialogBody() { + return Scaffold( + backgroundColor: Colors.transparent, + body: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Hooray!", + style: QuizTextStyles.label.copyWith(fontSize: 28), + ), + const SizedBox(height: 4), + const Text( + "You have got a new badge", + style: QuizTextStyles.body, + ), + const SizedBox(height: 28), + ClipRRect( + borderRadius: BorderRadius.circular(22), + child: Image.asset("assets/image/quiz_imgs/badge_dialog.jpg"), + ), + const SizedBox(height: 18), + IconButton( + onPressed: () => Get.back(), + icon: SvgPicture.asset( + "assets/image/quiz_imgs/cancel_outlined_rounded.svg", + ), + ) + ], + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Badges'), + ), + body: Padding( + padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 18), + child: Align( + alignment: Alignment.topCenter, + child: Wrap( + spacing: 8, + runSpacing: 18, + children: badgeJsonList + .map( + (badgeJsonList) => SizedBox( + width: Get.size.width * 0.28, + child: BadgeWidget( + isBadgeLocked: badgeJsonList["isLocked"], + label: badgeJsonList["label"], + badgeImgPath: badgeJsonList["imgPath"], + ), + ), + ) + .toList(), + ), + ), + )); + } +} + +class BadgeWidget extends StatelessWidget { + const BadgeWidget({ + required this.label, + required this.badgeImgPath, + this.isBadgeLocked = false, + Key? key, + }) : super(key: key); + + final String label; + final String badgeImgPath; + final bool isBadgeLocked; + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Column( + children: [ + Stack( + alignment: AlignmentDirectional.bottomCenter, + clipBehavior: Clip.none, + children: [ + Container( + width: 92, + height: 92, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: ColorFiltered( + colorFilter: isBadgeLocked + ? const ColorFilter.matrix([ + 0.2126, + 0.7152, + 0.0722, + 0, + 0, + 0.2126, + 0.7152, + 0.0722, + 0, + 0, + 0.2126, + 0.7152, + 0.0722, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + ]) + : const ColorFilter.mode( + Colors.transparent, + BlendMode.saturation, + ), + child: Opacity( + opacity: isBadgeLocked ? 0.3 : 1, + child: Image.asset(badgeImgPath), + ), + ), + ), + Visibility( + visible: isBadgeLocked, + child: Positioned( + bottom: -5, + child: SvgPicture.asset("assets/image/quiz_imgs/padlock.svg"), + ), + ) + ], + ), + SizedBox(height: isBadgeLocked ? 14 : 10), + Text( + label, + textAlign: TextAlign.center, + style: QuizTextStyles.body.copyWith( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ) + ], + ); + } +} diff --git a/gsf/lib/views/pages/quiz/quiz_home.dart b/gsf/lib/views/pages/quiz/quiz_home.dart new file mode 100644 index 0000000..b6dd3e5 --- /dev/null +++ b/gsf/lib/views/pages/quiz/quiz_home.dart @@ -0,0 +1,196 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'quiz_question.dart'; + +bool showQuizbool = true; + +class QuizHome extends StatefulWidget { + const QuizHome({Key? key}) : super(key: key); + + @override + State createState() => _QuizHomeState(); +} + +class _QuizHomeState extends State { + @override + Widget build(BuildContext context) { + final screenSize = Get.mediaQuery.size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Quiz'), + ), + body: SizedBox( + width: screenSize.width * 1, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 18, + vertical: 14, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //header img + Align( + alignment: Alignment.topCenter, + child: Stack( + alignment: AlignmentDirectional.centerStart, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Image.asset( + "assets/image/quiz_imgs/quiz_header_bg.jpg"), + ), + const Padding( + padding: EdgeInsets.only(left: 28.0), + child: Text( + 'Quiz', + style: TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w700, + fontSize: 52, + fontStyle: FontStyle.italic, + ), + ), + ) + ], + ), + ), + const SizedBox(height: 21), + Text( + "What's in the GSF quiz?", + style: QuizTextStyles.heading, + ), + const SizedBox(height: 8), + const Text( + "The GSF quiz will contain questions regarding nutrition, exercise, and wellbeing with variable difficulty", + style: QuizTextStyles.body, + ), + const SizedBox(height: 18), + Text( + "How To Earn Points?", + style: QuizTextStyles.heading, + ), + const SizedBox(height: 8), + const Text( + "You will be awarded points according to the number of questions you answer, one point per question", + style: QuizTextStyles.body, + ), + const SizedBox(height: 25), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //nutrition + Column( + children: [ + Container( + width: 80, + height: 80, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: const Color(0xff333333), + shape: BoxShape.circle, + border: Border.all( + color: const Color(0xffBBF046), + width: 1, + ), + ), + child: SvgPicture.asset( + "assets/image/quiz_imgs/nutrition.svg", + ), + ), + const SizedBox(height: 8), + Text( + "Nutrition", + style: QuizTextStyles.heading, + ), + ], + ), + //exercise + Column( + children: [ + Container( + width: 80, + height: 80, + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: const Color(0xff333333), + shape: BoxShape.circle, + border: Border.all( + color: const Color(0xffBBF046), + width: 1, + ), + ), + child: SvgPicture.asset( + "assets/image/quiz_imgs/exercise.svg", + ), + ), + const SizedBox(height: 8), + Text( + "Exercise", + style: QuizTextStyles.heading, + ), + ], + ), + //general medical + Column( + children: [ + Container( + width: 80, + height: 80, + padding: const EdgeInsets.all(18), + decoration: BoxDecoration( + color: const Color(0xff333333), + shape: BoxShape.circle, + border: Border.all( + color: const Color(0xffBBF046), + width: 1, + ), + ), + child: SvgPicture.asset( + "assets/image/quiz_imgs/general_medical.svg", + ), + ), + const SizedBox(height: 8), + Text( + "General\nMedical", + style: QuizTextStyles.heading, + ), + ], + ), + ], + ), + const SizedBox(height: 25), + const Center( + child: Text( + "Earn Points & Claim the Leaderboard", + style: QuizTextStyles.label, + ), + ), + ], + ), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: showQuizbool + ? FullWdtBtn( + btnText: "Participate Now!", + onTap: () => Get.off(() => const QuizQuestion()), + ) + : FullWdtBtn( + disabled: true, + btnText: "See you tomorrow!", + onTap: () => null, + )), + ); + } +} diff --git a/gsf/lib/views/pages/quiz/quiz_question.dart b/gsf/lib/views/pages/quiz/quiz_question.dart new file mode 100644 index 0000000..c12e013 --- /dev/null +++ b/gsf/lib/views/pages/quiz/quiz_question.dart @@ -0,0 +1,658 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:circular_countdown_timer/circular_countdown_timer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/modals/QuizModel.dart'; +import 'package:gsp_app/view_model/QuizApis.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'quiz_result.dart'; + +class QuizQuestion extends StatefulWidget { + const QuizQuestion({Key? key}) : super(key: key); + + @override + State createState() => _QuizQuestionState(); +} + +class _QuizQuestionState extends State { + List> quizJson = []; + // List> quizJson = [ + // { + // "question": "Which game is considered the national game of India?", + // "options": ["Hockey", "Not decided", "Cricket", "Football"], + // "ansIndex": 0 + // }, + // { + // "question": "Vajrasna is known for:", + // "options": ["Meditation", "Sleeping", "Relaxing", "Saluting"], + // "ansIndex": 0 + // }, + // { + // "question": + // "Which of the following would have the least effect on muscle anaerobic capacity?", + // "options": [ + // "Muscle glycolytic enzyme activity", + // "Resting muscle PCr concentration", + // "Resting muscle glycogen concentration", + // "Muscle buffering capacity", + // ], + // "ansIndex": 2 + // }, + // { + // "question": "Disease due to lack of vitamin D is:", + // "options": [ + // "Night blindness", + // "Rickets", + // "Beri Beri", + // "Scurvy", + // ], + // "ansIndex": 1 + // }, + // ]; + int index = 0; + + //options + bool? isFirstCorrect; + bool? isSecondCorrect; + bool? isThirdCorrect; + bool? isFourthCorrect; + + //score + int score = 0; + + int tapped = 0; + + late Future myfuture; + final countdowncontroller = CountDownController(); + @override + void initState() { + myfuture = QuizeApis().getQuiz(); + super.initState(); + } + + bool _isonce = true; + generateQuizJson() { + if (_isonce) { + int ansIndex = -1; // Initializing ansIndex with a default value + for (var i = 0; i < quizData!.result!.length; i++) { + String question = quizData!.result![i].questions!; + List options = quizData!.result![i].answer!; + for (var j = 0; j < options.length; j++) { + if (options[j].isActive == "1") { + ansIndex = j; + } + } + + if (ansIndex != -1) { + QuizQuestionModel quizQuestion = QuizQuestionModel( + question: question, + options: options, + ansIndex: ansIndex, + ); + quizJson.add(quizQuestion.toJson()); + } + } + _isonce = false; + } + } + + @override + Widget build(BuildContext context) { + final screenSize = Get.mediaQuery.size; + + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Quiz'), + ), + body: FutureBuilder( + future: myfuture, + builder: (ctx, snapshot) { + if (snapshot.data == null) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [Center(child: CircularProgressIndicator())], + ); + } + if (snapshot.connectionState == ConnectionState.done) { + generateQuizJson(); + countdowncontroller.start(); + if (snapshot.hasError) { + return Center( + child: Text( + '${snapshot.error} occured', + style: TextStyle(fontSize: 18), + ), + ); + } + } + return _buildBody(screenSize, quizJson[index]["ansIndex"]); + }, + ), + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: FullWdtBtn( + btnText: "Next", + onTap: () { + tapped = 0; + debugPrint("score: $score"); + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (index + 1 == quizJson.length) { + Get.off( + () => QuizResult( + score: score, + questions: quizJson.length, + ), + ); + } else { + setState(() { + index++; + }); + } + }, + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + ); + } + + _buildBody(screenSize, ansIndex) { + return SizedBox( + width: screenSize.width * 1, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 14), + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Questions ${index + 1}/${quizJson.length}", + style: QuizTextStyles.label + .copyWith(fontStyle: FontStyle.italic), + ), + CircularCountDownTimer( + duration: 20, + initialDuration: 0, + controller: countdowncontroller, + width: 35, + height: 35, + ringColor: Color(0xFFBBF046), + ringGradient: null, + fillColor: + Colors.white, // Colors.purpleAccent[100]!, + fillGradient: null, + backgroundColor: + Colors.black45, // Colors.purple[500], + backgroundGradient: null, + // strokeWidth: 10.0, + strokeCap: StrokeCap.round, + textStyle: QuizTextStyles.label + .copyWith(color: Colors.white, fontSize: 10), + textFormat: CountdownTextFormat.S, + isReverse: true, + isReverseAnimation: false, + isTimerTextShown: true, + autoStart: true, + onStart: () { + debugPrint('Countdown Started'); + }, + onComplete: () { + tapped = 0; + debugPrint("score: $score"); + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (index + 1 == quizJson.length) { + Get.off( + () => QuizResult( + score: score, + questions: quizJson.length, + ), + ); + } else { + setState(() { + index++; + }); + } + }, + onChange: (String timeStamp) { + debugPrint('Countdown Changed $timeStamp'); + }, + timeFormatterFunction: + (defaultFormatterFunction, duration) { + if (duration.inSeconds == 0) { + return "0"; + } else { + return Function.apply( + defaultFormatterFunction, [duration]); + } + }, + ), + ], + ), + const SizedBox(height: 40), + Stack( + clipBehavior: Clip.none, + alignment: AlignmentDirectional.bottomCenter, + children: [ + Positioned( + bottom: -18, + left: 0, + right: 0, + child: Container( + height: 207, + decoration: BoxDecoration( + color: const Color(0xFF161616), + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Color.fromARGB(255, 3, 3, 3), + offset: Offset(0, 0.5), + blurRadius: 1, + ) + ], + ), + ), + ), + Positioned( + bottom: -12, + left: 0, + right: 0, + child: Container( + height: 207, + decoration: BoxDecoration( + color: const Color(0xFF232323), + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Color.fromARGB(255, 3, 3, 3), + offset: Offset(0, 0.5), + blurRadius: 1, + ) + ], + ), + ), + ), + Positioned( + bottom: -6, + left: 0, + right: 0, + child: Container( + height: 207, + decoration: BoxDecoration( + color: const Color(0xFF292929), + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Color.fromARGB(255, 3, 3, 3), + offset: Offset(0, 0.5), + blurRadius: 1, + ) + ], + ), + ), + ), + Container( + height: 207, + decoration: BoxDecoration( + color: const Color(0xFF212121), + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Color.fromARGB(255, 3, 3, 3), + offset: Offset(0, 0.5), + blurRadius: 1, + ) + ], + ), + ), + //stopwatch + Positioned( + top: -32, + child: Container( + height: 64, + width: 64, + decoration: const BoxDecoration( + color: Color(0xFF1C1B1B), + shape: BoxShape.circle, + ), + child: Image.asset( + "assets/image/quiz_imgs/stopwatch.png", + ), + ), + ), + Container( + padding: const EdgeInsets.symmetric( + vertical: 52, + horizontal: 28, + ), + height: 207, + width: double.infinity, + color: Colors.transparent, + child: Text( + quizJson.elementAt(index)["question"], + style: QuizTextStyles.heading + .copyWith(fontStyle: FontStyle.italic), + ), + ), + ], + ), + const SizedBox(height: 36), + StatefulBuilder( + builder: (context, setOptState) { + return Column( + children: [ + GestureDetector( + onTap: () { + tapped++; + setOptState(() { + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (ansIndex == 0) { + isFirstCorrect = true; + if (tapped == 1) score++; + } + if (ansIndex != 0) { + isFirstCorrect = false; + } + switch (ansIndex) { + case 0: + isFirstCorrect = true; + break; + case 1: + isSecondCorrect = true; + break; + case 2: + isThirdCorrect = true; + break; + case 3: + isFourthCorrect = true; + break; + default: + } + }); + }, + child: QuizOptionElement( + isCorrect: isFirstCorrect, + label: quizJson + .elementAt(index)["options"][0] + .answers, + ), + ), + const SizedBox(height: 15), + GestureDetector( + onTap: () { + tapped++; + setOptState(() { + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (ansIndex == 1) { + isSecondCorrect = true; + if (tapped == 1) score++; + } + if (ansIndex != 1) { + isSecondCorrect = false; + } + switch (ansIndex) { + case 0: + isFirstCorrect = true; + break; + case 1: + isSecondCorrect = true; + break; + case 2: + isThirdCorrect = true; + break; + case 3: + isFourthCorrect = true; + break; + default: + } + }); + }, + child: QuizOptionElement( + isCorrect: isSecondCorrect, + label: quizJson + .elementAt(index)["options"][1] + .answers, + ), + ), + const SizedBox(height: 15), + GestureDetector( + onTap: () { + tapped++; + setOptState(() { + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (ansIndex == 2) { + isThirdCorrect = true; + if (tapped == 1) score++; + } + if (ansIndex != 2) { + isThirdCorrect = false; + } + switch (ansIndex) { + case 0: + isFirstCorrect = true; + break; + case 1: + isSecondCorrect = true; + break; + case 2: + isThirdCorrect = true; + break; + case 3: + isFourthCorrect = true; + break; + default: + } + }); + }, + child: QuizOptionElement( + isCorrect: isThirdCorrect, + label: quizJson + .elementAt(index)["options"][2] + .answers, + ), + ), + const SizedBox(height: 15), + GestureDetector( + onTap: () { + tapped++; + setOptState(() { + isFirstCorrect = null; + isSecondCorrect = null; + isThirdCorrect = null; + isFourthCorrect = null; + if (ansIndex == 3) { + isFourthCorrect = true; + if (tapped == 1) score++; + } + if (ansIndex != 3) { + isFourthCorrect = false; + } + switch (ansIndex) { + case 0: + isFirstCorrect = true; + break; + case 1: + isSecondCorrect = true; + break; + case 2: + isThirdCorrect = true; + break; + case 3: + isFourthCorrect = true; + break; + default: + } + }); + }, + child: QuizOptionElement( + isCorrect: isFourthCorrect, + label: quizJson + .elementAt(index)["options"][3] + .answers, + ), + ), + ], + ); + }, + ) + ]), + ), + const SizedBox(height: 36), + // Stack( + // clipBehavior: Clip.none, + // children: [ + // Container( + // margin: const EdgeInsets.symmetric(horizontal: 18), + // padding: const EdgeInsets.all(12), + // decoration: BoxDecoration( + // border: Border.all( + // color: const Color(0xff646464), + // width: 2, + // ), + // borderRadius: BorderRadius.circular(10), + // ), + // child: SizedBox( + // width: Get.width, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // const SizedBox(height: 12), + // Text( + // "Did You Know?", + // style: QuizTextStyles.label, + // ), + // SizedBox(height: 8), + // Text( + // "Lorem Ipsum is simply dummy text of the printing and typesetting industry.Lorem Ipsum is simply dummy text of the", + // style: QuizTextStyles.heading, + // ), + // ], + // ), + // ), + // ), + // Positioned( + // left: 1, + // top: -16, + // child: SvgPicture.asset("assets/image/quiz_imgs/bulb.svg"), + // ) + // ], + // ), + + // const SizedBox(height: 60) + ], + ), + ), + ), + ); + } +} + +class QuizOptionElement extends StatelessWidget { + const QuizOptionElement({ + Key? key, + required this.label, + this.isCorrect, + }) : super(key: key); + + final String label; + + final bool? isCorrect; + + @override + Widget build(BuildContext context) { + Icon correctIcon = const Icon( + Icons.check_circle_rounded, + color: Color(0xffbbf046), + ); + Icon incorrectIcon = const Icon( + Icons.cancel_rounded, + color: Color(0xffe12c0f), + ); + Icon defaultIcon = const Icon( + Icons.circle_outlined, + color: ColorConstants.kWhite, + ); + return Container( + height: 56, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: const Color(0xFF212121), + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: isCorrect == null + ? Colors.transparent + : isCorrect! + ? const Color(0xffbbf046) + : const Color(0xffe12c0f), + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Text( + label, + style: QuizTextStyles.heading, + ), + ), + const SizedBox(width: 16), + isCorrect == null + ? defaultIcon + : isCorrect! + ? correctIcon + : incorrectIcon + ], + ), + ); + } +} + +class QuizQuestionModel { + String question; + List options; + int ansIndex; + + QuizQuestionModel({ + required this.question, + required this.options, + required this.ansIndex, + }); + + Map toJson() { + return { + "question": question, + "options": options, + "ansIndex": ansIndex, + }; + } +} diff --git a/gsf/lib/views/pages/quiz/quiz_result.dart b/gsf/lib/views/pages/quiz/quiz_result.dart new file mode 100644 index 0000000..9f20b03 --- /dev/null +++ b/gsf/lib/views/pages/quiz/quiz_result.dart @@ -0,0 +1,184 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/QuizApis.dart'; +import 'package:lottie/lottie.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import '../home/home_page.dart'; +import 'dart:math' as math; + +class QuizResult extends StatefulWidget { + const QuizResult({ + required this.score, + required this.questions, + Key? key, + }) : super(key: key); + + final int score; + final int questions; + + @override + State createState() => _QuizResultState(); +} + +class _QuizResultState extends State { + @override + void initState() { + Map updata = {"points": widget.score}; + QuizeApis().storePoints(updata); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + final screenSize = Get.mediaQuery.size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Quiz'), + ), + body: SizedBox( + width: screenSize.width * 1, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 14), + child: SingleChildScrollView( + child: Column(children: [ + SizedBox( + width: 200, + height: 180, + child: Transform.rotate( + angle: math.pi / -4, + child: Lottie.asset('assets/lottie/confetti.json'), + ), + ), + const SizedBox(height: 8), + const Text( + "Hooray!", + style: QuizTextStyles.label, + ), + //const SizedBox(height: 18), + // const Padding( + // padding: EdgeInsets.symmetric(horizontal: 48.0), + // child: Text( + // "Lorem ipsum dolor sit amet . The graphic and typographic operators know this well, in reality all", + // textAlign: TextAlign.center, + // style: QuizTextStyles.body, + // ), + // ), + const SizedBox(height: 46), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18.0), + child: Stack( + clipBehavior: Clip.none, + alignment: AlignmentDirectional.topCenter, + children: [ + Container( + height: 104, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(13), + border: Border.all( + color: const Color(0xffD9D9D9), + ), + ), + padding: const EdgeInsets.symmetric(vertical: 32), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 98, + height: 80, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: const Color(0xff3B3B3B), + ), + child: Center( + child: Text( + widget.score.toString(), + style: + QuizTextStyles.label.copyWith(fontSize: 22), + ), + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 18.0), + child: Transform.rotate( + angle: 10, + child: const VerticalDivider( + thickness: 2, + color: Color(0xffD9D9D9), + ), + ), + ), + Container( + width: 98, + height: 80, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: const Color(0xff3B3B3B), + ), + child: Center( + child: Text( + widget.questions.toString(), + style: + QuizTextStyles.label.copyWith(fontSize: 22), + ), + ), + ), + ], + ), + ), + Positioned( + top: -18, + child: Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(9), + color: const Color(0xff232222)), + child: Text( + "Final Score", + style: QuizTextStyles.heading, + ), + ), + ) + ], + ), + ), + const SizedBox(height: 34), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 48.0), + child: Text( + "You successfully completed the quiz. Here is your final score and the questions you answered", + textAlign: TextAlign.center, + style: QuizTextStyles.body, + ), + ), + // const SizedBox(height: 18), + // const Padding( + // padding: EdgeInsets.symmetric(horizontal: 48.0), + // child: Text( + // "You answered two questions wrong. Here are the correct answers and the reasoning behind them.", + // textAlign: TextAlign.center, + // style: QuizTextStyles.body, + // ), + // ), + const SizedBox(height: 52), + ]), + ), + ), + ), + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: FullWdtBtn( + btnText: "Okay", + onTap: () => Get.off(() => const HomePage()), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + ); + } +} diff --git a/gsf/lib/views/pages/sessions/count_me.dart b/gsf/lib/views/pages/sessions/count_me.dart new file mode 100644 index 0000000..3814390 --- /dev/null +++ b/gsf/lib/views/pages/sessions/count_me.dart @@ -0,0 +1,112 @@ +import 'package:blobs/blobs.dart'; +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:intl/intl.dart'; +// import 'package:flutter_countdown_timer/index.dart'; +import 'package:slide_countdown/slide_countdown.dart'; +import '../../components/appbar.dart'; + +class CountMe extends StatefulWidget { + final String activityTitle; + final dynamic timer; + final dynamic date; + const CountMe({ + Key? key, + required this.activityTitle, + required this.timer, + required this.date, + }) : super(key: key); + + @override + State createState() => _CountMeState(); +} + +class _CountMeState extends State { + // late int timeDuration; + + BlobController blobCtrl = BlobController(); + @override + Widget build(BuildContext context) { + final date = widget.date.toString().split(" ")[0].split("-"); + final time = widget.timer.toString().split(":"); + + final dateTime = DateTime.utc( + int.parse(date[0]), + int.parse(date[1]), + int.parse(date[2]), + int.parse(time[0]), + int.parse(time[1]), + ); + + final dateTimeDiff = dateTime.toLocal().difference(DateTime.now()); + + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: widget.activityTitle), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer( + flex: 4, + ), + Blob.animatedRandom( + loop: true, + size: 400, + edgesCount: 9, + minGrowth: 7, + controller: blobCtrl, + duration: const Duration(milliseconds: 1500), + styles: BlobStyles(color: ColorConstants.kPrimaryColor), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + 'Next session in', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kBlack, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + // Text( + // '${widget.timer} Days', + // style: TextStyle( + // fontSize: 25, + // color: ColorConstants.kBlack, + // ), + // ), + SlideCountdown( + duration: dateTimeDiff, + // duration: Duration( + // days: days, + // hours: hours, + // minutes: minutes, + // seconds: seconds, + // ), + decoration: + const BoxDecoration(color: Colors.transparent), + textStyle: const TextStyle( + color: ColorConstants.kBlack, fontSize: 30), + separatorStyle: const TextStyle( + color: ColorConstants.kBlack, fontSize: 30), + ) + ], + ), + ), + ), + const Spacer( + flex: 7, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/sessions/live_session_detail.dart b/gsf/lib/views/pages/sessions/live_session_detail.dart new file mode 100644 index 0000000..26af980 --- /dev/null +++ b/gsf/lib/views/pages/sessions/live_session_detail.dart @@ -0,0 +1,417 @@ +// ignore_for_file: deprecated_member_use + +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_custom_tabs/flutter_custom_tabs.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/utc_time_contoller.dart'; +import 'package:intl/intl.dart'; +// import 'package:url_launcher/url_launcher.dart'; + +import '../../../modals/live_session_model.dart'; +import '../../../view_model/global_controller.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class SessionsDetails extends StatefulWidget { + final LiveActivityModel data; + const SessionsDetails({required this.data, Key? key}) : super(key: key); + + @override + State createState() => _SessionsDetailsState(); +} + +class _SessionsDetailsState extends State { + @override + Widget build(BuildContext context) { + // print('DATA OF INNER OF LIVE Sessions ${widget.data.time}'); + // convertTimeInUtcWithouAmAndPm + + var timeInUtc = convertUtcToLocalTime(widget.data.time); + + // var spliUtcTime = timeInUtc.split(' '); + + // var startTimeSessoin = spliUtcTime[0].split(':'); + + // Get the current time in the user's local time zone + final currentTime = DateTime.now(); + // print('timeInUtc currentTime $currentTime'); + + // Create a DateFormat object to format the time in AM/PM format + final timeFormatter = DateFormat.jm(); + // print('timeInUtc timeFormatter $currentTime'); + + // Format the current time in AM/PM format + final formattedTime = timeFormatter.format(currentTime); + + // Parse the time strings into DateTime objects + var sessionStartTime = DateFormat("hh:mm a").parse(timeInUtc); + var userLocalTime = DateFormat("hh:mm a").parse(formattedTime); + final duration = Duration(minutes: widget.data.dayDuration); + + // Add the duration to the sessionStartTime + final sessionEndTime = sessionStartTime.add(duration); + // print('sessionEndTime $sessionEndTime'); + + // Format the sessionEndTime to display + final formattedEndTime = DateFormat.jm().format(sessionEndTime); + var sessionEnddfghTime = DateFormat("hh:mm a").parse(formattedEndTime); + String btnTxt = ''; + bool btnBool = true; + + // Compare the DateTime objects + var isSecondTimeLessThanFirstTime = + userLocalTime.isBefore(sessionStartTime); + var isSecondTimeAfterThanFirstTime = + userLocalTime.isAfter(sessionEnddfghTime); + + // Set the boolValue based on the comparison + // String boolValue = isSecondTimeLessThanFirstTime ? "Wait" : "Join Now";÷÷ + + print('sessionStartTime $isSecondTimeAfterThanFirstTime'); + + if (isSecondTimeLessThanFirstTime == true) { + btnTxt = "Please wait to Join"; + btnBool = true; + } else { + btnTxt = "Join Now"; + btnBool = false; + } + + if (isSecondTimeAfterThanFirstTime == true) { + btnTxt = 'Session has been expired.'; + btnBool = true; + } + print('btnTxt $btnTxt'); + + GlobalController globalContoller = Get.put(GlobalController()); + List benifitActivity = + jsonDecode(widget.data.activityData[0].benefits.toString()); + List preRequisit = + jsonDecode(widget.data.activityData[0].preRequisites.toString()); + // print('zoom link ${data.zoomLink}'); + + _launchZoomMeeting(BuildContext context, String zoomLink) async { + try { + await launch( + zoomLink, + customTabsOption: CustomTabsOption( + toolbarColor: Theme.of(context).primaryColor, + enableDefaultShare: true, + enableUrlBarHiding: true, + showPageTitle: true, + ), + ); + } catch (e) { + print('Error launching Zoom: $e'); + // Handle the error, e.g., show an error message to the user. + } + } + + // void launchZoom(url) async { + // print('ZOOM URL $url'); + // final String zoomAppUrl = url; + + // if (await canLaunch(zoomAppUrl)) { + // await launch(zoomAppUrl); + // } else { + // showDialog( + // context: context, + // builder: (BuildContext context) => AlertDialog( + // title: const Text('Zoom App Not Found'), + // content: const Text( + // 'To join this Zoom meeting, please install the Zoom app.'), + // actions: [ + // TextButton( + // onPressed: () async { + // const String zoomPlayStoreUrl = + // 'https://play.google.com/store/apps/details?id=us.zoom.videomeetings'; + // if (await canLaunch(zoomPlayStoreUrl)) { + // await launch(zoomPlayStoreUrl); + // } else { + // throw 'Could not launch $zoomPlayStoreUrl'; + // } + // }, + // child: const Text('Download'), + // ), + // TextButton( + // onPressed: () => Navigator.pop(context), + // child: const Text('Cancel'), + // ), + // ], + // ), + // ); + // } + // } + + // Future joinZoomMeeting() async { + // if (await launchUrl(Uri.parse(meetingUrl))) { + // await launchUrl(Uri.parse(meetingUrl)); + // } else { + // throw 'Could not launch $meetingUrl'; + // } + // } + + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Live Session'), + ), + body: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + children: [ + Container( + width: Get.size.width * 1, + height: 400, + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage(widget.data.activityDayBanner), + alignment: Alignment.topCenter, + fit: BoxFit.cover, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + // joinZoomMeeting(); + }, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor.withOpacity(0.5), + shape: BoxShape.circle, + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow, + color: ColorConstants.kBlack, + size: 35, + ), + ), + ), + ), + const SizedBox(height: 20), + Text( + widget.data.activityName, + style: const TextStyle( + fontSize: 26, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.6, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + SvgPicture.asset('assets/image/live-streaming.svg'), + const SizedBox(height: 12), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: Container( + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: ColorConstants.kWhite, + ), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + '${widget.data.dayDuration.toString()} min', + // '', + style: const TextStyle( + fontSize: 20, + color: Color(0xffffffff), + // fontWeight: FontWeight.w500, + ), + ), + const Text( + 'Activity Duration', + style: TextStyle( + fontSize: 14, + color: Color(0xffffffff), + fontWeight: FontWeight.w300, + ), + ), + ], + ), + ), + Expanded( + flex: 0, + child: Container( + width: 1, + height: 50, + color: const Color(0xffffffff), + ), + ), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + widget.data.subscription.planName + .split(' ')[0], + style: const TextStyle( + fontSize: 20, + color: Color(0xffffffff), + ), + ), + const Text( + 'Activity Level', + style: TextStyle( + fontSize: 14, + color: Color(0xffffffff), + fontWeight: FontWeight.w300, + // height: 1, + ), + ), + ], + ), + ), + ], + ), + ), + ), + const SizedBox(height: 30), + ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'About the session', + style: TextStyle( + fontSize: 18, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + const SizedBox(height: 10), + Text( + widget.data.description.toString(), + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + const SizedBox(height: 30), + Text( + 'How will this activity help', + style: TextStyle( + fontSize: 18, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.7) + : ColorConstants.kWhite, + ), + ), + const SizedBox(height: 10), + Wrap(children: [ + for (var item in benifitActivity) + Padding( + padding: const EdgeInsets.only(right: 12.0, top: 10), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + item, + style: TextStyle( + fontSize: 14, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + ), + ) + ]), + const SizedBox(height: 20), + Text( + 'How can you prepare yourself for the session', + style: TextStyle( + fontSize: 18, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Wrap(children: [ + for (var item in preRequisit) + Padding( + padding: const EdgeInsets.only(right: 12.0, top: 10), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + item, + style: TextStyle( + fontSize: 14, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + ), + ) + ]), + ], + ), + ), + const SizedBox(height: 80), + ], + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: FullWdtBtn( + disabled: btnBool, + btnText: btnTxt, + onTap: () => btnBool + ? null + : _launchZoomMeeting(context, widget.data.zoomLink), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/sessions/session.dart b/gsf/lib/views/pages/sessions/session.dart new file mode 100644 index 0000000..c661b1d --- /dev/null +++ b/gsf/lib/views/pages/sessions/session.dart @@ -0,0 +1,999 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +// import 'package:gsp_app/modals/past_activity_modal.dart'; +import 'package:gsp_app/modals/upcoming_session_model.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/cj/past_session_services.dart'; +import 'package:gsp_app/views/components/page_animation.dart'; +import 'package:gsp_app/views/pages/Sessions/live_session_detail.dart'; +import 'package:intl/intl.dart'; +import 'package:skeletons/skeletons.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../../../modals/live_session_model.dart'; +import '../../../repository/services/cj/live_activity_service.dart'; +import '../../../repository/services/cj/upcoming_activity_service.dart'; +import '../../../view_model/global_controller.dart'; +import '../../../view_model/utc_time_contoller.dart'; +import '../../components/bottom_navigation.dart'; +import '../../components/btn.dart'; +import '../../components/notification_icon.dart'; +import '../../../view_model/home_controller.dart'; +import '../../theme.dart'; +import '../sidebar.dart'; +import '../signIn/sign_in.dart'; +import 'count_me.dart'; + +class Sessions extends StatefulWidget { + const Sessions({ + Key? key, + this.activeTabIndex = 0, + }) : super(key: key); + + final int activeTabIndex; + + @override + State createState() => _SessionsState(); +} + +class _SessionsState extends State with TickerProviderStateMixin { + late AnimationController _animationController; + // List expanded = [false, false]; + // final List _data = generateItems(4); + + @override + void initState() { + super.initState(); + // LiveActivityServices().getLiveActivitydata(); + _animationController = AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 600), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + ); + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalContoller = Get.find(); + _animationController.forward(); + TabController tabController = TabController(length: 3, vsync: this); + final TabsController controller = TabsController(); + // HomePageController homePageController = Get.put(HomePageController()); + tabController.animateTo(widget.activeTabIndex); + return Scaffold( + key: controller.scaffoldKey, + // backgroundColor: ColorConstants.kBlack, + drawer: const AppDrawer(), + appBar: AppBar( + automaticallyImplyLeading: false, + // backgroundColor: ColorConstants.kBlack, + leading: InkWell( + onTap: controller.openDrawer, + child: Padding( + padding: const EdgeInsets.all(8), + child: Obx( + () => Image.asset( + 'assets/image/${!globalContoller.darkMode.value ? 'menu_dark' : 'menu'}.png', + ), + )), + ), + actions: [ + SizedBox( + child: (controller.isLoggedIn) + ? Row( + children: [ + Padding( + padding: EdgeInsets.all(4.0), + child: NotificationIcon(), + ), + const SizedBox(width: 10), + // Padding( + // padding: const EdgeInsets.all(4), + // child: InkWell( + // splashColor: Colors.transparent, + // onTap: () => Get.to( + // () => const Settings(), + // ), + // child: Icon( + // Icons.settings_outlined, + // color: !globalContoller.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + // ), + // ), + // const SizedBox(width: 20), + ], + ) + : GestureDetector( + onTap: () => Get.off( + () => const SignIn(), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Image.asset( + 'assets/image/logout.png', + width: 30, + ), + ), + ), + ) + ], + bottom: PreferredSize( + preferredSize: const Size.fromHeight(70.0), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: Get.size.width * 0.025, vertical: 10), + child: Stack( + clipBehavior: Clip.none, + children: [ + Obx( + () => Container( + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff2B2B2B), + borderRadius: BorderRadius.circular(28), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 10, + spreadRadius: 2, + ) + ]), + child: TabBar( + isScrollable: false, + labelPadding: EdgeInsets.symmetric( + horizontal: Get.size.width * 0.0, + ), + labelColor: !globalContoller.darkMode.value + ? ColorConstants.kPrimaryColor + : ColorConstants.kBlack, + unselectedLabelColor: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + labelStyle: const TextStyle( + color: ColorConstants.kBlack, + fontFamily: 'SFPRO', + fontSize: 12, + ), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontFamily: 'SFPRO', + color: ColorConstants.kWhite, + ), + indicator: BoxDecoration( + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + borderRadius: BorderRadius.circular(50), + ), + controller: tabController, + // ignore: prefer_const_literals_to_create_immutables + tabs: [ + Tab( + text: 'Live Session', + ), + Tab( + text: 'Upcoming Session', + ), + Tab( + text: 'Previous Sessions', + ), + ], + ), + ), + ), + // Positioned( + // top: -10, + // right: 0, + // child: Container( + // decoration: const BoxDecoration( + // color: Color(0xffCC0101), + // shape: BoxShape.circle, + // ), + // child: const Padding( + // padding: EdgeInsets.all(4.0), + // child: Text( + // '15', + // style: TextStyle( + // fontSize: 13, + // color: ColorConstants.kWhite, + // fontFamily: 'SFPRO', + // ), + // ), + // ), + // ), + // ), + ], + ), + ), + ), + ), + body: AnimatedBuilder( + child: Column( + children: [ + Expanded( + child: TabBarView( + controller: tabController, + children: [ + liveSession(), + upcomingSession(), + previousSession(), + ], + ), + ), + ], + ), + animation: _animationController, + builder: (context, child) => FadeScaleTransition( + animation: _animationController, + child: child, + ), + ), + bottomNavigationBar: BottomNavigation(), + ); + } + + liveSession() { + GlobalController globalContoller = Get.find(); + return FutureBuilder( + future: LiveActivityServices().getLiveActivitydata(), + // initialData: InitialData, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // print('snapshot data live ${snapshot.data}'); + List data = snapshot.data!.data; + // print('length of live datas ${data[0].activityData[0].techerData.teacherName}'); + // print( + // 'snapshot data inner datas of live sessions ${data[0].zoomLink}'); + return data.isNotEmpty + ? Column( + children: [ + const SizedBox(height: 20), + Expanded( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: data.length, + itemBuilder: (context, index) { + var passData = data[index]; + // String meetingUrl = data[index].zoomLink; + // void joinZoomMeeting() async { + // if (await canLaunch(meetingUrl)) { + // await launch(meetingUrl); + // } else { + // throw 'Could not launch $meetingUrl'; + // } + // } + + var timeInUtc = + '${data[index].subscription.planName.split(' ')[0]}: ${data[index].dayDuration} mins - ${convertUtcToLocalTime(data[index].time)}'; + + return Padding( + padding: const EdgeInsets.only(bottom: 20), + child: OpenContainerWrappers( + closeBuild: Container( + height: 280, + width: Get.size.width, + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage( + data[index].activityDayBanner, + ), + alignment: Alignment.topCenter, + // AssetImage( + // 'assets/image/Sessions.jpg', + // ), + fit: BoxFit.cover, + ), + ), + child: Column( + children: [ + const Spacer(), + const SizedBox(height: 10), + // Container( + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor + // .withOpacity(0.5), + // shape: BoxShape.circle, + // ), + // child: GestureDetector( + // // redirect to Zoom for live session + // onTap: () { + // joinZoomMeeting(); + // print("MEEETING URL ${meetingUrl}"); + // }, + // child: const Padding( + // padding: EdgeInsets.all(8.0), + // child: Icon( + // Icons.play_arrow, + // color: ColorConstants.kBlack, + // size: 35, + // ), + // ), + // ), + // ), + Text( + data[index].activityName, + style: TextStyle( + fontSize: 26, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.7, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + timeInUtc, + style: TextStyle( + fontSize: 18, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 8), + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + border: Border.all( + color: const Color(0xffF5F5F5), + width: 1, + ), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(2.0), + child: ClipRRect( + borderRadius: BorderRadius.circular(50), + child: Image.asset( + 'assets/image/gsf_avatar.png', + fit: BoxFit.cover, + filterQuality:FilterQuality.high, + ), + ), + ), + ), + const SizedBox(height: 8), + Text( + 'With ${data[index].activityData.first.techerData.teacherName}', + style: TextStyle( + fontSize: 13, + color: ColorConstants.kWhite, + fontFamily: 'SFPRo', + ), + ), + const SizedBox(height: 7), + SvgPicture.asset( + 'assets/image/live-streaming.svg', + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 50), + child: FullWdtBtn( + btnText: 'Practice Now', + onTap: () => Get.to( + () => + SessionsDetails(data: passData), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ), + openBuild: SessionsDetails( + data: data[index], + ), + ), + ); + }), + ), + ], + ) + : Center( + child: Text( + 'No Session Found ☹️.', + style: TextStyle( + color: !globalContoller.darkMode.value + ? Colors.black + : ColorConstants.kPrimaryColor, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ); + } + return Padding( + padding: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: 4, + itemBuilder: (context, index) => Container( + margin: EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ); + } + + upcomingSession() { + // final List data1 = []; + GlobalController globalContoller = Get.find(); + + return FutureBuilder( + future: UpcomingActivityServices().getUpcomingActivitydata(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // print('snapshot data in upcomimg ${snapshot.data!.data}'); + List data = snapshot.data!.data; + // print( + // 'All data drive ${data[0].subscription.planName.split(' ')[0]}'); + String formatDate(String dateStr) { + DateTime date = DateTime.parse(dateStr); + String formattedDate = DateFormat('d MMMM y').format(date); + return formattedDate; + } + + // print('data[index].activityName ${data[0].activityData.first.techerData.teacherName}'); + + return (data.isNotEmpty) + ? Column( + children: [ + const SizedBox(height: 20), + Expanded( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: data.length, + itemBuilder: (context, index) { + // final dateTime = + // data[index].date.toString().split(' ')[0]; + // DateTime dates = DateTime.parse(dateTime); + // String formattedDate = + // DateFormat('dd MMMM yyyy').format(dates); + var dateTimeStand = + '${data[index].subscription.planName.split(' ')[0]}: ${data[index].dayDuration} mins - ${convertUtcToLocalTime(data[index].time)}'; + + print('dateTimeStand $dateTimeStand'); + return Padding( + padding: const EdgeInsets.only(bottom: 20), + child: OpenContainerWrappers( + closeBuild: Container( + height: 280, + width: Get.size.width, + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage( + data[index].activityDayBanner, + ), + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + ), + child: Column( + children: [ + const Spacer(), + // Container( + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor + // .withOpacity(0.5), + // shape: BoxShape.circle, + // ), + // child: GestureDetector( + // // redirect on count me screen + // // onTap: () => Get.to(() => const VimeoPlayer()), + // child: const Padding( + // padding: EdgeInsets.all(8.0), + // child: Icon( + // Icons.play_arrow, + // color: ColorConstants.kBlack, + // size: 35, + // ), + // ), + // ), + // ), + const SizedBox(height: 10), + Text( + data[index].activityName, + style: TextStyle( + fontSize: 26, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.4, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + '${dateTimeStand}', + // '${data[index].subscription.planName}: ${data[index].activityDuration} mins - ${data[index].time.toString()} ${(int.parse(data[index].time.toString().split(':')[0])) < 12 ? 'AM' : 'PM'} - Yoga', + // '', + style: TextStyle( + fontSize: 18, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 8), + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + border: Border.all( + color: const Color(0xffF5F5F5), + width: 1, + ), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(2.0), + child: ClipRRect( + borderRadius: BorderRadius.circular(50), + child: Image.asset( + 'assets/image/gsf_avatar.png', + fit: BoxFit.cover, + filterQuality:FilterQuality.high, + ), + ), + ), + ), + const SizedBox(height: 8), + Text( + 'With ${data[index].activityData.first.techerData.teacherName}', + style: TextStyle( + fontSize: 13, + color: ColorConstants.kWhite, + fontFamily: 'SFPRo', + ), + ), + const SizedBox(height: 7), + Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(22), + border: Border.all( + color: ColorConstants.kWhite, + width: 1, + ), + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10, vertical: 4), + child: Text( + formatDate(data[index].date), + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite,), + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 50), + child: FullWdtBtn( + btnText: 'Count me in', + onTap: () => Get.to( + () => CountMe( + activityTitle: + data[index].activityName, + date: data[index].date, + timer: data[index].time, + // sDate: , + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ), + openBuild: CountMe( + activityTitle: data[index].activityName, + timer: data[index].time, + date: data[index].date, + ), + ), + ); + })), + ], + ) + : Center( + child: Text( + 'No Session Found ☹️.', + style: TextStyle( + color: !globalContoller.darkMode.value + ? Colors.black + : ColorConstants.kPrimaryColor, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ); + } + return Padding( + padding: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: 4, + itemBuilder: (context, index) => Container( + margin: EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ); + } + + previousSession() { + GlobalController globalContoller = Get.find(); + // final List data1 = []; + // print('Data1 ${data1}'); + // var weekofTheSession = 1; + + Future _launchInBrowser(String url) async { + var urlN = Uri.parse(url); + if (!await launchUrl( + urlN, + mode: LaunchMode.externalApplication, + )) { + throw Exception('Could not launch $url'); + } + } + + int listLen = 0; + // int listLen2 = 0; + // int res = 0; + + // int scheduleIndex = 0; + bool expandTile = false; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + FutureBuilder( + future: PastActivity().getPastActivityData(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // var week index + // print( + // 'Data!.result!.schedule! ${pastData!.result!.schedule![0].pastData![0].day}'); + + return Expanded( + child: pastData?.result != null + ? ListView.builder( + physics: const ScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: pastData!.result!.schedule!.length, + itemBuilder: (context, index) { + var pastDataInData = pastData!.result!.schedule!; + return pastDataInData[index].pastData!.isNotEmpty + ? Container( + margin: const EdgeInsets.only( + bottom: 20, + ), // Set margin around each panel + child: StatefulBuilder( + builder: (context, setState) { + print('length of live datas index $index'); + return ClipRRect( + // borderRadius: BorderRadius.only( + // topLeft: Radius.circular(!expandTile?30:10), + // topRight: Radius.circular(!expandTile?30:10), + // bottomLeft: Radius.circular(!expandTile?30:10), + // bottomRight: Radius.circular(!expandTile?30:10), + // ), + borderRadius: + BorderRadius.circular(30), + child: ExpansionPanelList( + dividerColor: + ColorConstants.kPrimaryColor, + elevation: 1, + expandedHeaderPadding: + const EdgeInsets.all(0), + expansionCallback: + (int index, bool isExpanded) { + // isExpanded = !isExpanded; + if (isExpanded == false) { + setState(() { + expandTile = true; + }); + } else { + setState(() { + expandTile = false; + }); + } + }, + children: [ + ExpansionPanel( + headerBuilder: + (BuildContext context, + bool isExpanded) { + return ListTile( + title: Text( + 'Week ${index + 1}', // "Week ${((e.index) - listLen).abs()}", + style: const TextStyle( + color: ColorConstants + .kPrimaryColor, + ), + ), + ); + }, + body: Padding( + padding: + const EdgeInsets.only( + bottom: 20, + left: 20, + right: 20, + ), + child: + pastDataInData[index] + .pastData! + .isEmpty + ? Center( + child: Text( + 'No Session found ☹️.', + style: + TextStyle( + color: !globalContoller + .darkMode + .value + ? Colors + .black + : ColorConstants + .kPrimaryColor, + fontSize: 16, + ), + textAlign: + TextAlign + .center, + ), + ) + : ListView.builder( + itemCount: + pastDataInData[ + index] + .pastData! + .length, + shrinkWrap: true, + physics: + ScrollPhysics(), + itemBuilder: + (context, + index1) { + // print('pastDataInData[index] ${pastDataInData[index].pastData![index1].url}'); + return Container( + decoration: + BoxDecoration( + border: + Border + .all( + color: ColorConstants + .kPrimaryColor, + ), + borderRadius: + BorderRadius + .circular(5), + ), + margin: EdgeInsets + .only( + bottom: + 20), + padding: + EdgeInsets + .symmetric( + horizontal: + 10, + vertical: + 10, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/calendar.svg'), + SizedBox(width: 10), + Text( + '${pastDataInData[index].pastData![index1].day}', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ], + ), + SizedBox( + height: 8), + SizedBox( + width: 220, + child: + Text( + '${pastDataInData[index].pastData![index1].activityName!}', + // 'Season 26 Intermidiate Morning', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.4, + fontWeight: FontWeight.bold, + ), + // overflow: TextOverflow.clip, + ), + ), + SizedBox( + height: 10), + Row( + children: [ + SvgPicture.asset('assets/image/duration.svg'), + SizedBox(width: 10), + Text( + 'Duration ${pastDataInData[index].pastData![index1].duration} min', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ], + ) + ], + ), + Container( + decoration: + BoxDecoration( + border: + Border.all( + color: + ColorConstants.kPrimaryColor, + width: + 2, + ), + shape: + BoxShape.circle, + ), + child: + GestureDetector( + // redirect to Zoom for live session + onTap: + () { + _launchInBrowser('${pastDataInData[index].pastData![index1].url}'); + // _launchURL(e.pastData![index].url); + }, + child: + const Padding( + padding: + EdgeInsets.all(3.0), + child: + Icon( + Icons.play_arrow_rounded, + color: ColorConstants.kPrimaryColor, + size: 35, + ), + ), + ), + ), + ], + ), + ); + }, + ), + ), + isExpanded: expandTile, + ), + ], + ), + ); + }, + ), + ) + : const SizedBox(); + }, + ) + : Center( + child: Text( + 'No Session found ☹️.', + style: TextStyle( + color: !globalContoller.darkMode.value + ? Colors.black + : ColorConstants.kPrimaryColor, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ), + ); + } + return Padding( + padding: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: 2, + itemBuilder: (context, index) => Container( + margin: const EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ), + ], + ), + ); + } + + @override + void dispose() { + super.dispose(); + _animationController.dispose(); + } +} + +class Item { + Item({ + // required this.expandedValue, + required this.headerValue, + this.isExpanded = false, + }); + + // Widget expandedValue; + String headerValue; + bool isExpanded; +} + +List generateItems(int count) { + return List.generate(count, (int index) { + return Item( + headerValue: 'Week ${index + 1}', + // expandedValue: Text('data $index'), + ); + }); +} diff --git a/gsf/lib/views/pages/sessions/upcoming_session_details.dart b/gsf/lib/views/pages/sessions/upcoming_session_details.dart new file mode 100644 index 0000000..fc74b14 --- /dev/null +++ b/gsf/lib/views/pages/sessions/upcoming_session_details.dart @@ -0,0 +1,493 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class UpcomingSessionDetails extends StatelessWidget { + const UpcomingSessionDetails({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Upcoming Session'), + ), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + width: Get.size.width * 1, + height: 400, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'assets/image/innerPageDetails.jpg', + ), + alignment: Alignment.topCenter, + fit: BoxFit.cover, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor.withOpacity(0.5), + shape: BoxShape.circle, + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow, + color: ColorConstants.kBlack, + size: 35, + ), + ), + ), + const SizedBox(height: 20), + const Text( + 'Yoga for Stress Relief', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.6, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + SvgPicture.asset('assets/image/live-streaming.svg'), + const SizedBox(height: 12), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: Container( + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: ColorConstants.kWhite, + ), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + Text( + '60 mins', + style: TextStyle( + fontSize: 20, + color: Color(0xffD9D9D9), + ), + ), + Text( + 'Activity Duration', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w300, + ), + ), + ], + ), + ), + Expanded( + flex: 0, + child: Container( + width: 1, + height: 50, + color: const Color(0xffD9D9D9), + ), + ), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + Text( + 'Beginner', + style: TextStyle( + fontSize: 20, + color: Color(0xffD9D9D9), + ), + ), + Text( + 'Activity Level', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w300, + // height: 1, + ), + ), + ], + ), + ), + ], + ), + ), + ), + const SizedBox(height: 30), + ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 22), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'About the session', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 10), + const Text( + 'Discard all your stress with this 45 min yoga session with certified yoga specialist Ellie Jones. Enhance your breathing and relax your mind with simple and effective yoga techniques.', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 30), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Routine', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Warm Up', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '15 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Workout', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '35 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Cool Down', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '10 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + ], + ), + const SizedBox(height: 30), + const Text( + 'How will this activity help', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Full Body Workout', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Increased Lung Capacity', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 30), + const Text( + 'How can you prepare yourself for the session', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Yoga Mat', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Bottle of water', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 15), + const Text( + 'Previously Held Activity', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Stack( + children: [ + Container( + height: 190, + width: Get.size.width, + decoration: BoxDecoration( + image: const DecorationImage( + image: AssetImage('assets/image/cardio.jpg'), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(15), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor + .withOpacity(0), + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: ColorConstants.kPrimaryColor)), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow_outlined, + color: ColorConstants.kPrimaryColor, + size: 45, + ), + ), + ), + ], + ), + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + height: 50, + decoration: BoxDecoration( + color: ColorConstants.kBlack.withOpacity(0.3), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + 'Level- Intermediate 40 Min', + style: TextStyle( + fontSize: 15, + color: ColorConstants.kWhite, + ), + ), + ), + Expanded( + flex: 0, + child: SizedBox( + width: 20, + ), + ), + Expanded( + flex: 2, + child: Text( + 'Level- Intermediate 40 Min', + style: TextStyle( + fontSize: 15, + color: ColorConstants.kWhite, + ), + ), + ), + ], + ), + ), + ), + ), + ], + ) + ], + ), + ), + const SizedBox(height: 80), + ], + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: FullWdtBtn( + btnText: 'Count me in', + onTap: () {}, + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/settings/accounts.dart b/gsf/lib/views/pages/settings/accounts.dart new file mode 100644 index 0000000..3001599 --- /dev/null +++ b/gsf/lib/views/pages/settings/accounts.dart @@ -0,0 +1,393 @@ +import 'dart:io' show Platform; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/views/pages/biomateric.dart/account_controller.dart'; +import 'package:gsp_app/views/pages/biomateric.dart/face_id.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; +import 'change_password.dart'; +import 'update_mobile_number.dart'; + +class Accounts extends StatefulWidget { + const Accounts({Key? key}) : super(key: key); + + @override + State createState() => _AccountsState(); +} + +class _AccountsState extends State { + final box = GetStorage(); + + bool get isFingerPrintStoreTest => box.read("fingerPrint") ?? false; + + @override + Widget build(BuildContext context) { + // print('fingerPrint test${isFingerPrintStoreTest}'); + // print('default value $isFingerPrintStoreTest'); + // AccountController accountController = Get.put(AccountController()); + RxBool _switchValue = false.obs; + // bool fingerPrintStore = box.read("fingerPrint"); + + // RxBool switchValue1 = false.obs; + RxBool switchValue2 = false.obs; + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Account'), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // const SizedBox(height: 20), + // Text( + // 'Contact Details', + // style: TextStyle( + // fontSize: 18, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffD9D9D9), + // ), + // ), + // const SizedBox(height: 10), + // Container( + // height: 50, + // width: Get.size.width, + // decoration: BoxDecoration( + // color: (brightness == Brightness.light) + // ? Colors.white + // : const Color(0xff212121), + // borderRadius: BorderRadius.circular(10), + // boxShadow: [ + // BoxShadow( + // color: ColorConstants.kBlack.withOpacity(0.1), + // blurRadius: 10, + // spreadRadius: 2, + // ), + // ], + // ), + // child: Padding( + // padding: + // const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8), + // child: InkWell( + // onTap: () { + // Get.to( + // () => const UpdateMobileNumber(), + // ); + // }, + // child: Row( + // children: [ + // Icon( + // Icons.phone_outlined, + // size: 35, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + // const SizedBox(width: 8), + // Text( + // 'Phone Number', + // style: TextStyle( + // fontSize: 19, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffD9D9D9), + // ), + // ), + // ], + // ), + // ), + // ), + // ), + const SizedBox(height: 30), + Text( + 'Security Setting', + style: TextStyle( + fontSize: 18, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 10), + Container( + width: Get.size.width, + height: 50, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? Colors.white + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 10, + spreadRadius: 2, + ), + ], + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8), + child: InkWell( + onTap: () { + Get.to( + () => const ChangePassword(), + ); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/image/setting/${(brightness == Brightness.light) ? 'passwordreset_black' : 'passwordreset'}.svg'), + const SizedBox(width: 15), + Text( + 'Password reset', + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + ], + ), + ), + ), + ), + const SizedBox(height: 15), + if (Platform.isAndroid) ...[ + Container( + width: Get.size.width, + height: 50, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? Colors.white + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 10, + spreadRadius: 2, + ), + ], + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8), + child: Row( + children: [ + SvgPicture.asset( + 'assets/image/setting/${(brightness == Brightness.light) ? 'lock_black' : 'lock'}.svg'), + const SizedBox(width: 22), + Text( + 'Fingerprint', + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + Transform.scale( + scale: 0.8, + child: CupertinoSwitch( + activeColor: ColorConstants.kBlack, + value: isFingerPrintStoreTest, + trackColor: const Color(0xff333333), + thumbColor: const Color(0xffBBF046), + onChanged: (value) async { + value = isFingerPrintStoreTest; + setState(() { + if (isFingerPrintStoreTest == true) { + box.write('fingerPrint', false); + // print(box.read('fingerPrint')); + } else { + box.write('fingerPrint', true); + print(box.read('fingerPrint')); + // await LocalAuth.authenticate(); + } + }); + + if (box.read('fingerPrint') == true) { + await LocalAuth.authenticate(); + } + + print( + 'fingerPrint test value $isFingerPrintStoreTest'); + + // if (isFingerPrintStoreTest) { + // box.write('fingerPrint', false); + // print(' true ${isFingerPrintStoreTest}'); + // } else { + // box.write('fingerPrint', true); + // print('false ${isFingerPrintStoreTest}'); + // } + // print(box().read('fingerPrint')); + + // if (value == true) { + // box().write('fingerPrint', true); + // } + // box().read('fingerPrint') == value; + // if (box().read('fingerPrint') == false) { + // await LocalAuth.authenticate(); + // box().write('fingerPrint', true); + // } else { + // box().write('fingerPrint', false); + // } + // accountController.switchValue1.value = + // await LocalAuth.authenticate(); + // box().write('fingerPrint', + // accountController.switchValue1.value); + // if (await LocalAuth.authenticate() == true) { + // accountController.switchValue1.value = false; + // print( + // 'first ${accountController.switchValue1.value}'); + // } else { + // accountController.switchValue1.value = true; + // print( + // 'second ${accountController.switchValue1.value}'); + // } + }, + ), + ), + ], + ), + ), + ), + ] else if (Platform.isIOS) ...[ + Container( + width: Get.size.width, + height: 50, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? Colors.white + : const Color(0xff212121), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 10, + spreadRadius: 2, + ), + ], + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8), + child: Row( + children: [ + SvgPicture.asset( + 'assets/image/setting/${(brightness == Brightness.light) ? 'lock_black' : 'lock'}.svg'), + const SizedBox(width: 22), + Text( + 'Face ID', + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + Transform.scale( + scale: 0.8, + child: CupertinoSwitch( + activeColor: ColorConstants.kBlack, + value: isFingerPrintStoreTest, + trackColor: const Color(0xff333333), + thumbColor: const Color(0xffBBF046), + onChanged: (value) async { + value = isFingerPrintStoreTest; + setState(() { + if (isFingerPrintStoreTest == true) { + box.write('fingerPrint', false); + // print(box.read('fingerPrint')); + } else { + box.write('fingerPrint', true); + print(box.read('fingerPrint')); + // await LocalAuth.authenticate(); + } + }); + + if (box.read('fingerPrint') == true) { + await LocalAuth.authenticate(); + } + + print( + 'fingerPrint test value $isFingerPrintStoreTest'); + }, + ), + ), + ], + ), + ), + ), + ], + const SizedBox(height: 15), + // Container( + // width: Get.size.width, + // height: 50, + // decoration: BoxDecoration( + // color: (brightness == Brightness.light) + // ? Colors.white + // : const Color(0xff212121), + // boxShadow: [ + // BoxShadow( + // color: ColorConstants.kBlack.withOpacity(0.1), + // blurRadius: 10, + // spreadRadius: 2, + // ), + // ], + // borderRadius: BorderRadius.circular(10), + // ), + // child: Padding( + // padding: + // const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8), + // child: Row( + // children: [ + // SvgPicture.asset( + // 'assets/image/setting/${(brightness == Brightness.light) ? 'notification_black' : 'notification'}.svg'), + // const SizedBox(width: 22), + // Text( + // 'Notification', + // style: TextStyle( + // fontSize: 19, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffD9D9D9), + // ), + // ), + // const Spacer(), + // Transform.scale( + // scale: 0.8, + // child: Obx( + // () => CupertinoSwitch( + // activeColor: ColorConstants.kBlack, + // value: switchValue2.value, + // trackColor: const Color(0xff333333), + // thumbColor: const Color(0xffBBF046), + // onChanged: (bool value) { + // switchValue2.value = value; + // }), + // ), + // ), + // ], + // ), + // ), + // ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/settings/change_password.dart b/gsf/lib/views/pages/settings/change_password.dart new file mode 100644 index 0000000..2cd5099 --- /dev/null +++ b/gsf/lib/views/pages/settings/change_password.dart @@ -0,0 +1,509 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/api/base_manager.dart'; +import 'package:gsp_app/view_model/ResetPassword.dart'; +import 'package:gsp_app/views/pages/home/home.dart'; +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'accounts.dart'; + +class ChangePassword extends StatefulWidget { + const ChangePassword({Key? key}) : super(key: key); + + @override + State createState() => _ChangePasswordState(); +} + +class _ChangePasswordState extends State { + final TextEditingController _newPassword = TextEditingController(); + final TextEditingController _confirmPassword = TextEditingController(); + bool _newPasswordVisible = false; + bool _confirmPasswordVisible = false; + bool _isPasswordEightCar = false; + bool _isHasOneNumber = false; + bool _isHasSymboleOrCaptital = false; + final _form = GlobalKey(); + onPasswordChnage(String newPassword) { + setState(() { + final numricRegex = RegExp(r'[0-9]'); + final alphaRegex = RegExp(r'[A-Z]|(?=.*[@$!%*#?&])'); + + _isPasswordEightCar = false; + if (newPassword.length >= 8) _isPasswordEightCar = true; + + _isHasOneNumber = false; + if (numricRegex.hasMatch(newPassword)) _isHasOneNumber = true; + + _isHasSymboleOrCaptital = false; + if (alphaRegex.hasMatch(newPassword)) _isHasSymboleOrCaptital = true; + }); + } + + _validateInputs() async { + final isValid = _form.currentState?.validate(); + if (isValid! && + _isPasswordEightCar && + _isHasOneNumber && + _isHasSymboleOrCaptital) { + Map updata = { + "user_id": GetStorage().read("user_id"), + "old_pass": _confirmPassword.text, + "new_pass": _newPassword.text, + }; + final data = await ResetPassword().resetpasswordapi(updata); + + if (data.status == ResponseStatus.SUCCESS) { + if (data.data['status'] == 200) { + // _newPassword.clear(); + // _confirmPassword.clear(); + Fluttertoast.showToast(msg: data.data['message']); + Get.to(() => const Accounts()); + } else if (data.data['status'] == 201) { + Get.showSnackbar(GetSnackBar( + //title: + message: "${data.data['message']}", + duration: const Duration(seconds: 4), + )); + } + } else { + Fluttertoast.showToast(msg: data.message); + } + } else { + Fluttertoast.showToast(msg: "Please fill all details"); + } + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Change Password')), + body: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: SingleChildScrollView( + child: Form( + key: _form, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Text( + 'Current Password', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + // New Password* + // const SizedBox( + // height: 40, + // ), + SizedBox( + child: Column( + children: [ + TextFormField( + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: _confirmPassword, + obscureText: !_confirmPasswordVisible, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 25, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : const Color(0xffffffff).withOpacity(0.8), + fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + filled: true, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _confirmPasswordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.5), + ), + onPressed: () { + setState(() { + _confirmPasswordVisible = + !_confirmPasswordVisible; + }); + }, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + isDense: true, + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your password'; + } + // if (value.length < 8) { + // return 'Must contain atleast 8 characters'; + // } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox( + height: 25, + ), + ], + ), + ), + const SizedBox(height: 10), + SizedBox( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'New Password', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + ), + ), + const SizedBox(height: 10), + TextFormField( + onChanged: (newPassword) => + onPasswordChnage(newPassword), + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: _newPassword, + obscureText: !_newPasswordVisible, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.transparent + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 25, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: const Color(0xffffffff).withOpacity(0.8), + fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + filled: true, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _newPasswordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.5) + : const Color(0xffffffff).withOpacity(0.5), + ), + onPressed: () { + setState(() { + _newPasswordVisible = !_newPasswordVisible; + }); + }, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + isDense: true, + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your password'; + } + if (value.length < 8) { + return 'Must contain atleast 8 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox( + height: 25, + ), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isPasswordEightCar + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + 'Has at least 8 characters.', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isHasSymboleOrCaptital + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + 'Has at least 1 uppercase letter or symbol.', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + AnimatedContainer( + duration: const Duration( + milliseconds: 500, + ), + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + border: Border.all( + color: ColorConstants.kPrimaryColor, + ), + ), + child: _isHasOneNumber + ? const Icon( + Icons.check, + color: ColorConstants.kPrimaryColor, + size: 15, + ) + : const SizedBox(), + ), + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + 'Has a number', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffffffff), + ), + ), + ) + ], + ), + ], + ), + ), + const SizedBox(height: 50), + FullWdtBtn( + btnText: 'Save', + onTap: () { + _validateInputs(); + // Get.off( + // () => const Accounts(), + // ); + }, + ), + const SizedBox(height: 20), + Container( + width: screenSize.width * 1, + height: 50, + decoration: BoxDecoration( + color: const Color(0xffD9D9D9), + borderRadius: BorderRadius.circular(30), + ), + child: Center( + child: InkWell( + onTap: () => Get.back(), + child: const Text( + 'Cancel', + style: TextStyle( + fontSize: 16, + color: Color(0xff000000), + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + ), + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/settings/ratings.dart b/gsf/lib/views/pages/settings/ratings.dart new file mode 100644 index 0000000..6b90f23 --- /dev/null +++ b/gsf/lib/views/pages/settings/ratings.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class Ratings extends StatefulWidget { + const Ratings({Key? key}) : super(key: key); + + @override + State createState() => _RatingsState(); +} + +class _RatingsState extends State { + var _rating = 0; + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + child: CustomAppBars(titleHead: 'Rate Us'), + preferredSize: const Size.fromHeight(60), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + SvgPicture.asset('assets/image/ratings.svg'), + const SizedBox(height: 10), + const Text( + 'Enjoy the App ?', + style: TextStyle( + fontSize: 22, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 10), + const Text( + 'Rate your experience using Getsetfit so far', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: List.generate( + 5, + (index) => IconButton( + onPressed: () { + setState(() { + _rating = index + 1; + }); + }, + icon: index < _rating + ? const Icon( + Icons.star, + color: ColorConstants.kPrimaryColor, + size: 30, + ) + : const Icon( + Icons.star_border, + color: ColorConstants.kPrimaryColor, + size: 30, + ), + ), + ), + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: FullWdtBtn(btnText: 'Submit', onTap: () {}), + ), + const Spacer( + flex: 2, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/settings/setting_main.dart b/gsf/lib/views/pages/settings/setting_main.dart new file mode 100644 index 0000000..9e27330 --- /dev/null +++ b/gsf/lib/views/pages/settings/setting_main.dart @@ -0,0 +1,150 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/settings/ratings.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; +import '../feedback/feedback.dart'; +import 'accounts.dart'; + +class Settings extends StatefulWidget { + Settings({Key? key}) : super(key: key); + + @override + State createState() => _SettingsState(); +} + +class _SettingsState extends State { + PackageInfo? packageInfo; + initPackageinfo() async { + packageInfo = await PackageInfo.fromPlatform(); + } + + @override + void initState() { + initPackageinfo(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Setting'), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + accountsTab( + 'Account', + () { + Get.to(() => const Accounts()); + }, + ), + // const SizedBox(height: 10), + // accountsTab( + // 'Rate Us', + // () { + // Get.to( + // () => const Ratings(), + // ); + // }, + // ), + // const SizedBox(height: 10), + // accountsTab( + // 'Feedback', + // () { + // Get.to( + // () => const FeedBack(), + // ); + // }, + // ), + const SizedBox(height: 10), + Row( + children: [ + Text( + 'App Version', + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + const Spacer(), + if (Platform.isIOS) + Text( + packageInfo?.version ?? "1.3.12", + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xff979292), + ), + ), + if (Platform.isAndroid) + Text( + packageInfo?.buildNumber ?? "14", + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xff979292), + ), + ), + ], + ), + ], + ), + ), + ); + } + + accountsTab(String title, VoidCallback ontap) { + final brightness = Get.theme.brightness; + return InkWell( + onTap: ontap, + child: Container( + height: 50, + width: Get.size.width, + decoration: BoxDecoration( + color: (brightness == Brightness.light) + ? Colors.white + : const Color(0xff212121), + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.1), + blurRadius: 10, + spreadRadius: 2, + ), + ], + ), + child: Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0), + child: Text( + title, + style: TextStyle( + fontSize: 19, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + ), + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/settings/update_mobile_number.dart b/gsf/lib/views/pages/settings/update_mobile_number.dart new file mode 100644 index 0000000..76f7d03 --- /dev/null +++ b/gsf/lib/views/pages/settings/update_mobile_number.dart @@ -0,0 +1,353 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'update_otp.dart'; + +class UpdateMobileNumber extends StatefulWidget { + const UpdateMobileNumber({Key? key}) : super(key: key); + + @override + State createState() => _UpdateMobileNumberState(); +} + +class _UpdateMobileNumberState extends State { + // Country? _selectedCountry; + final TextEditingController _phone = TextEditingController(); + var _formKey = GlobalKey(); + + // void initCountry() async { + // final country = await getDefaultCountry(context); + // setState(() { + // _selectedCountry = country; + // }); + // } + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: ''), + ), + body: GestureDetector( + onTap: () => Get.focusScope?.unfocus(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + Text( + 'Update your mobile number', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w500, + ), + ), + Text( + 'Will be verified in the next step', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.8) + : const Color(0xffD9D9D9).withOpacity(0.8), + ), + ), + const SizedBox(height: 45), + Text( + 'New Mobile Number*', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + formUI(), + const Spacer(flex: 4), + FullWdtBtn( + btnText: 'Proceed', + onTap: () => Get.off( + () => const UpdateOtp(), + ), + ), + const Spacer(flex: 1), + ], + ), + ), + ), + ); + } + + formUI() { + // final country = _selectedCountry; + final brightness = Get.theme.brightness; + return Form( + key: _formKey, + child: Column( + children: [ + ClipPath( + clipper: ShapeBorderClipper( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Expanded( + // flex: 2, + // child: (country == null) + // ? Container( + // height: 60, + // width: 80, + // decoration: BoxDecoration( + // color: (brightness == Brightness.light) + // ? Colors.grey.withOpacity(0.2) + // : const Color(0xff212121), + // borderRadius: const BorderRadius.only( + // bottomLeft: Radius.circular(10), + // ), + // ), + // child: InkWell( + // onTap: () { + // _onPressedShowBottomSheet(); + // }, + // child: Column( + // children: [ + // Expanded( + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text( + // '+91', + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // // 'hello', + // // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 16, + // color: + // (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontWeight: FontWeight.normal, + // ), + // ), + // Icon( + // Icons.keyboard_arrow_down, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff), + // size: 18, + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ) + // : Container( + // height: 60, + // width: 80, + // decoration: BoxDecoration( + // color: (brightness == Brightness.light) + // ? Colors.grey.withOpacity(0.2) + // : const Color(0xff212121), + // borderRadius: BorderRadius.circular(0), + // ), + // child: InkWell( + // onTap: () { + // _onPressedShowBottomSheet(); + // }, + // child: Column( + // children: [ + // Expanded( + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text( + // country.callingCode, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // // 'hello', + // // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 16, + // color: + // (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff), + // fontFamily: 'Helvetica', + // fontWeight: FontWeight.normal, + // ), + // ), + // Icon( + // Icons.keyboard_arrow_down, + // color: (brightness == Brightness.light) + // ? ColorConstants.kBlack + // : const Color(0xffffffff), + // size: 18, + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ), + // ), + Expanded( + flex: 0, + child: Container( + color: const Color(0xffffffff).withOpacity(0.5), + width: 1, + height: 60, + ), + ), + Expanded( + flex: 8, + child: Padding( + padding: const EdgeInsets.only(left: 0, right: 0), + child: TextFormField( + style: TextStyle( + // color: Color(0xffffffff), + color: (brightness == Brightness.light) + ? const Color(0xff000000) + : const Color(0xffffffff), + fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + fillColor: (brightness == Brightness.light) + ? Colors.grey.withOpacity(0.2) + : const Color(0xff212121), + errorMaxLines: 3, + hintText: "Mobile Number*", + contentPadding: const EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 25, + ), + hintStyle: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xffffffff).withOpacity(0.6), + fontFamily: 'Helvetica', + ), + filled: true, + border: const OutlineInputBorder( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10), + topRight: Radius.circular(10), + ), + borderSide: BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorBorder: const OutlineInputBorder( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10), + topRight: Radius.circular(10), + ), + borderSide: BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: const OutlineInputBorder( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10), + topRight: Radius.circular(10), + ), + borderSide: BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + focusedBorder: const OutlineInputBorder( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10), + topRight: Radius.circular(10), + ), + borderSide: BorderSide( + width: 1, + color: Colors.transparent, + ), + ), + isDense: true, + ), + controller: _phone, + keyboardType: TextInputType.number, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your number'; + } + if (!RegExp(r"^[0-9]{10,12}$").hasMatch(value)) { + return 'Number allowed between 10-12 digits'; + } + return null; + }, + onSaved: (name) {}, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 180), + // FullWdtBtn(btnText: 'Proceed', onTap: () {}), + ], + ), + ); + } + + // void _onPressedShowBottomSheet() async { + // final country = await showCountryPickerSheet( + // context, + // // title: Text('Country Codes'), + // cancelWidget: Padding( + // padding: const EdgeInsets.only(top: 8, right: 25), + // child: Align( + // alignment: Alignment.centerRight, + // child: InkWell( + // onTap: () => Navigator.pop(context), + // child: const Text( + // 'Cancel', + // style: TextStyle( + // fontSize: 16, + // color: Color(0xff000000), + // ), + // ), + // ), + // ), + // ), + // ); + // if (country != null) { + // setState(() { + // _selectedCountry = country; + // }); + // } + // } +} diff --git a/gsf/lib/views/pages/settings/update_otp.dart b/gsf/lib/views/pages/settings/update_otp.dart new file mode 100644 index 0000000..198bb04 --- /dev/null +++ b/gsf/lib/views/pages/settings/update_otp.dart @@ -0,0 +1,209 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +// import 'package:alt_sms_autofill/alt_sms_autofill.dart'; +import 'package:flutter/services.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'accounts.dart'; + +class UpdateOtp extends StatefulWidget { + const UpdateOtp({Key? key}) : super(key: key); + + @override + State createState() => _UpdateOtpState(); +} + +class _UpdateOtpState extends State { + final textEditingController1 = TextEditingController(); + + Future initSmsListener() async { + String? comingSms; + // try { + // // comingSms = await AltSmsAutofill().listenForSms; + // } on PlatformException { + // comingSms = 'Failed to get Sms.'; + // } + if (!mounted) return; + + setState(() { + textEditingController1.text = comingSms.toString(); + }); + } + + @override + void initState() { + super.initState(); + initSmsListener(); + } + + @override + void dispose() { + textEditingController1.dispose(); + // AltSmsAutofill().unregisterListener(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + final brightness = Get.theme.brightness; + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: '')), + body: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 50), + Text( + 'We sent a code to your number ', + style: TextStyle( + fontSize: 16, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w500, + ), + ), + RichText( + text: TextSpan( + children: [ + TextSpan( + text: '-------713 ', + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontSize: 16), + ), + TextSpan( + text: 'Change', + recognizer: TapGestureRecognizer() + ..onTap = (() => Get.back()), + style: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 16, + decoration: TextDecoration.underline, + ), + ), + ], + ), + ), + const SizedBox(height: 45), + Text( + 'Enter OTP*', + style: TextStyle( + fontSize: 14, + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + otpWidget(), + const SizedBox(height: 50), + Align( + alignment: Alignment.center, + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Don\'t receive your code? ', + style: TextStyle( + color: (brightness == Brightness.light) + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontSize: 16), + ), + TextSpan( + text: 'Resend', + recognizer: TapGestureRecognizer()..onTap = () {}, + style: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 16, + decoration: TextDecoration.underline, + ), + ), + ], + ), + ), + ), + const Spacer(flex: 4), + FullWdtBtn( + btnText: 'Proceed', + onTap: () { + Get.off( + () => Accounts(), + ); + }, + ), + const Spacer(flex: 1), + ], + ), + ), + ), + ); + } + + otpWidget() { + final brightness = Get.theme.brightness; + return PinCodeTextField( + appContext: context, + pastedTextStyle: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + length: 4, + textStyle: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + obscureText: false, + animationType: AnimationType.fade, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp("[0-9]")), + ], + pinTheme: PinTheme( + shape: PinCodeFieldShape.box, + borderRadius: BorderRadius.circular(10), + fieldHeight: 60, + fieldWidth: 60, + inactiveFillColor: Colors.transparent, + inactiveColor: const Color(0xff707070), + selectedColor: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + selectedFillColor: Colors.transparent, + activeFillColor: Colors.transparent, + activeColor: ColorConstants.kPrimaryColor, + ), + cursorColor: (brightness == Brightness.light) + ? ColorConstants.kBlack + : Colors.white, + animationDuration: const Duration(milliseconds: 300), + enableActiveFill: true, + controller: textEditingController1, + keyboardType: TextInputType.number, + onCompleted: (v) { + //do something or move to next screen when code complete + }, + onChanged: (value) { + // print(value); + setState(() { + // print('$value'); + }); + }, + ); + } +} diff --git a/gsf/lib/views/pages/shareThoutgh/mission_impossible.dart b/gsf/lib/views/pages/shareThoutgh/mission_impossible.dart new file mode 100644 index 0000000..88219b1 --- /dev/null +++ b/gsf/lib/views/pages/shareThoutgh/mission_impossible.dart @@ -0,0 +1,123 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/btn.dart'; +import '../../theme.dart'; +import '../home/home_page.dart'; + +class MissionPossible extends StatefulWidget { + const MissionPossible({Key? key}) : super(key: key); + + @override + State createState() => _MissionPossibleState(); +} + +class _MissionPossibleState extends State { + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + body: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/share_thougth.png'), + fit: BoxFit.cover, + ), + ), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -80, + left: 0, + right: 0, + child: Align( + alignment: Alignment.center, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + width: 100, + height: 100, + child: Image.asset( + 'assets/image/feedback_img/power.png', + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + ), + ), + Column( + children: [ + const SizedBox(height: 56), + const Text( + '"There is nothing', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + const Text( + 'IMPOSSIBLE', + style: TextStyle( + fontSize: 42, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w600, + letterSpacing: 3, + height: 1, + ), + ), + const Text( + 'to they who will try"', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + height: 1, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + const SizedBox(height: 35), + FullWdtBtn( + btnText: 'Let\'s Go', + onTap: () { + Get.offAll( + // () => ShowCaseWidget( + // builder: Builder( + // builder: (context) => const HomePage(), + // ), + // ), + () => const HomePage(), + ); + }, + ) + ], + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/shareThoutgh/share_thought.dart b/gsf/lib/views/pages/shareThoutgh/share_thought.dart new file mode 100644 index 0000000..ce56e25 --- /dev/null +++ b/gsf/lib/views/pages/shareThoutgh/share_thought.dart @@ -0,0 +1,121 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/btn.dart'; +import '../../components/mood_meter.dart'; +import '../../theme.dart'; +import 'mission_impossible.dart'; + +class ShareThought extends StatefulWidget { + const ShareThought({Key? key}) : super(key: key); + + @override + State createState() => _ShareThoughtState(); +} + +class _ShareThoughtState extends State { + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + body: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/share_thougth.png'), + fit: BoxFit.cover, + ), + ), + // width: screenSize.width * 1, + // height: screenSize.height * 1, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -80, + left: 0, + right: 0, + child: Align( + alignment: Alignment.center, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + width: 100, + height: 100, + child: Image.asset( + 'assets/image/avatar.png', + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + ), + ), + Column( + children: [ + const SizedBox(height: 56), + RichText( + text: const TextSpan( + children: [ + TextSpan( + text: 'Hey ', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w500, + ), + ), + TextSpan( + text: 'Aditya', + style: TextStyle( + fontSize: 17, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + ), + const Text( + 'How are you feeling?', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 20), + const MoodOMeter(), + const SizedBox(height: 35), + FullWdtBtn( + btnText: 'Share your thoughts!', + onTap: () { + Get.to(() => const MissionPossible()); + }, + ) + ], + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/sidebar.dart b/gsf/lib/views/pages/sidebar.dart new file mode 100644 index 0000000..33baa60 --- /dev/null +++ b/gsf/lib/views/pages/sidebar.dart @@ -0,0 +1,655 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/QuizApis.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/FirstQuestion.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/Helper/StorageService.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/PeriodSelection.dart'; +import 'package:gsp_app/views/pages/MenstrualCycleTracker/TrackerHomePage.dart'; +import 'package:gsp_app/views/pages/podcast/podcast.dart'; +import 'package:gsp_app/views/pages/profile/pages/profile_page.dart'; +import 'package:gsp_app/views/pages/quiz/quiz_home.dart'; +import 'package:gsp_app/views/pages/signIn/complete_profile_before_sign_in.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../../view_model/global_controller.dart'; +import '../../view_model/home_controller.dart'; +import '../../repository/services/complete_profile_service.dart'; +import '../../repository/services/edit_profile_service.dart'; +import '../theme.dart'; +import 'contact_us.dart'; +import 'faq/about_gsf.dart'; +import 'faq/about_gsf_accordian.dart'; +import 'insta/insta_clip_list.dart'; +import 'insta/insta_web_view.dart'; +import 'test/upcoming_data_utc.dart'; + +class AppDrawer extends StatefulWidget { + const AppDrawer({Key? key}) : super(key: key); + + @override + State createState() => _AppDrawerState(); +} + +class _AppDrawerState extends State { + bool isDarkModeN = ThemseServices().loadThemeFromBox(); + + final TabsController controller = TabsController(); + final CompleteProfileController completeProfileController = + Get.put(CompleteProfileController(), permanent: true); + + final EditProfileController getProfileData = Get.put(EditProfileController()); + + bool get isScaleAdd => box.read("addScale"); + AppDataController appDataController = Get.find(); + GlobalController globalContoller = Get.put(GlobalController()); + + @override + void initState() { + QuizeApis().showQuiz(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + // print('globalContoller sidebar ${globalContoller.darkMode}'); + return Drawer( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 50), + //profile + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? Colors.transparent + : const Color(0xff2B2B2B), + borderRadius: BorderRadius.circular(14), + ), + child: Obx(() => Row( + children: [ + //pic + Container( + width: 52, + height: 52, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + width: 1, + color: Colors.white, + ), + shape: BoxShape.circle, + ), + child: appDataController.profilePicUrl.value.isEmpty + ? const Icon( + Icons.person_rounded, + size: 36, + color: Colors.white, + ) + : CircleAvatar( + backgroundImage: NetworkImage( + correctImgUrl(appDataController + .profilePicUrl.value), + ), + backgroundColor: Colors.transparent, + ), + ), + const SizedBox(width: 12), + Expanded( + child: Obx( + () => Text( + appDataController.name.value, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 16), + ), + )), + IconButton( + icon: const Icon( + Icons.edit_outlined, + // color: Colors.white, + ), + onPressed: () { + Get.back(); + Get.to(const CompleteProfileBeforeSignIn( + editProfile: true, + )); + }, + ) + ], + ))), + + const SizedBox(height: 40), + SizedBox( + // height: screenSize.height * 1 - 155, + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + headTitel('The Podium'), + menuWidget('quiz', 'Quiz Section', () { + Get.back(); + Get.to( + () => const QuizHome(), + ); + }, false), + const SizedBox(height: 15), + + // menuWidget('quiz', 'Menstrual cycle tracker', () { + // final isFilled = StorageService().readinitialSetup(); + // if (isFilled) { + // Get.back(); + // Get.to(() => TrackerHomePage()); + // } else { + // Get.back(); + // Get.to(() => const PeriodSelection()); + // } + // }, false), + // const SizedBox(height: 15), + + // menuWidget('rank', 'LeaderBoard', () { + // homePageController.updateBottomNavIndex(3); + // Get.back(); + // }), + // SizedBox( + // child: (controller.isLoggedIn) + // ? Column( + // children: [ + // const SizedBox(height: 15), + // menuWidget('previous', 'Previous Session', () { + // HomePageController.SessionsActiveTabIndex = + // 2; + // if (homePageController.bottomNavIndex.value == + // 1) { + // homePageController.updateBottomNavIndex(0); + // homePageController.updateBottomNavIndex(1); + // Get.back(); + // } else { + // homePageController.updateBottomNavIndex(1); + // } + // }), + // const SizedBox(height: 15), + // menuWidget('diet', 'My Diet Plan', () {}), + // ], + // ) + // : const SizedBox(), + // ), + // const SizedBox(height: 40), + headTitel('External Motivation'), + menuWidget( + 'podcast', + 'Podcasts', + () => Get.to( + () => const PodcastMain(), + ), + false), + const SizedBox(height: 15), + // menuWidget( + // 'news_articles', + // 'News & Articles', + // () => Get.to( + // () => const BlogMain(), + // ), + // ), + // const SizedBox(height: 15), + // menuWidget( + // 'instagram', + // 'GSF Instagram Handle', + // () { + // Get.back(); + // Get.to(() => const InstWebView()); + // }, + // ), + // const SizedBox(height: 40), + headTitel('All You need to know'), + // SizedBox( + // child: (controller.isLoggedIn) + // ? Column( + // children: [ + // menuWidget( + // 'subscriptions', 'My Subscription', () {}), + // const SizedBox(height: 15), + // ], + // ) + // : const SizedBox(), + // ), + menuWidget( + 'about', + 'About GETSETFIT', + () => Get.to( + () => const AboutGSF(), + ), + false), + + // const SizedBox(height: 15), + + // menuWidget( + // 'Skeleton', + // 'About GetSetFit', + // () => Get.to( + // () => const ProfileSkeleton(), + // ), + // ), + const SizedBox(height: 15), + menuWidget('video', 'Profile', () { + Get.back(); + Get.to( + () => const ProfilePage(), + ); + }, true), + const SizedBox(height: 15), + menuWidget('help_info', 'FAQs', () { + Get.back(); + Get.to( + () => const AboutGetSetFit(), + ); + }, false), + const SizedBox(height: 15), + // menuWidget('chat', 'Chat With Us', () { + // chatWithUsModalSheet(); + // }), + // const SizedBox(height: 15), + // SizedBox( + // child: (controller.isLoggedIn) + // ? Column( + // children: [ + // menuWidget('video', 'Help Videos', () {}), + // const SizedBox(height: 15), + // ], + // ) + // : const SizedBox(), + // ), + menuWidget('phone', 'Contact Us', () { + Get.back(); + Get.to( + () => const ContactUs(), + ); + }, false), + + // const SizedBox(height: 15), + // menuWidget('phone', 'Test', () { Get.back(); + // Get.to( + // () => const TestTimeInUpcoming(), + // );}), + + // const SizedBox(height: 20), + // menuWidget( + // 'logout', isScaleAdd ? 'Remove Scale' : 'Add Scale', + // () { + // GetStorage().write('addScale', false); + // Get.back(); + // homePageController.updateBottomNavIndex(2); + // }), + //dark mode + // const SizedBox(height: 15), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 12.0), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // 'Dark Mode', + // style: TextStyle( + // fontSize: 16, + // color: !globalContoller.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + // ), + // Column( + // mainAxisAlignment: MainAxisAlignment.center, + // // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // Transform.scale( + // scale: 1.2, + // child: Switch( + // value: isDarkModeN, + // activeColor: ColorConstants.kPrimaryColor, + // activeTrackColor: + // ColorConstants.kPrimaryColor, + // inactiveThumbColor: Colors.white, + // inactiveTrackColor: + // const Color(0xff4E4E4E), + // onChanged: (state) { + // print( + // 'light mode and dark mode $isDarkModeN'); + // setState(() { + // isDarkModeN = state; + // globalContoller.darkMode.value = + // state; + // ThemseServices().switchTheme(); + // print( + // 'theme bool value in LS is $isDarkModeN'); + // }); + // }), + // ), + // ], + // ), + // ], + // ), + // ), + const SizedBox(height: 15), + SizedBox( + child: (controller.isLoggedIn) + ? Column( + children: [ + menuWidget('logout', 'Logout', () { + logoutModalSheet(); + }, false), + const SizedBox(height: 15), + ], + ) + : const SizedBox(), + ), + ], + ), + ), + ) + ], + ), + ), + ), + ); + } + + menuWidget(String svgIcon, String title, VoidCallback ontap, + bool swapBitesWithProfile) { + // final brightness = Get.theme.brightness; + TextStyle textstyle = TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontWeight: FontWeight.w400); + return GestureDetector( + onTap: ontap, + child: Container( + decoration: BoxDecoration( + color: !globalContoller.darkMode.value + ? Colors.transparent + : const Color(0xff2B2B2B), + borderRadius: BorderRadius.circular(14), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Row( + children: [ + swapBitesWithProfile + ? SvgPicture.asset( + 'assets/image/menuicon/${!globalContoller.darkMode.value ? 'profile_black' : 'profile'}.svg', + width: 24, + height: 24, + ) + : SvgPicture.asset( + 'assets/image/sidebarIcons/${!globalContoller.darkMode.value ? svgIcon + '_black' : svgIcon}.svg', + width: 18, + ), + const SizedBox(width: 10), + Text( + title, + style: textstyle, + ) + ], + ), + ), + ), + ); + } + + headTitel(String headtitle) { + // final brightness = Get.theme.brightness; + TextStyle headStyle = TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ); + return Padding( + padding: const EdgeInsets.only(bottom: 10.0), + child: Text( + headtitle, + style: headStyle, + ), + ); + } + + logoutModalSheet() { + // final brightness = Get.theme.brightness; + return Get.bottomSheet( + SizedBox( + height: 250, + child: Obx( + () => Column( + children: [ + const Spacer(), + Container( + width: 75, + height: 75, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all( + width: 1, + color: Colors.white, + ), + shape: BoxShape.circle, + ), + child: appDataController.profilePicUrl.value.isEmpty + ? const Icon( + Icons.person_rounded, + size: 36, + color: Colors.white, + ) + : CircleAvatar( + backgroundImage: NetworkImage( + correctImgUrl( + appDataController.profilePicUrl.value, + ), + ), + backgroundColor: Colors.transparent, + ), + ), + // + // Container( + // height: 75, + // width: 75, + // decoration: const BoxDecoration( + // shape: BoxShape.circle, + // ), + // child: Image.asset( + // 'assets/image/avatar.png', + // fit: BoxFit.cover, + // ), + // ), + const SizedBox(height: 10), + Text( + 'Hello ${appDataController.name.value}', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 10), + Text( + 'Are you sure you want to log out?', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 12), + Container( + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: ColorConstants.kPrimaryColor, + ), + borderRadius: BorderRadius.circular(30), + ), + child: InkWell( + onTap: () { + // box.write('isLoggedIn', false); + // Get.offAll(() => const SignIn()); + box.write('isLoggedIn', false).then((value) { + Get.back(); + Get.back(); + Get.off(const SignIn()); + }); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15.0, vertical: 8), + child: Text( + 'LOG OUT', + style: TextStyle( + fontSize: 16, + color: !globalContoller.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ), + const SizedBox(height: 10), + InkWell( + onTap: () => Get.back(), + child: const Text( + 'Cancel', + style: TextStyle( + fontSize: 14, + color: Color(0xff858585), + fontFamily: 'SFPRO', + ), + ), + ), + const Spacer(), + ], + ), + )), + // barrierColor: Colors.red[0], + isDismissible: false, + backgroundColor: !globalContoller.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + // side: BorderSide(width: 5, color: Colors.black), + ), + // enableDrag: false, + ); + } + + chatWithUsModalSheet() { + return Get.bottomSheet( + SizedBox( + height: 250, + child: Column( + children: [ + const SizedBox(height: 30), + const Text( + 'Chat with us', + style: TextStyle( + fontSize: 18, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + InkWell( + onTap: () { + launchEmailSubmission(); + }, + child: Container( + decoration: BoxDecoration( + color: const Color(0xff4A4A4A), + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + 'assets/image/gmail-svg.svg', + width: 30, + height: 30, + ), + ), + ), + ), + const SizedBox(width: 15), + InkWell( + onTap: () { + _launchWhatsapp(); + }, + child: Container( + decoration: BoxDecoration( + color: const Color(0xff4A4A4A), + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + 'assets/image/whatsapp.svg', + width: 30, + height: 30, + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + barrierColor: Colors.black.withOpacity(1), + isDismissible: false, + backgroundColor: const Color(0xff212121), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + // side: BorderSide(width: 5, color: Colors.black), + ), + // enableDrag: false, + ); + } + + void launchEmailSubmission() async { + final Uri _emailLaunchUri = Uri( + scheme: 'mailto', + path: 'gsf@gmail.com', + ); + launch(_emailLaunchUri.toString()); + } + + _launchWhatsapp() async { + var whatsapp = "9594353563"; + launchUrl( + Uri.parse('https://wa.me/$whatsapp?text=Hi'), + mode: LaunchMode.externalApplication, + ); + // launch("https://wa.me/$whatsapp?text=Hello"); + } +} diff --git a/gsf/lib/views/pages/signIn/complete_profile_before_sign_in.dart b/gsf/lib/views/pages/signIn/complete_profile_before_sign_in.dart new file mode 100644 index 0000000..3727232 --- /dev/null +++ b/gsf/lib/views/pages/signIn/complete_profile_before_sign_in.dart @@ -0,0 +1,1401 @@ +import 'dart:io'; + +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/user_model.dart'; +import 'package:gsp_app/modals/view_frnd_profile_model.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/cj/update_profile_service.dart'; +import 'package:gsp_app/repository/services/cj/user_data_service.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/view_model/common_functions.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; + +import '../../../view_model/select_profile_picture_controller.dart'; +import '../../components/appbar.dart'; +import '../../components/dialog_app_tour_permission.dart'; +import '../../theme.dart'; +import '../../components/const.dart'; + +class CompleteProfileBeforeSignIn extends StatefulWidget { + const CompleteProfileBeforeSignIn({ + Key? key, + this.editProfile = false, + }) : super(key: key); + + final bool editProfile; + + @override + State createState() => + _CompanyProfileBeforeSignInState(); +} + +class _CompanyProfileBeforeSignInState + extends State { + final formKey = GlobalKey(); + + final List gender = [ + 'male', + 'female', + ]; + String? selectedGender; + + var nameTextFieldController = TextEditingController(); + var bioTextFieldController = TextEditingController(); + var ageTextFieldController = TextEditingController(); + var phoneTextFieldController = TextEditingController(); + var emailTextFieldController = TextEditingController(); + var addressTextFieldController = TextEditingController(); + var cityTextFieldController = TextEditingController(); + var heightTextFieldController = TextEditingController(); + var weightTextFieldController = TextEditingController(); + var submitBtnController = RoundedLoadingButtonController(); + + var selectProfilePicController = Get.put(SelectProfilePictureController()); + AppDataController appDataController = Get.find(); + + @override + void initState() { + super.initState(); + nameTextFieldController.text = appDataController.name.value; + phoneTextFieldController.text = appDataController.phoneNo.value; + emailTextFieldController.text = appDataController.email.value; + if (widget.editProfile) { + bioTextFieldController.text = appDataController.bio.value; + selectedGender = appDataController.gender.value; + ageTextFieldController.text = appDataController.age.value.toString(); + addressTextFieldController.text = appDataController.address.value; + cityTextFieldController.text = appDataController.city.value; + heightTextFieldController.text = + appDataController.height.value.toString(); + weightTextFieldController.text = + appDataController.weight.value.toString(); + } + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + GlobalController globalController = Get.find(); + return Scaffold( + // backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: widget.editProfile ? 'Edit Profile' : 'Complete Profile', + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: PrimaryButton( + controller: submitBtnController, + onTap: () { + Get.focusScope!.unfocus(); + if (formKey.currentState!.validate()) { + UpdateProfileService() + .updateProfile( + name: nameTextFieldController.text, + bio: bioTextFieldController.text, + description: bioTextFieldController.text, + gender: selectedGender!, + age: int.parse(ageTextFieldController.text), + address: addressTextFieldController.text, + city: cityTextFieldController.text, + height: double.parse(heightTextFieldController.text), + // weight: double.parse(weightTextFieldController.text), + profilePicPath: selectProfilePicController + .profilePicPath.value.isEmpty + ? null + : selectProfilePicController.profilePicPath.value) + .then((responseModel) { + switch (responseModel.responseStatus) { + case ResponseStatus.success: + submitBtnController.success(); + selectProfilePicController.profilePicPath.value = ""; + UserModel userModel = responseModel.data; + appDataController.fromUserModel(userModel); + try { + var newModel = ViewfrndsProfileModel( + id: userModel.id, + name: userModel.name, + contactNumber: userModel.phoneNo, + emailId: userModel.email, + userDetailModel: UserDetailModel( + // name: userModel.name, + age: userModel.age.toString(), + city: userModel.city, + description: userModel.bio, + fullAddress: userModel.address, + gender: userModel.gender, + height: userModel.height.toString(), + profilePicture: userModel.profilePicUrl, + userBio: userModel.bio, + // weight: userModel.weight.toString(), + )); + + var oldModel = appDataController.viewFriendsProfileModels + .singleWhere((friendProfileModel) => + friendProfileModel.id == userModel.id); + + int index = appDataController.viewFriendsProfileModels + .indexOf(oldModel); + + appDataController.viewFriendsProfileModels + .removeAt(index); + appDataController.viewFriendsProfileModels + .insert(index, newModel); + } catch (e) {} + if (widget.editProfile) { + Get.showSnackbar(const GetSnackBar( + duration: Duration(seconds: 4), + message: "Profile Updated", + )); + Get.offAll(() => const HomePage()); + } else { + guidedTourPremission(context); + } + break; + case ResponseStatus.failed: + case ResponseStatus.error: + case ResponseStatus.expired: + submitBtnController.error(); + break; + } + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => submitBtnController.reset()); + }); + } else { + submitBtnController.reset(); + } + }, + text: "Submit", + ), + body: GestureDetector( + onTap: () => FocusManager.instance.primaryFocus?.unfocus(), + child: Align( + alignment: Alignment.topCenter, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 22), + child: Column( + children: [ + const SizedBox(height: 32), + Stack( + alignment: AlignmentDirectional.center, + clipBehavior: Clip.none, + children: [ + Container( + decoration: BoxDecoration( + color: !globalController.darkMode.value + ? ColorConstants.kWhite + : const Color(0xff212121), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: + // Obx( + // () => + Container( + width: 106, + height: 106, + decoration: BoxDecoration( + color: const Color(0xff212121), + border: Border.all(width: 1), + shape: BoxShape.circle, + ), + child: Obx(() { + if (selectProfilePicController + .profilePicPath.value.isNotEmpty) { + return CircleAvatar( + backgroundImage: FileImage( + File(selectProfilePicController + .profilePicPath.value), + ), + backgroundColor: Colors.transparent, + ); + } else { + if (appDataController + .profilePicUrl.value.isNotEmpty) { + return CircleAvatar( + backgroundImage: NetworkImage( + correctImgUrl(appDataController + .profilePicUrl.value), + ), + backgroundColor: Colors.transparent, + ); + } + return const Icon( + Icons.person_rounded, + size: 84, + ); + } + }), + ), + // ), + ), + ), + // GestureDetector( + // onTap: () => Get.to(const CompanyProfile()), + // child: + // Image.asset("assets/image/badges/wdi_badge.png")), + Positioned( + bottom: 8, + right: 0, + child: GestureDetector( + onTap: () => showSelectImgSheet(), + child: Container( + width: 32, + height: 32, + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + color: const Color(0xff212121), + shape: BoxShape.circle, + boxShadow: const [ + BoxShadow( + color: Color.fromARGB(190, 0, 0, 0), + blurRadius: 2, + ) + ]), + child: const Icon( + Icons.camera_alt_rounded, + size: 18, + color: Color.fromARGB(148, 255, 255, 255), + ), + ), + ), + ) + ], + ), + // const SizedBox(height: 12), + // Text( + // widget.userModel.name, + // textAlign: TextAlign.center, + // style: QuizTextStyles.heading.copyWith( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // ), + // ), + // Text( + // "Lucknow", + // textAlign: TextAlign.center, + // style: QuizTextStyles.heading.copyWith( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite), + // ), + // Text( + // "Global Ranking-15", + // textAlign: TextAlign.center, + // style: QuizTextStyles.heading.copyWith( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite), + // ), + // const SizedBox(height: 24), + // Container( + // height: 48, + // width: 242, + // color: Colors.transparent, + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Expanded( + // child: Row( + // children: [ + // Expanded( + // child: InkWell( + // onTap: () => Get.to(const BadgesPage()), + // child: Column( + // children: [ + // const SizedBox(height: 3), + // Row( + // mainAxisAlignment: + // MainAxisAlignment.center, + // children: [ + // SvgPicture.asset( + // 'assets/image/profile/crown.svg', + // width: 14, + // height: 14, + // ), + // const SizedBox(width: 8), + // SvgPicture.asset( + // 'assets/image/profile/dumbell.svg', + // width: 14, + // height: 14, + // ), + // const SizedBox(width: 8), + // SvgPicture.asset( + // 'assets/image/profile/runner.svg', + // width: 14, + // height: 14, + // ), + // ], + // ), + // const SizedBox(height: 3), + // const Text("My Badges", + // style: QuizTextStyles.heading), + // ], + // ), + // ), + // ), + // const VerticalDivider( + // color: Colors.white, + // width: 2, + // thickness: 2, + // ), + // Expanded( + // child: Column( + // children: const [ + // Text("0", style: QuizTextStyles.heading), + // Text("Days Streak", + // style: QuizTextStyles.heading), + // ], + // ), + // ) + // ], + // ), + // ), + // const Divider( + // color: Colors.white, + // thickness: 2, + // height: 2, + // ) + // ], + // ), + // ), + const SizedBox(height: 38), + Form( + key: formKey, + child: + // Obx( + // () => + + Column( + children: [ + //name + Align( + alignment: Alignment.centerLeft, + child: Text( + "Name", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // enabled: false, + // initialValue: '${SignInData.name}', + // controller: completeProfileController + // .nameController.value, + // enabled: false, + controller: nameTextFieldController, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + disabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Name'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Bio + Align( + alignment: Alignment.centerLeft, + child: Text( + "Bio", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // controller: , + // controller: + // completeProfileController.bioController.value, + controller: bioTextFieldController, + autovalidateMode: + AutovalidateMode.onUserInteraction, + minLines: 4, + maxLines: 8, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your bio'; + } else if (value.length < 8) { + return 'Atleast 8 characters are required'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Gender + Align( + alignment: Alignment.centerLeft, + child: Text( + "Gender", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + const SizedBox(height: 6), + DropdownButtonFormField2( + hint: Text( + "Please select the gender", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + isExpanded: true, + items: gender + .map((item) => DropdownMenuItem( + value: item, + child: Padding( + padding: const EdgeInsets.only( + left: 0.0, top: 0, bottom: 0), + child: Text( + item, + style: QuizTextStyles.body.copyWith( + color: + !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + overflow: TextOverflow.ellipsis, + ), + ), + )) + .toList(), + autovalidateMode: + AutovalidateMode.onUserInteraction, + validator: (value) { + if (value == null) { + return 'Please select gender'; + } + return null; + }, + value: selectedGender, + onChanged: (value) { + setState(() { + selectedGender = value.toString(); + SignInData.selectedGender = selectedGender; + }); + }, + onSaved: (value) { + setState(() { + selectedGender = value.toString(); + }); + }, + decoration: + const InputDecoration(border: InputBorder.none), + iconStyleData: const IconStyleData( + icon: + Icon(Icons.arrow_drop_down_rounded, size: 32), + iconSize: 14, + // iconEnabledColor: Colors.yellow, + iconDisabledColor: Colors.grey, + ), + buttonStyleData: ButtonStyleData( + height: 58, + padding: const EdgeInsets.only(right: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: Border.all( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + dropdownStyleData: DropdownStyleData( + elevation: 8, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: !globalController.darkMode.value + ? Colors.white + : const Color(0xff212121), + ), + offset: const Offset(0, 1), + ), + menuItemStyleData: const MenuItemStyleData( + height: 40, + padding: EdgeInsets.only(left: 14, right: 14), + ), + ), + const SizedBox(height: 18), + //age + Align( + alignment: Alignment.centerLeft, + child: Text( + "Age", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + ), + const SizedBox(height: 6), + TextFormField( + readOnly: widget.editProfile ? true : false, + // controller: + // completeProfileController.ageController.value, + controller: ageTextFieldController, + autovalidateMode: + AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.number, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your age'; + } + return null; + }, + ), + const SizedBox(height: 18), + //phone number + Align( + alignment: Alignment.centerLeft, + child: Text( + "Phone Number", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: phoneTextFieldController, + enabled: false, + // controller: completeProfileController + // .phoneNumberController.value, + // initialValue: '${SignInData.mobileNumber}', + keyboardType: TextInputType.number, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + disabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Phone Number'; + } + return null; + }, + ), + const SizedBox(height: 18), + //email + Align( + alignment: Alignment.centerLeft, + child: Text( + "Email", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: emailTextFieldController, + enabled: false, + // initialValue: '${SignInData.emailId}', + // controller: completeProfileController + // .emailProfileController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + disabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Email'; + } + return null; + }, + ), + const SizedBox(height: 18), + //Full Address + Align( + alignment: Alignment.centerLeft, + child: Text( + "Full Address", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + controller: addressTextFieldController, + // controller: completeProfileController + // .fullAdrsessController.value, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your Address'; + } + return null; + }, + ), + const SizedBox(height: 18), + //City + Align( + alignment: Alignment.centerLeft, + child: Text( + "City", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // controller: completeProfileController + // .cityController.value, + controller: cityTextFieldController, + autovalidateMode: + AutovalidateMode.onUserInteraction, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your city name'; + } + return null; + }, + ), + const SizedBox(height: 18), + //height + Align( + alignment: Alignment.centerLeft, + child: Text( + "Height(in cm)", + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite), + ), + ), + const SizedBox(height: 6), + TextFormField( + // controller: completeProfileController + // .heightController.value, + //maxLength: 3, + controller: heightTextFieldController, + autovalidateMode: + AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.number, + style: QuizTextStyles.body.copyWith( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + decoration: InputDecoration( + filled: true, + fillColor: !globalController.darkMode.value + ? Colors.transparent + : const Color(0xff212121), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide( + width: 1, + color: !globalController.darkMode.value + ? const Color(0xff000000) + : Colors.transparent, + ), + ), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your height'; + } + + double height; + try { + height = double.parse(value); + } catch (e) { + return 'Please enter a valid number'; + } + + if (height < 120 || height > 250) { + return '120 cm to 250 cm'; + } + + return null; // Return null to indicate that the input is valid + }, + ), + // const SizedBox(height: 18), + //weight + // Align( + // alignment: Alignment.centerLeft, + // child: Text( + // "Weight(in kg)", + // style: QuizTextStyles.body.copyWith( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite), + // ), + // ), + // const SizedBox(height: 6), + // TextFormField( + // // controller: completeProfileController + // // .weightController.value, + // controller: weightTextFieldController, + // autovalidateMode: + // AutovalidateMode.onUserInteraction, + // keyboardType: TextInputType.number, + // style: QuizTextStyles.body.copyWith( + // color: !globalController.darkMode.value + // ? ColorConstants.kBlack + // : ColorConstants.kWhite, + // fontSize: 16, + // fontWeight: FontWeight.w500, + // ), + // decoration: InputDecoration( + // filled: true, + // fillColor: !globalController.darkMode.value + // ? Colors.transparent + // : const Color(0xff212121), + // border: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1, + // color: !globalController.darkMode.value + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // errorBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1, + // color: !globalController.darkMode.value + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // errorStyle: const TextStyle( + // fontSize: 16.0, + // ), + // enabledBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1, + // color: !globalController.darkMode.value + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // focusedBorder: OutlineInputBorder( + // borderRadius: BorderRadius.circular(10), + // borderSide: BorderSide( + // width: 1, + // color: !globalController.darkMode.value + // ? const Color(0xff000000) + // : Colors.transparent, + // ), + // ), + // ), + // validator: (value) { + // if (value!.isEmpty) { + // return 'Please enter your weight'; + // } + // return null; + // }, + // ), + const SizedBox(height: 32), + /* + FullWdtBtn( + btnText: "Done", + onTap: () { + Get.focusScope!.unfocus(); + if (formKey.currentState!.validate()) { + // formKey.currentState!.save(); + // debugPrint(completeProfileController + // .nameController.value.text); + // debugPrint(completeProfileController + // .bioController.value.text); + // debugPrint(selectedValue); + // debugPrint(completeProfileController + // .ageController.value.text); + // debugPrint(completeProfileController + // .phoneNumberController.value.text); + // debugPrint(completeProfileController + // .emailProfileController.value.text); + // debugPrint(completeProfileController + // .fullAdrsessController.value.text); + // debugPrint(completeProfileController + // .cityController.value.text); + // debugPrint(completeProfileController + // .heightController.value.text); + // debugPrint(completeProfileController + // .weightController.value.text); + // completeProfileController.completeProfile(); + debugPrint('complete profile api runned'); + // debugPrint(selectedValue); + // if() + } + }, + ), + */ + + const SizedBox(height: 18), + ], + ), + // ), + ), + const SizedBox(height: 38), + ], + ), + ), + ), + ), + )); + } + + showSelectImgSheet() { + final brightness = Theme.of(context).brightness; + + return Get.bottomSheet( + Container( + decoration: BoxDecoration( + color: brightness == Brightness.dark + ? const Color(0xff1C1C1C) + : const Color(0xffcccccc), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(24), + topRight: Radius.circular(24), + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14.6), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Select Profile Picture', + style: TextStyle( + fontSize: 18, + fontFamily: "Poppins", + color: (brightness == Brightness.dark) + ? const Color.fromARGB(190, 255, 255, 255) + : const Color(0xff000000), + ), + ), + const SizedBox(height: 32), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + LabelIconButton( + onTap: () => selectProfilePicController + .selectImg(ImageSource.camera), + icon: Icons.camera_alt_rounded, + label: "Camera", + ), + LabelIconButton( + onTap: () => selectProfilePicController + .selectImg(ImageSource.gallery), + icon: Icons.photo_library_rounded, + label: "Gallery", + ), + ], + ), + const SizedBox(height: 24), + ], + ), + ), + ), + ); + } +} + +class LabelIconButton extends StatelessWidget { + const LabelIconButton({ + Key? key, + required this.onTap, + required this.icon, + required this.label, + }) : super(key: key); + + final VoidCallback onTap; + final IconData icon; + final String label; + + @override + Widget build(BuildContext context) { + return TextButton( + onPressed: onTap, + style: TextButton.styleFrom( + foregroundColor: const Color.fromARGB(255, 8, 8, 8), + ), + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(18), + decoration: const ShapeDecoration( + shape: CircleBorder(), + color: Color.fromARGB(82, 0, 0, 0), + ), + child: Icon( + icon, + size: 32, + color: const Color.fromARGB(131, 255, 255, 255), + ), + ), + const SizedBox(height: 6), + Text( + label, + style: const TextStyle( + fontFamily: "SFPRO", + fontSize: 17, + color: Color.fromARGB(182, 255, 255, 255), + ), + ) + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/signIn/sign_in.dart b/gsf/lib/views/pages/signIn/sign_in.dart new file mode 100644 index 0000000..e67190f --- /dev/null +++ b/gsf/lib/views/pages/signIn/sign_in.dart @@ -0,0 +1,649 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/modals/manage_banner_model.dart'; +import 'package:gsp_app/modals/user_model.dart'; +import 'package:gsp_app/repository/response_data.dart'; +import 'package:gsp_app/repository/services/cj/login_service.dart'; +import 'package:gsp_app/repository/services/cj/view_frnds_profile_service.dart'; +import 'package:gsp_app/view_model/global_controller.dart'; +import 'package:gsp_app/views/components/primary_button.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:rounded_loading_button/rounded_loading_button.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../../../modals/view_frnd_profile_model.dart'; +import '../../../repository/services/cj/manage_banner_service.dart'; +import '../../../view_model/app_data_controller.dart'; +import '../../components/btn.dart'; +import '../../../repository/services/sign_in_service.dart'; +import '../../components/dialog_app_tour_permission.dart'; +import '../../theme.dart'; +import '../forgotPassword/forgot_password.dart'; +import '../home/home_page.dart'; +import 'complete_profile_before_sign_in.dart'; + +class SignIn extends StatefulWidget { + const SignIn({ + Key? key, + this.fromHomePage = false, + }) : super(key: key); + + final bool fromHomePage; + + @override + State createState() => _SignInState(); +} + +class _SignInState extends State { + final box = GetStorage(); + bool get isRemember => box.read("remember") ?? false; + set isRemember(bool value) => box.write("remember", value); + + GlobalKey _formKey = GlobalKey(); + bool _passwordVisible = false; + + // final emailRegx = RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); + final emailRegx = RegExp(r"^[a-zA-Z0-9_.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); + + final SignInController signInController = Get.put(SignInController()); + var signInBtnController = RoundedLoadingButtonController(); + var emailController = TextEditingController(); + var passwordController = TextEditingController(); + GlobalController globalController = Get.put(GlobalController()); + + AppDataController appDataController = Get.find(); + @override + void initState() { + loadCreds(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + // final brightness = Get.theme.brightness; + final screenSize = MediaQuery.of(context).size; + + return GestureDetector( + onTap: () => Get.focusScope!.unfocus(), + child: Scaffold( + body: Padding( + padding: EdgeInsets.symmetric( + horizontal: screenSize.width * 0.1, + // vertical: screenSize.width * 0.18, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Spacer(), + Text( + 'Welcome,', + style: TextStyle( + fontSize: 46, + color: !globalController.darkMode.value + ? Colors.grey + : ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w300, + fontFamily: 'Poppins', + ), + ), + Text( + 'Let\'s Sign you in', + style: TextStyle( + fontSize: 20, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffffffff), + fontWeight: FontWeight.w300, + fontFamily: 'Poppins', + ), + ), + formUi(), + const Spacer(flex: 4) + ], + ), + ), + ), + ); + } + + saveCreds() { + if (isRemember) { + GetStorage().write('usernameLogin', emailController.text); + GetStorage().write('passwordLogin', passwordController.text); + } + } + + loadCreds() { + if (isRemember) { + setState(() { + emailController.text = GetStorage().read('usernameLogin'); + passwordController.text = GetStorage().read('passwordLogin'); + }); + } + } + + formUi() { + // void allFunction() {} + return Form( + key: _formKey, + child: Column( + children: [ + const SizedBox(height: 52), + TextFormField( + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffffffff), + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + // controller: signInController.emailController.value, + controller: emailController, + keyboardType: TextInputType.text, + autovalidateMode: AutovalidateMode.onUserInteraction, + // inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"))], + decoration: InputDecoration( + hintText: 'Email', + hintStyle: TextStyle( + fontSize: 16, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xffB7B7B7), + ), + // suffixIcon: Padding( + // padding: const EdgeInsets.only(left: 20.0, right: 5), + // child: SvgPicture.asset( + // 'assets/image/user.svg', + // width: 25, + // height: 25, + // fit: BoxFit.cover, + // ), + // ), + suffixIcon: IconButton( + icon: Icon( + Icons.perm_identity_rounded, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xffB7B7B7), + size: 30, + ), + onPressed: () { + // setState( + // () { + // _passwordVisible = !_passwordVisible; + // }, + // ); + }, + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email Id'; + } + if (!value.contains(emailRegx)) { + return 'Please enter valid email Id'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + TextFormField( + style: TextStyle( + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffffffff), + // fontFamily: 'Helvetica', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + // controller: signInController.passwordController.value, + controller: passwordController, + obscureText: !_passwordVisible, + decoration: InputDecoration( + errorMaxLines: 3, + hintText: "Password", + hintStyle: TextStyle( + fontSize: 16, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xffB7B7B7), + // fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _passwordVisible + ? Icons.lock_open_outlined + : Icons.lock_outlined, + color: !globalController.darkMode.value + ? ColorConstants.kBlack.withOpacity(0.6) + : const Color(0xffB7B7B7), + size: 25, + ), + onPressed: () { + setState(() { + _passwordVisible = !_passwordVisible; + }); + }, + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide(width: 1, color: Color(0xffB7B7B7)), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your password'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 6), + Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 1, + child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + height: 12.0, + width: 12.0, + child: Checkbox( + activeColor: + const Color.fromARGB(255, 150, 217, 5), + shape: const CircleBorder(), + value: isRemember, + onChanged: (value) { + setState(() { + isRemember = value!; + }); + })), + const SizedBox( + width: 10, + ), + const Text( + 'Remember me?', + style: TextStyle( + // fontSize: 12, + // color: ColorC, + ), + ), + ], + )), + //const Spacer(), + // GestureDetector( + // onTap: () { + // Get.to(() => const ForgotPassword()); + // }, + // child: Text( + // 'Forgot Password?', + // style: TextStyle( + // fontSize: 14, + // color: !globalController.darkMode.value + // ? Colors.grey + // : ColorConstants.kPrimaryColor, + // ), + // ), + // ), + Expanded( + child: TextButton( + style: TextButton.styleFrom( + foregroundColor: !globalController.darkMode.value + ? ColorConstants.kBlack + : const Color(0xffffffff), + ), + onPressed: () { + Get.to(() => const ForgotPassword()); + Get.focusScope!.unfocus(); + }, + child: const Text('Forgot Password'), + ), + ) + ], + ), + const SizedBox(height: 52), + PrimaryButton( + controller: signInBtnController, + onTap: () { + Get.focusScope!.unfocus(); + if (_formKey.currentState!.validate()) { + signInBtnController.start(); + LoginService() + .loginUser( + email: emailController.text, + password: passwordController.text) + .then((responseModel) { + Future.delayed(const Duration(seconds: 12)).then((value) { + signInBtnController.reset(); + }); + if (responseModel.responseStatus == ResponseStatus.error) { + //NO INTERNET + Get.showSnackbar(const GetSnackBar( + title: "Cannot Sign In", + message: "Please try again later", + duration: Duration(seconds: 4), + )); + signInBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => signInBtnController.reset()); + } else if (responseModel.responseStatus == + ResponseStatus.expired) { + Get.showSnackbar(const GetSnackBar( + title: "Subscription Expired", + message: "Please contact gsf team", + duration: Duration(seconds: 4), + )); + signInBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => signInBtnController.reset()); + } else if (responseModel.responseStatus == + ResponseStatus.failed) { + //INVALID CREDENTAILS + Get.showSnackbar(const GetSnackBar( + title: "Invalid Credentials", + message: "Please check your email and password", + duration: Duration(seconds: 4), + )); + signInBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => signInBtnController.reset()); + } else if (responseModel.responseStatus == + ResponseStatus.success) { + //USER LOGIN SUCCESS + var userModel = responseModel.data as UserModel; + appDataController.fromUserModel(userModel); + GetStorage().write('token', userModel.token); + GetStorage().write('user_id', userModel.id); + saveCreds(); + //MANAGE BANNER START + ManageBannerService().fetchManageBanner().then((resModel) { + switch (resModel.responseStatus) { + case ResponseStatus.success: + //MANAGE BANNER SUCCESS + ManageBannerModel model = resModel.data; + appDataController.bannerPath.value = model.bannerPath; + appDataController.bannerPosition.value = + model.bannerPosition; + + //VIEW FRIENDS PROFILE START + ViewFriendsProfileService() + .fetchFriendsProfile() + .then((friendsProfileResModel) { + switch (friendsProfileResModel.responseStatus) { + case ResponseStatus.success: + //VIEW FRIENDS PROFILE SUCCESS + var friendsProfile = friendsProfileResModel.data + as List; + appDataController.viewFriendsProfileModels + .value = friendsProfile; + + //LAST + emailController.clear(); + passwordController.clear(); + if (userModel.age == null) { + Get.to(() => + const CompleteProfileBeforeSignIn()); + } else { + box.read('ShowModalSheet') ?? true + ? guidedTourPremission(context) + : gotoHome(); + } + box.write('isSignedIn', true); + signInBtnController.reset(); + break; + case ResponseStatus.failed: + case ResponseStatus.expired: + case ResponseStatus.error: + signInBtnController.error(); + Future.delayed( + const Duration(milliseconds: 800)) + .then( + (value) => signInBtnController.reset()); + break; + } + }); + + break; + case ResponseStatus.failed: + case ResponseStatus.expired: + case ResponseStatus.error: + signInBtnController.error(); + Future.delayed(const Duration(milliseconds: 800)) + .then((value) => signInBtnController.reset()); + break; + } + }); + // + } + }); + // debugPrint("signInController" + emailController.text); + // debugPrint("signInController" + passwordController.text); + + // signInController.loginApi().then( + // (value) { + // if (SignInData.data == true) { + // debugPrint('status values ${SignInData.status}'); + // SignInData.status == '0' + // ? Get.to(() => const CompleteProfileBeforSignIn()) + // : box.read('ShowModalSheet') ?? true + // ? guidedTourPremission() + // : gotoHome(); + // } + // signInBtnController.reset(); + // }, + // ); + + // + } else { + signInBtnController.reset(); + } + }, + text: "Sign in", + ), + const SizedBox(height: 15), + if (Platform.isIOS) + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'New User? ', + style: TextStyle( + fontSize: 14, + color: globalController.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + ), + ), + GestureDetector( + onTap: () { + showDesclaimer(); + }, + child: Text( + 'Register Now', + style: TextStyle( + fontSize: 14, + color: globalController.darkMode.value + ? ColorConstants.kWhite + : ColorConstants.kBlack, + decoration: TextDecoration.underline, + ), + ), + ) + ], + ) + ], + ), + ); + } + + showDesclaimer() { + void _launchWebsite() async { + final Uri url = Uri.parse('https://thegsf.co'); + if (Platform.isAndroid) { + // Open in Chrome on Android + await launchUrl(url, mode: LaunchMode.externalApplication); + } else if (Platform.isIOS) { + // Open in Safari on iOS + await launchUrl(url, mode: LaunchMode.externalApplication); + } else { + // For other platforms, use the default behavior + await launchUrl(url); + } + } + + void _launchWebsiteForiOS() async { + final Uri url = Uri.parse('https://apps.apple.com/in/story/id1614232807'); + if (Platform.isIOS) { + // Open in Safari on iOS + await launchUrl(url, mode: LaunchMode.externalApplication); + } else { + // For other platforms, use the default behavior + await launchUrl(url); + } + } + + return showBarModalBottomSheet( + expand: false, + context: context, + barrierColor: const Color(0xff000000).withOpacity(0.9), + backgroundColor: const Color(0xff1C1C1C), + builder: (context) { + return Padding( + padding: + const EdgeInsets.only(left: 25.0, right: 25, top: 30, bottom: 5), + child: Column( + children: [ + Text( + 'You\'re about to leave the app and go to an external website. You will no longer be transacting with Apple.', + style: TextStyle( + fontSize: 24, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + const SizedBox(height: 20), + Text( + 'Any accounts or purchases made outside of this app will be managed by the developer "Getsetfit". Your App Store account, stored payment method, and related features, such as subscription management and refund request, will not be available. Apple is not responsible for the privacy or security of transactions made with this developer', + style: TextStyle( + fontSize: 16, + color: !globalController.darkMode.value + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + ), + const Spacer( + flex: 4, + ), + // OutlinedButton(onPressed: onPressed, child: child) + Container( + width: Get.size.width, + height: 50.0, + margin: const EdgeInsets.symmetric(vertical: 3.0), + child: SizedBox.expand( + child: OutlinedButton( + style: OutlinedButton.styleFrom( + side: const BorderSide( + width: 1, + color: ColorConstants.kPrimaryColor, + style: BorderStyle.solid, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50)), + ), + onPressed: () { + _launchWebsiteForiOS(); + Get.back(); + }, + child: Text( + 'Learn More', + style: TextStyle( + color: globalController.darkMode.value + ? ColorConstants.kPrimaryColor + : ColorConstants.kBlack), + ), + ), + ), + ), + const SizedBox(height: 20), + + FullWdtBtn( + btnText: 'Continue', + onTap: () { + _launchWebsite(); + Get.back(); + }, + ), + const SizedBox(height: 20), + FullWdtBtn( + btnText: 'Cancel', + onTap: () { + Get.back(); + }), + const Spacer(flex: 1), + ], + ), + ); + }, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(30), + ), + ), + ); + } + + void gotoHome() { + // Get.offAll(const HomePage()); + // box.write("showMoodOmeter", true); + Get.offAll( + const HomePage(), + // Home(), + // SplashScreen(), + // transition: Transition.fadeIn, + // duration: const Duration(milliseconds: 900), + ); + box.write('isLoggedIn', true); + } +} diff --git a/gsf/lib/views/pages/signUp/privacy_policy_modal.dart b/gsf/lib/views/pages/signUp/privacy_policy_modal.dart new file mode 100644 index 0000000..cf78918 --- /dev/null +++ b/gsf/lib/views/pages/signUp/privacy_policy_modal.dart @@ -0,0 +1,62 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../../theme.dart'; + +class PrivacyAndPolicy extends StatefulWidget { + const PrivacyAndPolicy({Key? key}) : super(key: key); + + @override + State createState() => _PrivacyAndPolicyState(); +} + +class _PrivacyAndPolicyState extends State { + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Material( + child: SizedBox( + height: screenSize.height * 0.85, + child: CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + backgroundColor: ColorConstants.kPrimaryColor, + leading: Container(), + middle: const Text( + 'Privacy Policy', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + child: SafeArea( + // bottom: false, + child: SingleChildScrollView( + child: Container( + color: ColorConstants.kBlack, + width: screenSize.width * 1, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + SizedBox(height: 10), + Text( + 'If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: ColorConstants.kWhite), + ), + ], + ), + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/signUp/sign_up.dart b/gsf/lib/views/pages/signUp/sign_up.dart new file mode 100644 index 0000000..261e396 --- /dev/null +++ b/gsf/lib/views/pages/signUp/sign_up.dart @@ -0,0 +1,528 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:vibration/vibration.dart'; + +import '../../components/btn.dart'; +import '../../theme.dart'; +import 'privacy_policy_modal.dart'; +import 'sign_up_otp.dart'; +import 'term_conditions_modal.dart'; + +class SignUp extends StatefulWidget { + const SignUp({Key? key}) : super(key: key); + + @override + State createState() => _SignUpState(); +} + +class _SignUpState extends State { + var _formKey = GlobalKey(); + final TextEditingController _fullName = TextEditingController(); + final TextEditingController _phone = TextEditingController(); + final TextEditingController _email = TextEditingController(); + final TextEditingController _password = TextEditingController(); + final TextEditingController _confirmPassword = TextEditingController(); + bool _confirmPasswordVisible = false; + bool passwordVisible = false; + bool isChecked = false; + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + body: GestureDetector( + onTap: () => Get.focusScope?.unfocus(), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 70), + const Text( + 'Let\'s Sign you up', + style: TextStyle( + fontSize: 30, + color: Color(0xffffffff), + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 80), + form() + ], + ), + ), + ), + ), + ); + } + + form() { + return Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + style: const TextStyle( + color: ColorConstants.kWhite, + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + controller: _fullName, + keyboardType: TextInputType.text, + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + hintText: 'Full Name', + hintStyle: const TextStyle( + fontSize: 16, + color: Color(0xffB7B7B7), + ), + suffixIcon: Padding( + padding: const EdgeInsets.only(left: 20.0, right: 15), + child: SvgPicture.asset( + 'assets/image/user.svg', + width: 20, + // height: 25, + // fit: BoxFit.cover, + ), + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your full name'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + TextFormField( + style: const TextStyle( + color: ColorConstants.kWhite, + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + controller: _phone, + keyboardType: TextInputType.number, + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + hintText: 'Phone Number', + hintStyle: const TextStyle( + fontSize: 16, + color: Color(0xffB7B7B7), + ), + suffixIcon: Padding( + padding: const EdgeInsets.only( + left: 10.0, right: 15, bottom: 10, top: 10), + child: SvgPicture.asset( + 'assets/image/phone.svg', + // width: 25, + height: 10, + // fit: BoxFit.cover, + ), + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your number'; + } + if (!RegExp(r"^[0-9]{10,12}$").hasMatch(value)) { + return 'Number allowed between 10-12 digits'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + TextFormField( + style: const TextStyle( + color: ColorConstants.kWhite, + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + controller: _email, + keyboardType: TextInputType.text, + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: InputDecoration( + hintText: 'Email', + hintStyle: const TextStyle( + fontSize: 16, + color: Color(0xffB7B7B7), + ), + suffixIcon: Padding( + padding: const EdgeInsets.only(left: 10, right: 15), + child: SvgPicture.asset( + 'assets/image/email.svg', + // width: 25, + height: 10, + // fit: BoxFit.cover, + ), + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email Id'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + TextFormField( + style: const TextStyle( + color: ColorConstants.kWhite, + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + controller: _password, + obscureText: !passwordVisible, + autovalidateMode: AutovalidateMode.onUserInteraction, + keyboardType: TextInputType.text, + decoration: InputDecoration( + hintText: 'Password', + hintStyle: const TextStyle( + fontSize: 16, + color: Color(0xffB7B7B7), + ), + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + passwordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: const Color(0xffffffff), + ), + onPressed: () { + setState(() { + passwordVisible = !passwordVisible; + }); + }, + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 14.0, + // color: Color(0xffffffff), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email Id'; + } + if (value.length < 4) { + return 'Must be less than 4 characters'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox(height: 30), + TextFormField( + style: const TextStyle( + color: Color(0xffffffff), + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w400, + ), + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: _confirmPassword, + obscureText: !_confirmPasswordVisible, + decoration: InputDecoration( + fillColor: Colors.transparent, + errorMaxLines: 3, + hintText: "Confirm Password*", + contentPadding: const EdgeInsets.only( + top: 20, + // bottom: 13, + left: 0, + right: 0, + ), + hintStyle: TextStyle( + fontSize: 16, + color: const Color(0xffffffff).withOpacity(0.8), + fontFamily: 'Helvetica', + ), + // fillColor: Colors.white, + filled: true, + suffixIcon: IconButton( + icon: Icon( + // Based on passwordVisible state choose the icon + _confirmPasswordVisible + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: const Color(0xffffffff), + ), + onPressed: () { + setState(() { + _confirmPasswordVisible = !_confirmPasswordVisible; + }); + }, + ), + enabledBorder: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + border: const UnderlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Color(0xffB7B7B7), + ), + ), + focusedBorder: const UnderlineInputBorder( + borderSide: + BorderSide(width: 1, color: ColorConstants.kPrimaryColor), + ), + errorStyle: const TextStyle( + fontSize: 16.0, + // color: Color(0xffffffff), + ), + isDense: false, + ), + keyboardType: TextInputType.visiblePassword, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter your password'; + } + if (value.length < 8) { + return 'Must be less than 8 characters'; + } + if (value != _password.text) { + return 'Password does not match'; + } + return null; + }, + onSaved: (name) {}, + ), + const SizedBox( + height: 30, + ), + Row( + children: [ + Expanded( + flex: 0, + child: SizedBox( + width: 24, + height: 24, + child: Theme( + data: ThemeData( + checkboxTheme: CheckboxThemeData( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + ), + ), + child: Checkbox( + side: const BorderSide(color: ColorConstants.kWhite), + checkColor: ColorConstants.kBlack, + activeColor: ColorConstants.kPrimaryColor, + value: isChecked, + onChanged: (bool? value) { + setState( + () { + isChecked = value!; + }, + ); + }, + ), + ), + ), + ), + Expanded( + flex: 6, + child: Padding( + padding: const EdgeInsets.only(left: 3), + child: Wrap( + children: [ + const Text( + 'By creating an account you agree to our ', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: Color(0xffffffff), + ), + ), + InkWell( + onTap: () { + showBarModalBottomSheet( + expand: false, + context: context, + barrierColor: + const Color(0xff000000).withOpacity(0.9), + backgroundColor: const Color(0xff1C1C1C), + builder: (context) => + const TermAnndConditionsModal(), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(30), + ), + ), + ); + }, + child: const Text( + 'Terms of Service', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + decoration: TextDecoration.underline, + // decorationColor: Color(0xffcc9900), + // decorationThickness: 2, + color: ColorConstants.kPrimaryColor, + ), + ), + ), + const Text( + ' and ', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + color: Color(0xffffffff), + ), + ), + InkWell( + onTap: () { + showBarModalBottomSheet( + expand: false, + context: context, + barrierColor: + const Color(0xff000000).withOpacity(0.9), + backgroundColor: const Color(0xff1C1C1C), + builder: (context) => const PrivacyAndPolicy(), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(30), + ), + ), + ); + }, + child: const Text( + 'Privacy Policy.', + style: TextStyle( + fontFamily: 'Helvetica', + fontSize: 12, + decoration: TextDecoration.underline, + // decorationColor: Color(0xffcc9900), + // decorationThickness: 2, + color: ColorConstants.kPrimaryColor, + ), + ), + ), + ], + ), + ), + ), + ], + ), + const SizedBox(height: 40), + FullWdtBtn( + btnText: 'Sign Up', + onTap: () { + // HapticFeedback.heavyImpact(); + Get.to( + () => const SignUpOtp(), + ); + Vibration.vibrate(duration: 200); + }, + ), + const SizedBox(height: 20), + InkWell( + onTap: () => Get.to(() => const SignIn()), + child: const Text( + 'Click here to Sign In', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kPrimaryColor, + ), + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/signUp/sign_up_otp.dart b/gsf/lib/views/pages/signUp/sign_up_otp.dart new file mode 100644 index 0000000..45fee7d --- /dev/null +++ b/gsf/lib/views/pages/signUp/sign_up_otp.dart @@ -0,0 +1,257 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +// import 'package:alt_sms_autofill/alt_sms_autofill.dart'; +import 'package:flutter/services.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:pin_code_fields/pin_code_fields.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../components/dialog_app_tour_permission.dart'; +import '../../theme.dart'; + +class SignUpOtp extends StatefulWidget { + const SignUpOtp({Key? key}) : super(key: key); + + @override + State createState() => _SignUpOtpState(); +} + +final box = GetStorage(); + +class _SignUpOtpState extends State { + final textEditingController1 = TextEditingController(); + + Future initSmsListener() async { + String? comingSms; + // try { + // comingSms = await AltSmsAutofill().listenForSms; + // } on PlatformException { + // comingSms = 'Failed to get Sms.'; + // } + if (!mounted) return; + + setState(() { + // print("====>Message: $comingSms"); + // print("${_comingSms[32]}"); + textEditingController1.text = comingSms + .toString(); //used to set the code in the message to a string and setting it to a textcontroller. message length is 38. so my code is in string index 32-37. + }); + } + + @override + void initState() { + super.initState(); + // textEditingController1.text = 123486.toString(); + initSmsListener(); + } + + @override + void dispose() { + // textEditingController1.dispose(); + // AltSmsAutofill().unregisterListener(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: '')), + body: GestureDetector( + onTap: () => Get.focusScope?.unfocus(), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 50), + const Text( + 'We sent a code to your number ', + style: TextStyle( + fontSize: 16, + color: Color(0xffD9D9D9), + fontWeight: FontWeight.w500, + ), + ), + RichText( + text: TextSpan( + children: [ + const TextSpan( + text: '-------713 ', + style: TextStyle(color: Color(0xffD9D9D9), fontSize: 16), + ), + TextSpan( + text: 'Change', + recognizer: TapGestureRecognizer() + ..onTap = (() => Get.back()), + style: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 16, + decoration: TextDecoration.underline, + ), + ), + ], + ), + ), + const SizedBox(height: 45), + const Text( + 'Enter OTP*', + style: TextStyle( + fontSize: 14, + color: Color(0xff9F9F9F), + ), + ), + const SizedBox(height: 10), + otpWidget(), + const SizedBox(height: 50), + Align( + alignment: Alignment.center, + child: RichText( + text: TextSpan( + children: [ + const TextSpan( + text: 'Don\'t receive your code? ', + style: + TextStyle(color: Color(0xffD9D9D9), fontSize: 16), + ), + TextSpan( + text: 'Resend', + recognizer: TapGestureRecognizer()..onTap = () {}, + style: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 16, + decoration: TextDecoration.underline, + ), + ), + ], + ), + ), + ), + const Spacer(flex: 4), + FullWdtBtn( + btnText: 'Continue!', + onTap: () { + guidedTourPremission(context); + + box.write('isLoggedIn', true); + }, + ), + const Spacer(flex: 1), + ], + ), + ), + ), + ); + } + + otpWidget() { + return PinCodeTextField( + appContext: context, + pastedTextStyle: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + length: 4, + textStyle: const TextStyle( + color: ColorConstants.kPrimaryColor, + fontSize: 22, + fontWeight: FontWeight.w500, + ), + obscureText: false, + animationType: AnimationType.fade, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp("[0-9]")), + ], + pinTheme: PinTheme( + shape: PinCodeFieldShape.box, + borderRadius: BorderRadius.circular(10), + fieldHeight: 60, + fieldWidth: 60, + inactiveFillColor: Colors.transparent, + inactiveColor: const Color(0xff707070), + selectedColor: ColorConstants.kPrimaryColor, + selectedFillColor: Colors.transparent, + activeFillColor: Colors.transparent, + activeColor: ColorConstants.kPrimaryColor, + ), + cursorColor: Colors.white, + animationDuration: const Duration(milliseconds: 300), + enableActiveFill: true, + controller: textEditingController1, + keyboardType: TextInputType.number, + onCompleted: (v) { + //do something or move to next screen when code complete + }, + onChanged: (value) { + // print(value); + setState(() { + // print('$value'); + }); + }, + ); + } + + // void guidedTourPremission() { + // final screenSize = MediaQuery.of(context).size; + // Get.bottomSheet( + // SizedBox( + // height: screenSize.width * 0.7, + // child: Padding( + // padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.1), + // child: Column( + // children: [ + // const Spacer(flex: 3), + // Text( + // 'Would you like a guided tour\n of our app?', + // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 20, + // color: ColorConstants.kWhite.withOpacity(0.8), + // ), + // ), + // const SizedBox(height: 30), + // FullWdtBtn( + // btnText: 'Yes', + // onTap: () { + // // box.write('isUserRegistered', true).then((value) { + // // Get.to(() => const ShareThought()); + // // }); + // box.write('isLoggedIn', true); + // // box.write('showAppTour', true); + // }), + // const SizedBox(height: 20), + // InkWell( + // splashColor: Colors.transparent, + // onTap: () => Get.offAll( + // () => const ShareThought(), + // ), + // child: const Text( + // 'No', + // style: TextStyle( + // fontSize: 18, + // color: Color(0xffffffff), + // ), + // ), + // ), + // const Spacer(flex: 2), + // ], + // ), + // ), + // ), + // backgroundColor: const Color(0xff212121), + // barrierColor: ColorConstants.kBlack, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.only( + // topLeft: Radius.circular(20), + // topRight: Radius.circular(20), + // ), + // ), + // ); + // } +} diff --git a/gsf/lib/views/pages/signUp/term_conditions_modal.dart b/gsf/lib/views/pages/signUp/term_conditions_modal.dart new file mode 100644 index 0000000..64d2658 --- /dev/null +++ b/gsf/lib/views/pages/signUp/term_conditions_modal.dart @@ -0,0 +1,63 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../../theme.dart'; + +class TermAnndConditionsModal extends StatefulWidget { + const TermAnndConditionsModal({Key? key}) : super(key: key); + + @override + State createState() => + _TermAnndConditionsModalState(); +} + +class _TermAnndConditionsModalState extends State { + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return Material( + child: SizedBox( + height: screenSize.height * 0.85, + child: CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + backgroundColor: ColorConstants.kPrimaryColor, + leading: Container(), + middle: const Text( + 'Terms of Service', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + child: SafeArea( + // bottom: false, + child: SingleChildScrollView( + child: Container( + color: ColorConstants.kBlack, + width: screenSize.width * 1, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 20, horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: const [ + Text( + 'If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.If you work in marketing, design, or publishing, you’ve likely heard of lorem ipsum. This Latin scramble of letters has long served as the industry standard dummy text for everything from web page designs to print advertisements. But where exactly did lorem ipsum come from and is it the best way to think about dummy copy? Read on to find out.', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: ColorConstants.kWhite, + ), + ), + ], + ), + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/splash.dart b/gsf/lib/views/pages/splash.dart new file mode 100644 index 0000000..90fe466 --- /dev/null +++ b/gsf/lib/views/pages/splash.dart @@ -0,0 +1,352 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/services/cj/user_data_service.dart'; +import 'package:gsp_app/view_model/app_data_controller.dart'; +import 'package:gsp_app/views/components/custom_skeleton.dart'; +import 'package:gsp_app/views/pages/home/home_page.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:video_player/video_player.dart'; +import '../../modals/manage_banner_model.dart'; +import '../../modals/short_clip_likes_model.dart'; +import '../../modals/short_clip_model.dart'; +import '../../modals/view_frnd_profile_model.dart'; +import '../../repository/response_data.dart'; +import '../../repository/services/cj/manage_banner_service.dart'; +import '../../repository/services/cj/view_frnds_profile_service.dart'; +import '../../repository/services/home_controller.dart'; +import 'package:async/async.dart'; +import '../../repository/services/short_clip_service.dart'; + +class ShortClipTemp { + static List tempClips = []; + static List tempclipLikes = []; +} + +class SplashScreen extends StatefulWidget { + const SplashScreen({Key? key}) : super(key: key); + + @override + State createState() => _SplashScreenState(); +} + +class _SplashScreenState extends State { + final AppDataController appDataController = Get.find(); + + FutureGroup futureGroup = FutureGroup(); + final HomeApiController homeController = Get.put(HomeApiController()); + final box = GetStorage(); + bool get isFingerPrintStoreTest => box.read("fingerPrint") ?? false; + bool isAuthenticated = false; + LocalAuthentication authentication = LocalAuthentication(); + bool? _hasBioSensor; + + @override + void initState() { + futureGroup.add(UserDataService().fetchUserData()); + futureGroup.add(ShortClipService().fetchShortClips()); + futureGroup.add(ShortClipService().fetchShortClipLikes()); + futureGroup.close(); + + //old + if (isFingerPrintStoreTest) { + _checkBio(); + } else { + setState(() { + isAuthenticated = true; + }); + } + super.initState(); + } + + Future _checkBio() async { + try { + _hasBioSensor = await authentication.canCheckBiometrics; + List availableBiometrics = + await authentication.getAvailableBiometrics(); + final isDeviceSupported = await authentication.isDeviceSupported(); + print(_hasBioSensor); + print(availableBiometrics); + print("device support $isDeviceSupported"); + if (_hasBioSensor!) { + _getAuthwithfinger(); + } else { + _getAuth(); + print("fingerprint not available"); + } + // ignore: empty_catches + } on PlatformException {} + } + + Future _getAuthwithfinger() async { + print("getauth called"); + bool isAuth = false; + try { + isAuth = await authentication.authenticate( + localizedReason: 'Scan your fingerprint to access the app', + options: const AuthenticationOptions( + biometricOnly: true, + useErrorDialogs: true, + stickyAuth: true, + ), + ); + + if (isAuth) { + setState(() { + isAuthenticated = true; + }); + } + + // ignore: empty_catches + } on PlatformException catch (e) { + print(e); + } + if (!mounted) return; + } + + Future _getAuth() async { + bool isAuth = false; + try { + isAuth = await authentication.authenticate( + localizedReason: 'Enter your Pattern or Pin to unlock', + options: const AuthenticationOptions( + biometricOnly: false, + useErrorDialogs: true, + stickyAuth: true, + ), + ); + if (isAuth) { + setState(() { + isAuthenticated = true; + }); + } + + // ignore: empty_catches + } on PlatformException catch (e) { + print(e); + } + if (!mounted) return; + } + + @override + Widget build(BuildContext context) { + return isAuthenticated + ? FutureBuilder( + future: futureGroup.future, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + ResponseModel responseModel = snapshot.data![0]; + + ShortClipTemp.tempClips = snapshot.data![1]; + ShortClipTemp.tempclipLikes = snapshot.data![2]; + + switch (responseModel.responseStatus) { + case ResponseStatus.success: + appDataController.fromUserModel(responseModel.data); + ManageBannerService() + .fetchManageBanner() + .then((resModel) async { + switch (resModel.responseStatus) { + case ResponseStatus.success: + //MANAGE BANNER SUCCESS + ManageBannerModel model = resModel.data; + appDataController.bannerPath.value = model.bannerPath; + appDataController.bannerPosition.value = + model.bannerPosition; + // var moodResult = await MoodOMeterService().getMoodOMeter(); + // // if() + // if(moodResult.responseStatus != ResponseStatus.success ){ + // return const HomePageSkeleton(); + // } + + // print(moodResult.tojson); + // print("sdf"); + // print) + // moodOMeterResult. + + // switch + // var moodOMeterData = homeController.apiGetMoodO_meter(); + // print("moodOMeterData"); + // if(moodOMeterData == null){ + // return const HomePageSkeleton(); + // } + // print("mood o meter data $moodOMeterData"); + // debugPrint("mood o meter data ${moodOMeterData}"); + //VIEW FRIENDS PROFILE START + ViewFriendsProfileService() + .fetchFriendsProfile() + .then((friendsProfileResModel) { + switch (friendsProfileResModel.responseStatus) { + case ResponseStatus.success: + //VIEW FRIENDS PROFILE SUCCESS + var friendsProfile = friendsProfileResModel.data + as List; + appDataController.viewFriendsProfileModels + .value = friendsProfile; + // GetStorage().write("showMoodOmeter", true); + + Get.offAll(const HomePage()); + break; + case ResponseStatus.failed: + case ResponseStatus.expired: + case ResponseStatus.error: + break; + } + }); + + break; + case ResponseStatus.failed: + case ResponseStatus.expired: + case ResponseStatus.error: + Get.showSnackbar(const GetSnackBar( + title: "Unable to load", + message: "Please try again later", + )); + break; + } + }); + break; + // return const HomePage(); + case ResponseStatus.failed: + + case ResponseStatus.expired: + // Get.showSnackbar( + // const GetSnackBar( + // title: "Session Expired", + // message: "Please login again", + // ), + // ); + + Future.delayed(const Duration(seconds: 1), () { + Get.offAll(() => const SignIn()); + }); + break; + case ResponseStatus.error: + Get.showSnackbar( + const GetSnackBar( + title: "Unable to load", + message: "Please try again later", + ), + ); + break; + } + } + return const HomePageSkeleton(); + }, + ) + : Platform.isAndroid + ? Scaffold( + body: SizedBox( + width: Get.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + "Use your fingerprint to easily log in!", + // style: blackStyle(context), + ), + const SizedBox( + height: 20, + ), + GestureDetector( + onTap: () { + _checkBio(); + }, + child: SizedBox( + width: 64, + height: 77, + child: SvgPicture.asset( + 'assets/image/Thumbprint.svg', + color: ColorConstants.kPrimaryColor, + ), + ), + ), + const SizedBox( + height: 21, + ), + const Text("Touch the fingerprint sensor"), + const SizedBox( + height: 20, + ), + // const Divider( + // thickness: 2, + // ), + const SizedBox( + height: 10, + ), + // GestureDetector( + // onTap: () {}, + // child: Text("Login with Pin", + // style: TextStyle( + // fontSize: 18, + // fontWeight: FontWeight.bold, + // color: Color(0xFFF78104), + // decoration: TextDecoration.underline, + // )), + // ), + ], + ), + ), + ) + : Scaffold( + body: SizedBox( + width: Get.width, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + "Use your FaceID to easily log in!", + // style: blackStyle(context), + ), + const SizedBox( + height: 20, + ), + GestureDetector( + onTap: () { + _checkBio(); + }, + child: SizedBox( + width: 64, + height: 77, + child: SvgPicture.asset( + 'assets/image/face-id-svgrepo-com.svg', + color: ColorConstants.kPrimaryColor, + ), + ), + ), + const SizedBox( + height: 21, + ), + const Text("Touch the FaceID sensor"), + const SizedBox( + height: 20, + ), + const Divider( + thickness: 2, + ), + const SizedBox( + height: 10, + ), + // GestureDetector( + // onTap: () {}, + // child: Text("Login with Pin", + // style: TextStyle( + // fontSize: 18, + // fontWeight: FontWeight.bold, + // color: Color(0xFFF78104), + // decoration: TextDecoration.underline, + // )), + // ), + ], + ), + )); + } +} diff --git a/gsf/lib/views/pages/summer_sweet/summer_sweet.dart b/gsf/lib/views/pages/summer_sweet/summer_sweet.dart new file mode 100644 index 0000000..984215a --- /dev/null +++ b/gsf/lib/views/pages/summer_sweet/summer_sweet.dart @@ -0,0 +1,556 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class SummerSweet extends StatelessWidget { + const SummerSweet({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Summer Sweat!')), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text( + 'Turn up the heat with our 3 months & 60 Sessions Long Summer Activity', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + ), + const SizedBox(height: 10), + Container( + height: 312, + width: Get.size.width, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/summerSweet.jpg'), + fit: BoxFit.cover, + ), + ), + child: Align( + alignment: Alignment.center, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor.withOpacity(0.8), + shape: BoxShape.circle, + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow, + color: ColorConstants.kBlack, + size: 45, + ), + ), + ), + ), + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'About the session', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 10), + const Text( + 'Torch those calories and melt off your body fat with this 30 min cardio + abs session. This killer abs and cardio session will help you get a full abs workout while burning fat with intense cardio exercises. You will build muscle and lose fat, making those abs pop out.', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + '', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + InkWell( + onTap: () {}, + child: const Icon( + Icons.keyboard_arrow_right, + color: ColorConstants.kWhite, + size: 30, + ), + ) + ], + ), + SizedBox( + height: 200, + child: ListView.builder( + itemCount: 5, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => Padding( + padding: const EdgeInsets.only(right: 20), + child: yoga(), + ), + ), + ), + const SizedBox(height: 16), + const Text( + 'Teachers', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 10), + SizedBox( + height: 150, + child: ListView.builder( + itemCount: 8, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => SizedBox( + width: 110, + child: Column( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(100), + child: SizedBox( + width: 94, + height: 94, + child: Image.asset( + 'assets/image/podcastAudio.jpg', + fit: BoxFit.cover, + ), + ), + ), + const SizedBox(height: 10), + const Text( + 'Kartikey Gautam 110 Classes', + style: TextStyle( + fontSize: 12, + color: ColorConstants.kWhite, + ), + textAlign: TextAlign.center, + ) + ], + ), + ), + ), + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + 'Free trial videos', + style: TextStyle( + fontSize: 17, + color: Color(0xffD9D9D9), + ), + ), + InkWell( + onTap: () {}, + child: const Icon( + Icons.keyboard_arrow_right, + color: ColorConstants.kWhite, + size: 30, + ), + ) + ], + ), + Container( + height: 190, + width: Get.size.width, + decoration: BoxDecoration( + image: const DecorationImage( + image: AssetImage('assets/image/cardio.jpg'), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(15), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: + ColorConstants.kPrimaryColor.withOpacity(0), + shape: BoxShape.circle, + border: Border.all( + width: 2, + color: ColorConstants.kPrimaryColor)), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.play_arrow_outlined, + color: ColorConstants.kPrimaryColor, + size: 45, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 35), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Routine', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Warm Up', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '15 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Workout', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '35 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset('assets/image/Layer.svg'), + const Text( + 'Cool Down', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ), + ], + ), + const Text( + '10 mins', + style: TextStyle( + fontSize: 14, + color: Color(0xffD9D9D9), + ), + ) + ], + ), + Divider( + color: const Color(0xffD9D9D9).withOpacity(0.5), + thickness: 1, + ), + ], + ), + const SizedBox(height: 30), + const Text( + 'How will this activity help', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Full Body Workout', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Increased Lung Capacity', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 30), + const Text( + 'How can you prepare yourself for the session', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + ), + ), + const SizedBox(height: 15), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Yoga Mat', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: ColorConstants.kPrimaryColor, + width: 1, + ), + borderRadius: BorderRadius.circular(25), + ), + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, vertical: 10), + child: Text( + 'Bottle of water', + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 70), + ], + ), + ), + ], + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: FullWdtBtn( + btnText: 'Subscribe Today!', + onTap: () {}, + ), + ), + ); + } + + yoga() { + return Stack( + children: [ + Container( + height: 190, + width: Get.size.width * 0.8, + decoration: BoxDecoration( + image: const DecorationImage( + image: AssetImage('assets/image/yoga.jpg'), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsets.only(top: 8, left: 8), + child: Text( + 'Yoga', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + ), + Container( + decoration: const BoxDecoration( + color: ColorConstants.kWhite, + borderRadius: BorderRadius.only( + topRight: Radius.circular(20), + bottomLeft: Radius.circular(20), + ), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: const [ + Text( + '8', + style: TextStyle( + fontSize: 50, + color: Color(0xff646464), + height: 1, + ), + ), + Text( + 'session', + style: TextStyle( + fontSize: 14, + color: Color(0xff646464), + height: 0.8, + ), + ) + ], + ), + ), + ) + ], + ), + ], + ), + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack.withOpacity(0.3), + ), + child: Padding( + padding: const EdgeInsets.only( + left: 10, right: 10, bottom: 20, top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: const [ + Text( + 'Movement and Mind', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + Text( + 'Intermediate', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + ), + ), + ], + ), + ), + ), + ), + ], + ); + } +} diff --git a/gsf/lib/views/pages/summer_sweet/summer_sweet_details.dart b/gsf/lib/views/pages/summer_sweet/summer_sweet_details.dart new file mode 100644 index 0000000..e0c0c6e --- /dev/null +++ b/gsf/lib/views/pages/summer_sweet/summer_sweet_details.dart @@ -0,0 +1,187 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../components/appbar.dart'; +import '../../theme.dart'; + +class SummwerSweetDetails extends StatelessWidget { + const SummwerSweetDetails({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Summer Sweat!')), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + width: Get.size.width, + height: 273, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/image/yoga.jpg'), + fit: BoxFit.cover), + ), + child: const Padding( + padding: EdgeInsets.only(left: 20, top: 40), + child: Text( + 'Yoga\n Level-Intermediate', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Torch those calories and melt off your body fat with this 30 min cardio + abs session. This killer abs and cardio session will help you get a full abs workout while burning fat with intense cardio exercises. You will build muscle and lose fat, making those abs pop out.', + style: TextStyle( + fontSize: 16, + color: Color(0xffD9D9D9), + fontFamily: 'SFPRO', + fontWeight: FontWeight.w300, + ), + ), + const SizedBox(height: 30), + Text( + 'WEEK 1', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 20), + ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.vertical, + physics: ScrollPhysics(), + itemCount: 2, + itemBuilder: (context, index) => yogaExcercise(), + ), + SizedBox(height: 50), + Text( + 'WEEK 2', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + const SizedBox(height: 20), + ListView.builder( + shrinkWrap: true, + scrollDirection: Axis.vertical, + physics: ScrollPhysics(), + itemCount: 2, + itemBuilder: (context, index) => yogaExcercise(), + ), + ], + ), + ) + ], + ), + ), + ); + } + + yogaExcercise() { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Container( + decoration: BoxDecoration( + color: Color(0xffD9D9D9), + borderRadius: BorderRadius.circular(7), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(7), + topRight: Radius.circular(7), + ), + child: Image.asset( + 'assets/image/yoga1.jpg', + width: Get.size.width, + height: 150, + fit: BoxFit.cover, + ), + ), + Positioned( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + 'Yoga', + style: TextStyle( + fontSize: 16, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Session-2', + style: TextStyle( + fontSize: 14, + color: Color(0xff858585), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Movement and Mind', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kBlack, + ), + ), + Text( + 'Intermediate', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kBlack, + ), + ), + ], + ), + SizedBox(height: 10), + Text( + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.', + style: TextStyle( + fontSize: 14, + color: Color(0xff858585), + ), + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/accordian.dart b/gsf/lib/views/pages/test/accordian.dart new file mode 100644 index 0000000..a5ec10e --- /dev/null +++ b/gsf/lib/views/pages/test/accordian.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class AccordionExample extends StatefulWidget { + @override + _AccordionExampleState createState() => _AccordionExampleState(); +} + +class _AccordionExampleState extends State { + List _data = generateItems(5); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Accordion Example'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16.0), + child: _buildPanel(), + ), + ), + ); + } + + Widget _buildPanel() { + return ExpansionPanelList( + elevation: 1, + expandedHeaderPadding: EdgeInsets.all(0), + expansionCallback: (int index, bool isExpanded) { + setState(() { + _data.forEach((item) { + item.isExpanded = false; + }); + _data[index].isExpanded = !isExpanded; + }); + }, + children: _data.map((Item item) { + return ExpansionPanel( + headerBuilder: (BuildContext context, bool isExpanded) { + return ListTile( + title: Text(item.headerValue), + ); + }, + body: ListTile( + title: Text(item.expandedValue), + ), + isExpanded: item.isExpanded, + ); + }).toList(), + ); + } +} + +class Item { + Item({ + required this.expandedValue, + required this.headerValue, + this.isExpanded = false, + }); + + String expandedValue; + String headerValue; + bool isExpanded; +} + +List generateItems(int count) { + return List.generate(count, (int index) { + return Item( + headerValue: 'Week ${index + 1}', + expandedValue: 'This is item number $index', + ); + }); +} diff --git a/gsf/lib/views/pages/test/age_calculator.dart b/gsf/lib/views/pages/test/age_calculator.dart new file mode 100644 index 0000000..e53bed8 --- /dev/null +++ b/gsf/lib/views/pages/test/age_calculator.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + + + +class AgeCalculator extends StatefulWidget { + const AgeCalculator({super.key}); + + @override + State createState() => _AgeCalculatorState(); +} + +class _AgeCalculatorState extends State { + final dateController = TextEditingController(); + String age = '0'; + + @override + void dispose() { + // Clean up the controller when the widget is removed + dateController.dispose(); + super.dispose(); + } + + String calculateAge(DateTime birthDate) { + DateTime currentDate = DateTime.now(); + int age = currentDate.year - birthDate.year; + int month1 = currentDate.month; + int month2 = birthDate.month; + if (month2 > month1) { + age--; + } else if (month1 == month2) { + int day1 = currentDate.day; + int day2 = birthDate.day; + if (day2 > day1) { + age--; + } + } + return age.toString(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Flutter Date Picker Example'), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Center( + child: Column(children: [ + TextField( + readOnly: true, + controller: dateController, + decoration: const InputDecoration(hintText: 'Pick your Date'), + onTap: () async { + var date = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(1900), + lastDate: DateTime(2100)); + if (date != null) { + setState(() { + age = calculateAge(date); + }); + dateController.text = DateFormat('dd/MM/yyyy').format(date); + } + }, + ), + Text('You are $age years old!') + ])))); + } +} \ No newline at end of file diff --git a/gsf/lib/views/pages/test/age_defined.dart b/gsf/lib/views/pages/test/age_defined.dart new file mode 100644 index 0000000..85f0146 --- /dev/null +++ b/gsf/lib/views/pages/test/age_defined.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Age Calculator', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: AgeInputForm(), + ); + } +} + +class AgeInputForm extends StatefulWidget { + const AgeInputForm({super.key}); + + @override + _AgeInputFormState createState() => _AgeInputFormState(); +} + +class _AgeInputFormState extends State { + DateTime? _selectedDate; + final TextEditingController _ageController = TextEditingController(); + + void _selectDate(BuildContext context) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: _selectedDate ?? DateTime.now(), + firstDate: DateTime(1900), + lastDate: DateTime.now(), + ); + + if (picked != null && picked != _selectedDate) { + setState( + () { + _selectedDate = picked; + final today = DateTime.now(); + final age = today.year - + _selectedDate!.year - + ((today.month > _selectedDate!.month || + (today.month == _selectedDate!.month && + today.day >= _selectedDate!.day)) + ? 0 + : 1); + _ageController.text = age.toString(); + }, + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Age Calculator'), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + child: Column( + children: [ + FormField( + builder: (state) { + return InputDecorator( + decoration: InputDecoration( + labelText: 'Select your birthdate', + errorText: state.errorText, + ), + child: Row( + children: [ + Expanded( + child: Text( + _selectedDate != null + ? DateFormat('yyyy-MM-dd') + .format(_selectedDate!) + : 'Select your birthdate', + ), + ), + IconButton( + icon: Icon(Icons.calendar_today), + onPressed: () => _selectDate(context), + ), + ], + ), + ); + }, + validator: (value) { + if (value == null) { + return 'Please select your birthdate'; + } + return null; + }, + ), + SizedBox(height: 20.0), + TextFormField( + controller: _ageController, + keyboardType: TextInputType.number, + readOnly: true, + decoration: InputDecoration( + labelText: 'Age', + ), + ), + SizedBox(height: 20.0), + ElevatedButton( + onPressed: () { + // Handle form submission if needed + }, + child: Text('Submit'), + ), + ], + ), + ), + ), + ); + } + + @override + void dispose() { + _ageController.dispose(); + super.dispose(); + } +} diff --git a/gsf/lib/views/pages/test/animated_counter_clock.dart b/gsf/lib/views/pages/test/animated_counter_clock.dart new file mode 100644 index 0000000..281d2fc --- /dev/null +++ b/gsf/lib/views/pages/test/animated_counter_clock.dart @@ -0,0 +1,122 @@ +import 'package:blobs/blobs.dart'; +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:intl/intl.dart'; +// import 'package:flutter_countdown_timer/index.dart'; +import 'package:slide_countdown/slide_countdown.dart'; +import '../../components/appbar.dart'; + +class AnimatedCounterClock extends StatefulWidget { + // final String activityTitle; + final dynamic timer; + const AnimatedCounterClock({Key? key, required this.timer}) : super(key: key); + + @override + State createState() => _AnimatedCounterClockState(); +} + +class _AnimatedCounterClockState extends State { + // late int timeDuration; + + BlobController blobCtrl = BlobController(); + @override + Widget build(BuildContext context) { + // print('Widget timer ${widget.timer}'); + + // chnage the datetime formate start + + // final dateStr = widget.timer; + // final newDateFormat = "yyyy, MM, dd"; + // final parsedDate = DateTime.parse(dateStr); + // final formattedDate = + // DateFormat(newDateFormat).format(parsedDate).split(','); + // print('formattedDate ${formattedDate.runtimeType}'); + + // List dateNew = formattedDate; + // List intList = dateNew.map((str) => int.parse(str)).toList(); + + // print('DATE NEW $dateNew'); + // final newYear = int.parse(dateNew[0]); + // final newMonth = int.parse(dateNew[1]); + // final newDay = int.parse(dateNew[2]); + // print('New year ${newDay}'); + + // var dateInt = DateTime.parse(widget.timer); + + // chnage the datetime formate end + + // final currentDate = DateTime.now(); + // final targetDate = DateTime(newYear, newMonth, 18); + // print('targeted date ${targetDate.runtimeType}'); + + // final duration = targetDate.difference(currentDate); + // final days = duration.inDays; + // final hours = duration.inHours.remainder(24); + // final minutes = duration.inMinutes.remainder(60); + // final seconds = duration.inSeconds.remainder(60); + + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars(titleHead: 'Animated Counter Clock'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer( + flex: 4, + ), + // Lottie.asset('assets/lottie/timer.json', height: 200), + Blob.animatedRandom( + loop: true, + size: 400, + edgesCount: 9, + minGrowth: 7, + controller: blobCtrl, + duration: const Duration(milliseconds: 1500), + styles: BlobStyles(color: ColorConstants.kPrimaryColor), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + 'We will go live\n within', + style: TextStyle( + fontSize: 18, + color: ColorConstants.kBlack, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + // Text( + // '${widget.timer} Days', + // style: TextStyle( + // fontSize: 25, + // color: ColorConstants.kBlack, + // ), + // ), + SlideCountdown( + duration: Duration(days: int.parse(widget.timer)), + decoration: + const BoxDecoration(color: Colors.transparent), + textStyle: const TextStyle( + color: ColorConstants.kBlack, fontSize: 30), + separatorStyle: const TextStyle( + color: ColorConstants.kBlack, fontSize: 30), + ) + ], + ), + ), + ), + const Spacer( + flex: 7, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/animation.dart b/gsf/lib/views/pages/test/animation.dart new file mode 100644 index 0000000..0ae5311 --- /dev/null +++ b/gsf/lib/views/pages/test/animation.dart @@ -0,0 +1,170 @@ +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; + +class Test1 extends StatefulWidget { + const Test1({Key? key}) : super(key: key); + + @override + State createState() => _Test1State(); +} + +class _Test1State extends State { + ContainerTransitionType transitionType = ContainerTransitionType.fade; + void _showMarkedAsDoneSnackbar(bool? isMarkedAsDone) {} + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text( + 'Animation Test', + style: TextStyle(fontSize: 20, color: Colors.white), + )), + body: Column( + children: [ + OpenContainer( + transitionType: ContainerTransitionType.fade, + transitionDuration: Duration(seconds: 1), + openBuilder: (BuildContext context, VoidCallback _) { + return const DetailsPage(); + }, + onClosed: _showMarkedAsDoneSnackbar, + tappable: false, + // closedBuilder: (context, action) { + // return Text('Close Builder action perform here'); + // }, + closedBuilder: (BuildContext _, VoidCallback openContainer) { + return _ExampleCard(openContainer: openContainer); + }, + ), + ], + ), + ); + } +} + +class OpenContainerWrapper extends StatelessWidget { + const OpenContainerWrapper({ + required this.closedBuilder, + required this.transitionType, + required this.onClosed, + }); + + final CloseContainerBuilder closedBuilder; + final ContainerTransitionType transitionType; + final ClosedCallback onClosed; + + @override + Widget build(BuildContext context) { + return OpenContainer( + transitionType: transitionType, + openBuilder: (BuildContext context, VoidCallback _) { + return const DetailsPage(); + }, + onClosed: onClosed, + tappable: false, + closedBuilder: closedBuilder, + ); + } +} + +class DetailsPage extends StatelessWidget { + const DetailsPage({this.includeMarkAsDoneButton = true}); + + final bool includeMarkAsDoneButton; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Details page'), + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + color: Colors.black38, + height: 250, + width: MediaQuery.of(context).size.width, + child: Padding( + padding: const EdgeInsets.all(70.0), + child: Image.asset( + 'assets/placeholder_image.png', + ), + ), + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Title', + style: Theme.of(context).textTheme.headlineSmall!.copyWith( + color: Colors.black54, + fontSize: 30.0, + ), + ), + const SizedBox(height: 10), + Text( + '_loremIpsumParagraph', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Colors.black54, + height: 1.5, + fontSize: 16.0, + ), + ), + ], + ), + ), + ], + ), + ); + } +} + +class _ExampleCard extends StatelessWidget { + const _ExampleCard({required this.openContainer}); + + final VoidCallback openContainer; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: openContainer, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Container( + color: Colors.black38, + child: Center( + child: Image.asset( + 'assets/placeholder_image.png', + width: 100, + ), + ), + ), + const ListTile( + title: Text('Title'), + subtitle: Text('Secondary text'), + ), + Padding( + padding: const EdgeInsets.only( + left: 16.0, + right: 16.0, + bottom: 16.0, + ), + child: Text( + 'Lorem ipsum dolor sit amet, consectetur ' + 'adipiscing elit, sed do eiusmod tempor.', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.black54), + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/blobs.dart b/gsf/lib/views/pages/test/blobs.dart new file mode 100644 index 0000000..05114c8 --- /dev/null +++ b/gsf/lib/views/pages/test/blobs.dart @@ -0,0 +1,74 @@ +// import 'package:flutter/material.dart'; +// import 'package:blobs/blobs.dart'; +// import 'package:get/get.dart'; +// import 'package:slide_countdown/slide_countdown.dart'; + +// import '../../theme.dart'; + +// class Blobs extends StatelessWidget { +// const Blobs({super.key}); + +// @override +// Widget build(BuildContext context) { +// BlobController blobCtrl = BlobController(); +// // final days = 3; + +// final currentDate = DateTime.now(); +// final targetDate = DateTime(2023, 7, 18); + +// final duration = targetDate.difference(currentDate); +// final days = duration.inDays; +// final hours = duration.inHours.remainder(24); +// final minutes = duration.inMinutes.remainder(60); +// final seconds = duration.inSeconds.remainder(60); + +// final formattedTime = '$days, $hours, $minutes, $seconds'; + +// return Scaffold( +// body: Center( +// child: Blob.animatedRandom( +// loop: true, +// size: 400, +// edgesCount: 9, +// minGrowth: 7, +// controller: blobCtrl, +// duration: const Duration(milliseconds: 1500), +// styles: BlobStyles(color: const Color(0xffB33771)), +// child: Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// const Text( +// 'Take a breath we will\n go live within', +// style: TextStyle( +// fontSize: 16, +// color: ColorConstants.kBlack, +// ), +// textAlign: TextAlign.center, +// ), +// Text( +// '${days} Days', +// style: TextStyle( +// fontSize: 25, +// color: ColorConstants.kBlack, +// ), +// ), +// SlideCountdown( +// duration: Duration( +// days: days, +// hours: hours, +// minutes: minutes, +// seconds: seconds), +// decoration: const BoxDecoration(color: Colors.transparent), +// textStyle: +// const TextStyle(color: ColorConstants.kBlack, fontSize: 30), +// separatorStyle: +// const TextStyle(color: ColorConstants.kBlack, fontSize: 30), +// ) +// ], +// ), +// ), +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/bottom_nav.dart b/gsf/lib/views/pages/test/bottom_nav.dart new file mode 100644 index 0000000..c799aef --- /dev/null +++ b/gsf/lib/views/pages/test/bottom_nav.dart @@ -0,0 +1,248 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/view_model/bottom_navigation_controller.dart'; +import 'package:gsp_app/views/pages/signIn/sign_in.dart'; + +import '../../../view_model/home_controller.dart'; +import '../../../view_model/home_page_controller.dart'; +import '../../theme.dart'; +import 'bottomnvigation_controller.dart'; + +class BottomNavigations extends StatefulWidget { + const BottomNavigations({ + Key? key, + // required this.three, + // required this.four, + // required this.five, + // required this.six, + // required this.seven, + }) : super(key: key); + // final GlobalKey three; + // final GlobalKey four; + // final GlobalKey five; + // final GlobalKey six; + // final GlobalKey seven; + + @override + State createState() => _BottomNavigationsState(); +} + +class _BottomNavigationsState extends State { + final NavigationCrontrollers navControllerTest = Get.find(); + int _selectedIndex = 0; + HomePageController homePageController = Get.put(HomePageController()); + final TabsController controller = TabsController(); + + void _onItemTapped(int index) { + HomePageController.SessionsActiveTabIndex = 0; + homePageController.updateBottomNavIndex(index); + } + + @override + void initState() { + super.initState(); + _selectedIndex = homePageController.bottomNavIndex.value; + } + + void ontaps() { + if (controller.isLoggedIn) { + _selectedIndex; + } else { + Get.to(() => const SignIn()); + } + } + + @override + Widget build(BuildContext context) { + final brightness = Get.theme.brightness; + double iconSize = 24; + return Theme( + data: Get.theme.copyWith(), + child: Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: ColorConstants.kBlack.withOpacity(0.6), + blurRadius: 10, + spreadRadius: 2, + // offset: + ) + ], + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + )), + child: BottomNavigationBar( + unselectedFontSize: 10, + selectedFontSize: 10, + unselectedItemColor: (brightness == Brightness.light) + ? ColorConstants.kBlack.withOpacity(0.6) + : ColorConstants.kWhite, + items: [ + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'home_black' : 'home'}.svg', + selectedIndex: _selectedIndex, + ), + // Showcase( + // targetPadding: const EdgeInsets.all(5), + // targetShapeBorder: const CircleBorder(), + // key: navControllerTest.f, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + + // ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'home_black' : 'home'}.svg', + width: iconSize, + height: iconSize, + ), + ), + label: 'Home', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'live_black' : 'live'}.svg', + selectedIndex: _selectedIndex, + ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'live_black' : 'live'}.svg', + width: iconSize, + height: iconSize, + ), + ), + + // Showcase( + // key: navControllerTest.g, + // targetShapeBorder: const CircleBorder(), + // targetPadding: const EdgeInsets.all(5), + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + // ), + label: 'Live Session', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'weight_scale_black' : 'weight_scale'}.svg', + selectedIndex: _selectedIndex, + ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'weight_scale_black' : 'weight_scale'}.svg', + width: iconSize, + height: iconSize, + ), + ), + + // Showcase( + // targetShapeBorder: const CircleBorder(), + // targetPadding: const EdgeInsets.all(5), + // key: navControllerTest.h, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + + // ), + label: 'Bio Maker', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'ranking_black' : 'ranking'}.svg', + selectedIndex: _selectedIndex, + ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'ranking_black' : 'ranking'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // Showcase( + // targetShapeBorder: const CircleBorder(), + // targetPadding: const EdgeInsets.all(5), + // key: navControllerTest.i, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + // ), + label: 'My Ranking', + ), + BottomNavigationBarItem( + activeIcon: ActiveIcon( + iconPath: + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'profile_black' : 'profile'}.svg', + selectedIndex: _selectedIndex, + ), + icon: Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: SvgPicture.asset( + 'assets/image/menuicon/${(brightness == Brightness.light) ? 'profile_black' : 'profile'}.svg', + width: iconSize, + height: iconSize, + ), + ), + // Showcase( + // targetShapeBorder: const CircleBorder(), + // targetPadding: const EdgeInsets.all(5), + // key: navControllerTest.j, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + // ), + label: 'Profile', + ), + ], + type: BottomNavigationBarType.fixed, + currentIndex: _selectedIndex, + selectedItemColor: (brightness == Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kPrimaryColor, + iconSize: 40, + onTap: _onItemTapped, + elevation: 0, + ), + ), + ); + } +} + +class ActiveIcon extends StatelessWidget { + const ActiveIcon({ + required this.iconPath, + required this.selectedIndex, + Key? key, + }) : super(key: key); + + final String iconPath; + final int selectedIndex; + + @override + Widget build(BuildContext context) { + return Container( + width: 28, + height: 28, + padding: const EdgeInsets.all(5), + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: ColorConstants.kPrimaryColor, + ), + child: SvgPicture.asset( + iconPath, + color: Colors.black, + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/bottomnvigation_controller.dart b/gsf/lib/views/pages/test/bottomnvigation_controller.dart new file mode 100644 index 0000000..c92b963 --- /dev/null +++ b/gsf/lib/views/pages/test/bottomnvigation_controller.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +// NavigationController extends NavigationController +class NavigationCrontrollers extends GetxController { + final a = GlobalKey>(); + final b = GlobalKey>(); + final c = GlobalKey>(); + final d = GlobalKey>(); + final e = GlobalKey>(); + final f = GlobalKey>(); + final g = GlobalKey>(); + final h = GlobalKey>(); + final i = GlobalKey>(); + final j = GlobalKey>(); +} diff --git a/gsf/lib/views/pages/test/colors_util.dart b/gsf/lib/views/pages/test/colors_util.dart new file mode 100644 index 0000000..dd7e7c4 --- /dev/null +++ b/gsf/lib/views/pages/test/colors_util.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class HexColor extends Color { + static int _getColorFromHex(String hexColor) { + hexColor = hexColor.toUpperCase().replaceAll("#", ""); + if (hexColor.length == 6) { + hexColor = "FF" + hexColor; + } + return int.parse(hexColor, radix: 16); + } + + HexColor(final String hexColor) : super(_getColorFromHex(hexColor)); +} diff --git a/gsf/lib/views/pages/test/counter_clock_list.dart b/gsf/lib/views/pages/test/counter_clock_list.dart new file mode 100644 index 0000000..14bda6d --- /dev/null +++ b/gsf/lib/views/pages/test/counter_clock_list.dart @@ -0,0 +1,59 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter/src/widgets/framework.dart'; +// import 'package:flutter/src/widgets/placeholder.dart'; +// import 'package:get/get.dart'; +// import 'package:gsp_app/views/theme.dart'; + +// import 'animated_counter_clock.dart'; + +// class ClockCounterList extends StatefulWidget { +// const ClockCounterList({super.key}); + +// @override +// State createState() => _ClockCounterListState(); +// } + +// class _ClockCounterListState extends State { +// List timings = [ +// '2', +// '3', +// '1', +// '8', +// '6', +// '7', +// ]; +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: const Text('Counter Clock List'), +// ), +// body: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 80), +// child: ListView.builder( +// itemCount: timings.length, +// shrinkWrap: true, +// itemBuilder: (context, index) { +// return Card( +// child: TextButton( +// style: TextButton.styleFrom( +// backgroundColor: ColorConstants.kPrimaryColor), +// onPressed: () { +// Get.to(AnimatedCounterClock( +// timer: timings[index], +// )); +// }, +// child: Text( +// 'Count ${index + 1}', +// style: const TextStyle( +// fontSize: 20, +// color: ColorConstants.kBlack, +// ), +// ), +// ), +// ); +// }, +// ), +// )); +// } +// } diff --git a/gsf/lib/views/pages/test/croper_image.dart b/gsf/lib/views/pages/test/croper_image.dart new file mode 100644 index 0000000..6e4a5c2 --- /dev/null +++ b/gsf/lib/views/pages/test/croper_image.dart @@ -0,0 +1,297 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; + +class MyAppTest extends StatelessWidget { + const MyAppTest({Key? key}) : super(key: key); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + highlightColor: const Color(0xFFD0996F), + backgroundColor: const Color(0xFFFDF5EC), + canvasColor: const Color(0xFFFDF5EC), + textTheme: TextTheme( + headline5: ThemeData.light() + .textTheme + .headline5! + .copyWith(color: const Color(0xFFBC764A)), + ), + iconTheme: IconThemeData( + color: Colors.grey[600], + ), + appBarTheme: const AppBarTheme( + backgroundColor: Color(0xFFBC764A), + centerTitle: false, + foregroundColor: Colors.white, + actionsIconTheme: IconThemeData(color: Colors.white), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ButtonStyle( + backgroundColor: MaterialStateColor.resolveWith( + (states) => const Color(0xFFBC764A)), + ), + ), + outlinedButtonTheme: OutlinedButtonThemeData( + style: ButtonStyle( + foregroundColor: MaterialStateColor.resolveWith( + (states) => const Color(0xFFBC764A), + ), + side: MaterialStateBorderSide.resolveWith( + (states) => const BorderSide(color: Color(0xFFBC764A))), + ), + )), + home: const HomePages(title: 'Image Cropper Demo'), + ); + } +} + +class HomePages extends StatefulWidget { + final String title; + + const HomePages({ + Key? key, + required this.title, + }) : super(key: key); + + @override + _HomePagesState createState() => _HomePagesState(); +} + +class _HomePagesState extends State { + XFile? _pickedFile; + CroppedFile? _croppedFile; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: !kIsWeb ? AppBar(title: Text(widget.title)) : null, + body: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (kIsWeb) + Padding( + padding: const EdgeInsets.all(kIsWeb ? 24.0 : 16.0), + child: Text( + widget.title, + style: Theme.of(context) + .textTheme + .displayMedium! + .copyWith(color: Theme.of(context).highlightColor), + ), + ), + Expanded(child: _body()), + ], + ), + ); + } + + Widget _body() { + if (_croppedFile != null || _pickedFile != null) { + return _imageCard(); + } else { + return _uploaderCard(); + } + } + + Widget _imageCard() { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: kIsWeb ? 24.0 : 16.0), + child: Card( + elevation: 4.0, + child: Padding( + padding: const EdgeInsets.all(kIsWeb ? 24.0 : 16.0), + child: _image(), + ), + ), + ), + const SizedBox(height: 24.0), + _menu(), + ], + ), + ); + } + + Widget _image() { + final screenWidth = MediaQuery.of(context).size.width; + final screenHeight = MediaQuery.of(context).size.height; + if (_croppedFile != null) { + final path = _croppedFile!.path; + return ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 0.8 * screenWidth, + maxHeight: 0.7 * screenHeight, + ), + child: kIsWeb ? Image.network(path) : Image.file(File(path)), + ); + } else if (_pickedFile != null) { + final path = _pickedFile!.path; + return ConstrainedBox( + constraints: BoxConstraints( + maxWidth: 0.8 * screenWidth, + maxHeight: 0.7 * screenHeight, + ), + child: kIsWeb ? Image.network(path) : Image.file(File(path)), + ); + } else { + return const SizedBox.shrink(); + } + } + + Widget _menu() { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + FloatingActionButton( + onPressed: () { + _clear(); + }, + backgroundColor: Colors.redAccent, + tooltip: 'Delete', + child: const Icon(Icons.delete), + ), + if (_croppedFile == null) + Padding( + padding: const EdgeInsets.only(left: 32.0), + child: FloatingActionButton( + onPressed: () { + _cropImage(); + }, + backgroundColor: const Color(0xFFBC764A), + tooltip: 'Crop', + child: const Icon(Icons.crop), + ), + ) + ], + ); + } + + Widget _uploaderCard() { + return Center( + child: Card( + elevation: 4.0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16.0), + ), + child: SizedBox( + width: kIsWeb ? 380.0 : 320.0, + height: 300.0, + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.image, + color: Theme.of(context).highlightColor, + size: 80.0, + ), + const SizedBox(height: 24.0), + Text( + 'Upload an image to start', + style: kIsWeb + ? Theme.of(context).textTheme.headline5!.copyWith( + color: Theme.of(context).highlightColor) + : Theme.of(context).textTheme.bodyText2!.copyWith( + color: Theme.of(context).highlightColor), + ) + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 24.0), + child: ElevatedButton( + onPressed: () { + _uploadImage(); + }, + child: const Text('Upload'), + ), + ), + ], + ), + ), + ), + ); + } + + Future _cropImage() async { + if (_pickedFile != null) { + final croppedFile = await ImageCropper().cropImage( + sourcePath: _pickedFile!.path, + compressFormat: ImageCompressFormat.jpg, + compressQuality: 100, + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'Cropper', + toolbarColor: Colors.deepOrange, + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: false), + IOSUiSettings( + title: 'Cropper', + ), + WebUiSettings( + context: context, + presentStyle: CropperPresentStyle.dialog, + boundary: const CroppieBoundary( + width: 520, + height: 520, + ), + viewPort: + const CroppieViewPort(width: 480, height: 480, type: 'circle'), + enableExif: true, + enableZoom: true, + showZoomer: true, + ), + ], + ); + if (croppedFile != null) { + setState(() { + _croppedFile = croppedFile; + }); + } + } + } + + Future _uploadImage() async { + final pickedFile = + await ImagePicker().pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + setState(() { + _pickedFile = pickedFile; + }); + } + } + + void _clear() { + setState(() { + _pickedFile = null; + _croppedFile = null; + }); + } +} diff --git a/gsf/lib/views/pages/test/date_calender.dart b/gsf/lib/views/pages/test/date_calender.dart new file mode 100644 index 0000000..76a5632 --- /dev/null +++ b/gsf/lib/views/pages/test/date_calender.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; + +import 'colors_util.dart'; +import 'date_utils.dart' as date_util; + +class MyHomePage1 extends StatefulWidget { + final String title; + const MyHomePage1({Key? key, required this.title}) : super(key: key); + + @override + _MyHomePage1State createState() => _MyHomePage1State(); +} + +class _MyHomePage1State extends State { + double width = 0.0; + double height = 0.0; + late ScrollController scrollController; + List currentMonthList = List.empty(); + DateTime currentDateTime = DateTime.now(); + + @override + void initState() { + currentMonthList = date_util.DateUtils.daysInMonth(currentDateTime); + currentMonthList.sort((a, b) => a.day.compareTo(b.day)); + currentMonthList = currentMonthList.toSet().toList(); + scrollController = + ScrollController(initialScrollOffset: 37.0 * currentDateTime.day); + super.initState(); + } + + Widget titleView() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 20), + child: Text( + date_util.DateUtils.months[currentDateTime.month - 1] + + ' ' + + currentDateTime.year.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ); + } + + Widget hrizontalCapsuleListView() { + return SizedBox( + width: width, + height: 70, + child: ListView.builder( + controller: scrollController, + scrollDirection: Axis.horizontal, + physics: const ClampingScrollPhysics(), + shrinkWrap: true, + itemCount: currentMonthList.length, + itemBuilder: (BuildContext context, int index) { + return capsuleView(index); + }, + ), + ); + } + + Widget capsuleView(int index) { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), + child: GestureDetector( + onTap: () { + setState(() { + currentDateTime = currentMonthList[index]; + }); + }, + child: Container( + width: 45, + height: 67, + decoration: BoxDecoration( + color: (currentMonthList[index].day != currentDateTime.day) + ? Colors.red + : Colors.yellow, + borderRadius: BorderRadius.circular(40), + boxShadow: [ + BoxShadow( + offset: Offset(4, 4), + blurRadius: 4, + spreadRadius: 2, + color: Colors.black12, + ) + ]), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + currentMonthList[index].day.toString(), + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + height: 1, + color: + (currentMonthList[index].day != currentDateTime.day) + ? HexColor("465876") + : Colors.white, + ), + ), + Text( + date_util.DateUtils + .weekdays[currentMonthList[index].weekday - 1], + style: TextStyle( + fontSize: + (currentMonthList[index].day != currentDateTime.day) + ? 12 + : 14, + fontWeight: FontWeight.bold, + color: + (currentMonthList[index].day != currentDateTime.day) + ? HexColor("465876") + : Colors.white, + ), + ) + ], + ), + ), + ), + )); + } + + Widget topView() { + return SizedBox( + // height: height * 0.35, + width: width, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + titleView(), + hrizontalCapsuleListView(), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + width = MediaQuery.of(context).size.width; + height = MediaQuery.of(context).size.height; + return Scaffold( + backgroundColor: Colors.black, + body: Stack( + children: [topView()], + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/date_test.dart b/gsf/lib/views/pages/test/date_test.dart new file mode 100644 index 0000000..b1d774d --- /dev/null +++ b/gsf/lib/views/pages/test/date_test.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +class DateTEst extends StatelessWidget { + const DateTEst({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final now = DateTime.now(); + final monthNames = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ]; + + return Scaffold( + appBar: AppBar( + title: Text('Current Date and Months List'), + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Text( + '${now.day} ${monthNames[now.month - 1]}, ${now.year}', + style: const TextStyle(fontSize: 24), + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/date_utils.dart b/gsf/lib/views/pages/test/date_utils.dart new file mode 100644 index 0000000..b9b3d76 --- /dev/null +++ b/gsf/lib/views/pages/test/date_utils.dart @@ -0,0 +1,183 @@ +library utils; + +import 'package:intl/intl.dart'; + +class DateUtils { + static final DateFormat _monthFormat = DateFormat('MMMM yyyy'); + static final DateFormat _dayFormat = DateFormat('dd'); + static final DateFormat _firstDayFormat = DateFormat('MMM dd'); + static final DateFormat _fullDayFormat = DateFormat('EEE MMM dd, yyyy'); + static final DateFormat _apiDayFormat = DateFormat('yyyy-MM-dd'); + + static String formatMonth(DateTime d) => _monthFormat.format(d); + + static String formatDay(DateTime d) => _dayFormat.format(d); + + static String formatFirstDay(DateTime d) => _firstDayFormat.format(d); + + static String fullDayFormat(DateTime d) => _fullDayFormat.format(d); + + static String apiDayFormat(DateTime d) => _apiDayFormat.format(d); + + static const List weekdays = [ + 'Mon', + 'Tue', + 'Wed', + 'Thu', + 'Fri', + 'Sat', + 'Sun' + ]; + + static const List months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ]; + + /// The list of days in a given month + static List daysInMonth(DateTime month) { + var first = firstDayOfMonth(month); + var last = DateUtils.lastDayOfMonth(month); + + var daysAfter = 7 - last.weekday; + + // If the last day is sunday (7) the entire week must be rendered + if (daysAfter == 0) { + daysAfter = 7; + } + + // var lastToDisplay = last.add(Duration(days: daysAfter)); + return daysRange(first, last).toList(); + } + + static Iterable daysRange(DateTime first, DateTime last) { + var listOfDates = new List.generate( + last.day, (i) => DateTime(first.year, first.month, i + 1)); + return listOfDates; + } + + static bool isFirstDayOfMonth(DateTime day) { + return isSameDay(firstDayOfMonth(day), day); + } + + static bool isLastDayOfMonth(DateTime day) { + return isSameDay(lastDayOfMonth(day), day); + } + + static DateTime firstDayOfMonth(DateTime month) { + return DateTime(month.year, month.month); + } + + static DateTime firstDayOfWeek(DateTime day) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + day = DateTime.utc(day.year, day.month, day.day, 12); + + /// Weekday is on a 1-7 scale Monday - Sunday, + /// This Calendar works from Sunday - Monday + var decreaseNum = day.weekday % 7; + return day.subtract(Duration(days: decreaseNum)); + } + + static DateTime lastDayOfWeek(DateTime day) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + day = DateTime.utc(day.year, day.month, day.day, 12); + + /// Weekday is on a 1-7 scale Monday - Sunday, + /// This Calendar's Week starts on Sunday + var increaseNum = day.weekday % 7; + return day.add(Duration(days: 7 - increaseNum)); + } + + /// The last day of a given month + static DateTime lastDayOfMonth(DateTime month) { + var beginningNextMonth = (month.month < 12) + ? DateTime(month.year, month.month + 1, 1) + : DateTime(month.year + 1, 1, 1); + return beginningNextMonth.subtract(Duration(days: 1)); + } + + /// Returns a [DateTime] for each day the given range. + /// + /// [start] inclusive + /// [end] exclusive + static Iterable daysInRange(DateTime start, DateTime end) sync* { + var i = start; + var offset = start.timeZoneOffset; + while (i.day <= end.day) { + yield i; + i = i.add(Duration(days: 1)); + var timeZoneDiff = i.timeZoneOffset - offset; + if (timeZoneDiff.inSeconds != 0) { + offset = i.timeZoneOffset; + i = i.subtract(Duration(seconds: timeZoneDiff.inSeconds)); + } + } + } + + /// Whether or not two times are on the same day. + static bool isSameDay(DateTime a, DateTime b) { + return a.year == b.year && a.month == b.month && a.day == b.day; + } + + static bool isSameWeek(DateTime a, DateTime b) { + /// Handle Daylight Savings by setting hour to 12:00 Noon + /// rather than the default of Midnight + a = DateTime.utc(a.year, a.month, a.day); + b = DateTime.utc(b.year, b.month, b.day); + + var diff = a.toUtc().difference(b.toUtc()).inDays; + if (diff.abs() >= 7) { + return false; + } + + var min = a.isBefore(b) ? a : b; + var max = a.isBefore(b) ? b : a; + var result = max.weekday % 7 - min.weekday % 7 >= 0; + return result; + } + + static DateTime previousMonth(DateTime m) { + var year = m.year; + var month = m.month; + if (month == 1) { + year--; + month = 12; + } else { + month--; + } + return DateTime(year, month); + } + + static DateTime nextMonth(DateTime m) { + var year = m.year; + var month = m.month; + + if (month == 12) { + year++; + month = 1; + } else { + month++; + } + return DateTime(year, month); + } + + static DateTime previousWeek(DateTime w) { + return w.subtract(Duration(days: 7)); + } + + static DateTime nextWeek(DateTime w) { + return w.add(Duration(days: 7)); + } +} diff --git a/gsf/lib/views/pages/test/detailscreen.dart b/gsf/lib/views/pages/test/detailscreen.dart new file mode 100644 index 0000000..f171498 --- /dev/null +++ b/gsf/lib/views/pages/test/detailscreen.dart @@ -0,0 +1,129 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class Detail extends StatefulWidget { + const Detail({Key? key}) : super(key: key); + + @override + _DetailState createState() => _DetailState(); +} + +class _DetailState extends State { + final GlobalKey _one = GlobalKey(); + BuildContext? myContext; + + @override + void initState() { + super.initState(); + //NOTE: remove ambiguate function if you are using + //flutter version greater than 3.x and direct use WidgetsBinding.instance + // ambiguate(WidgetsBinding.instance)?.addPostFrameCallback( + // (_) => Future.delayed( + // const Duration(milliseconds: 200), + // () { + // ShowCaseWidget.of(myContext!).startShowCase([_one]); + // }, + // ), + // ); + } + + @override + Widget build(BuildContext context) { + return + // ShowCaseWidget( + // builder: Builder( + // builder: (context) { + // myContext = context; + // return + Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + leading: IconButton( + icon: const Icon( + Icons.arrow_back, + color: Colors.black, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: ListView( + children: [ + InkWell( + onTap: () {}, + child: const Text( + 'Flutter Notification', + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.w600, + ), + ), + ), + // Showcase( + // key: _one, + // title: 'Title', + // description: 'Desc', + // child: + + // ), + const SizedBox( + height: 16, + ), + const Text( + 'Hi, you have new Notification from flutter group, open ' + 'slack and check it out', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), + ), + const SizedBox( + height: 16, + ), + RichText( + text: const TextSpan( + style: TextStyle( + fontWeight: FontWeight.w400, + color: Colors.black, + ), + children: [ + TextSpan(text: 'Hi team,\n\n'), + TextSpan( + text: 'As some of you know, we’re moving to Slack for ' + 'our internal team communications. Slack is a ' + 'messaging app where we can talk, share files, ' + 'and work together. It also connects with tools ' + 'we already use, like [add your examples here], ' + 'plus 900+ other apps.\n\n', + ), + TextSpan( + text: 'Why are we moving to Slack?\n\n', + style: TextStyle( + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + TextSpan( + text: 'We want to use the best communication tools to ' + 'make our lives easier and be more productive. ' + 'Having everything in one place will help us ' + 'work together better and faster, rather than ' + 'jumping around between emails, IMs, texts and ' + 'a bunch of other programs. Everything you share ' + 'in Slack is automatically indexed and archived, ' + 'creating a searchable archive of all our work.', + ), + ], + ), + ), + ], + ), + ), + ); + + // }, + // ), + // ); + } +} diff --git a/gsf/lib/views/pages/test/image_downloader.dart b/gsf/lib/views/pages/test/image_downloader.dart new file mode 100644 index 0000000..cefccbc --- /dev/null +++ b/gsf/lib/views/pages/test/image_downloader.dart @@ -0,0 +1,52 @@ +// import 'package:flutter/material.dart'; +// import 'package:image_downloader/image_downloader.dart'; + +// class ImageDownloaderInFile extends StatefulWidget { +// const ImageDownloaderInFile({Key? key}) : super(key: key); + +// @override +// _ImageDownloaderInFileState createState() => _ImageDownloaderInFileState(); +// } + +// class _ImageDownloaderInFileState extends State { +// String imageUrl = 'https://picsum.photos/id/42/200/200'; +// bool isDownloading = false; +// double progress = 0.0; + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text('Download Image'), +// ), +// body: Center( +// child: Column( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Image.network(imageUrl), +// const SizedBox(height: 16.0), +// if (isDownloading) +// LinearProgressIndicator( +// value: progress, +// ), +// OutlinedButton( +// onPressed: () { +// setState(() { +// isDownloading = true; +// }); +// ImageDownloader.downloadImage(imageUrl).then((value) { +// setState(() { +// isDownloading = false; +// }); +// }).catchError((error) { +// print('Error $error'); +// }); +// }, +// child: const Text('Download Image'), +// ), +// ], +// ), +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/image_zoom.dart b/gsf/lib/views/pages/test/image_zoom.dart new file mode 100644 index 0000000..c04ef06 --- /dev/null +++ b/gsf/lib/views/pages/test/image_zoom.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; + +class ImageZoom extends StatefulWidget { + const ImageZoom({Key? key}) : super(key: key); + + @override + State createState() => _ImageZoomState(); +} + +class _ImageZoomState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: PhotoView( + // minScale: 100.01, + // maxScale: 100.00, + imageProvider: const NetworkImage( + "https://images.unsplash.com/photo-1687161590608-6d948d357bad?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1906&q=80"), + minScale: PhotoViewComputedScale.contained * 0.8, + // enableRotation: true, + heroAttributes: PhotoViewHeroAttributes(tag: 'tag') + // initialScale: 0.5, + // maxScale: PhotoViewComputedScale.covered * 1.1, + // initialScale: PhotoViewComputedScale.covered * 1.1, + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/just_audio.dart b/gsf/lib/views/pages/test/just_audio.dart new file mode 100644 index 0000000..b6c5085 --- /dev/null +++ b/gsf/lib/views/pages/test/just_audio.dart @@ -0,0 +1,79 @@ +import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; +import 'package:flutter/material.dart'; +import 'page_manager.dart'; + +class JustAudios extends StatefulWidget { + const JustAudios({Key? key}) : super(key: key); + + @override + _JustAudiosState createState() => _JustAudiosState(); +} + +class _JustAudiosState extends State { + late final PageManager _pageManager; + + @override + void initState() { + super.initState(); + _pageManager = PageManager(); + } + + @override + void dispose() { + _pageManager.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + children: [ + const Spacer(), + ValueListenableBuilder( + valueListenable: _pageManager.progressNotifier, + builder: (_, value, __) { + return ProgressBar( + progress: value.current, + buffered: value.buffered, + total: value.total, + onSeek: _pageManager.seek, + ); + }, + ), + ValueListenableBuilder( + valueListenable: _pageManager.buttonNotifier, + builder: (_, value, __) { + switch (value) { + case ButtonState.loading: + return Container( + margin: const EdgeInsets.all(8.0), + width: 32.0, + height: 32.0, + child: const CircularProgressIndicator(), + ); + case ButtonState.paused: + return IconButton( + icon: const Icon(Icons.play_arrow), + iconSize: 32.0, + onPressed: _pageManager.play, + ); + case ButtonState.playing: + return IconButton( + icon: const Icon(Icons.pause), + iconSize: 32.0, + onPressed: _pageManager.pause, + ); + } + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/modelTest.dart b/gsf/lib/views/pages/test/modelTest.dart new file mode 100644 index 0000000..166aa62 --- /dev/null +++ b/gsf/lib/views/pages/test/modelTest.dart @@ -0,0 +1,95 @@ +// ignore_for_file: prefer_const_constructors, unrelated_type_equality_checks + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:intl/intl.dart'; + +class PopupAfterTwoMinutes extends StatefulWidget { + const PopupAfterTwoMinutes({Key? key}) : super(key: key); + + @override + _PopupAfterTwoMinutesState createState() => _PopupAfterTwoMinutesState(); +} + +class _PopupAfterTwoMinutesState extends State { + late DateTime _lastShown; + late GetStorage _storage; + late Timer timer; + + @override + void initState() { + super.initState(); + final tData = DateFormat("HH:mm:ss a").format(DateTime.now()); + final now = DateTime.now(); + print('current date time :- ${now}'); + print('current only time :- ${tData}'); + final confirmTime = '13:06:00 PM'; + + Timer mytimer = Timer.periodic(Duration(seconds: 2), (timer) { + if (tData == confirmTime) { + print('timer every 2 seconds'); + } + }); + // _initPrefs(); + } + + void _initPrefs() async { + await GetStorage.init(); + _storage = GetStorage(); + _lastShown = DateTime.tryParse(_storage.read('last_shown3') ?? '') ?? + DateTime.now().subtract(const Duration(days: 1)); + // print('last_shown time: ${GetStorage().read('last_shown3')}'); + // print('last_shown only: ${_lastShown}'); + // subtracting 24 hours to ensure that the popup is shown immediately on the first run + _checkToShowPopup(); + } + + void _checkToShowPopup() { + final tData = DateFormat("HH:mm:ss a").format(DateTime.now()); + final now = DateTime.now(); + final confirmTime = '01:04:00'; + print('current date time :- ${now}'); + print('current only time :- ${tData}'); + final difference = now.difference(_lastShown); + // print('difference.inSeconds :- ${difference.inSeconds}'); + if (tData == confirmTime) { + print('timer every 2 seconds'); + } + } + + void _showPopup() { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Popup Title'), + content: Text('Popup Content'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + _lastShown = DateTime.now(); + _storage.write('last_shown3', _lastShown.toString()); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('My App'), + ), + body: Center( + child: Text('Welcome to my app!'), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/no_internet_connection.dart b/gsf/lib/views/pages/test/no_internet_connection.dart new file mode 100644 index 0000000..f6c1cc6 --- /dev/null +++ b/gsf/lib/views/pages/test/no_internet_connection.dart @@ -0,0 +1,85 @@ +import 'dart:async'; +import 'dart:developer' as developer; + +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../components/appbar.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class NoInternetConnectTest extends StatefulWidget { + const NoInternetConnectTest({Key? key}) : super(key: key); + + @override + State createState() => _NoInternetConnectTestState(); +} + +class _NoInternetConnectTestState extends State { + ConnectivityResult _connectionStatus = ConnectivityResult.none; + final Connectivity _connectivity = Connectivity(); + late StreamSubscription _connectivitySubscription; + + @override + void initState() { + super.initState(); + initConnectivity(); + + _connectivitySubscription = + _connectivity.onConnectivityChanged.listen(_updateConnectionStatus); + } + + @override + void dispose() { + _connectivitySubscription.cancel(); + super.dispose(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initConnectivity() async { + late ConnectivityResult result; + // Platform messages may fail, so we use a try/catch PlatformException. + try { + result = await _connectivity.checkConnectivity(); + } on PlatformException catch (e) { + developer.log('Couldn\'t check connectivity status', error: e); + return; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) { + return Future.value(null); + } + + return _updateConnectionStatus(result); + } + + Future _updateConnectionStatus(ConnectivityResult result) async { + setState(() { + _connectionStatus = result; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: CustomAppBars( + titleHead: 'No Internet', + showLeading: false, + ), + ), + body: Center( + child: Text( + 'Connection Status: ${_connectionStatus.toString()}', + ), + )); + } +} diff --git a/gsf/lib/views/pages/test/our_thoutghs.dart b/gsf/lib/views/pages/test/our_thoutghs.dart new file mode 100644 index 0000000..515a2c2 --- /dev/null +++ b/gsf/lib/views/pages/test/our_thoutghs.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/repository/response_data.dart'; + +import '../../../modals/share_thoughts.dart'; +import '../../../repository/services/share_thoughts_service.dart'; +import '../../components/btn.dart'; +import '../../theme.dart'; + +class ShareThoutghs extends StatefulWidget { + const ShareThoutghs({Key? key}) : super(key: key); + + @override + State createState() => _ShareThoutghsState(); +} + +class _ShareThoutghsState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: context.width * 0.05), + child: FutureBuilder( + future: GetOurThoughts().getShareThoughtsData(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + ShareOurthoutghs shareOurthoutghs = snapshot.data!.data; + // print('GetOurThoughts :- ${shareOurthoutghs.userThoughts}'); + // print( + // 'snapshot connectionState :- ${snapshot.connectionState}'); + var thoughts = shareOurthoutghs.userThoughts.split(' '); + var indexs = thoughts; + print('GetOurThoughts new :- ${indexs}'); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: ColorConstants.kBlack, + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 25), + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: -80, + left: 0, + right: 0, + child: Align( + alignment: Alignment.center, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + ), + width: 100, + height: 100, + child: Image.asset( + 'assets/image/feedback_img/power.png', + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + ), + ), + Column( + children: [ + const SizedBox(height: 56), + Text( + '${thoughts[0]}', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + Text( + '${thoughts[1]}', + style: TextStyle( + fontSize: 42, + color: ColorConstants.kPrimaryColor, + fontWeight: FontWeight.w600, + letterSpacing: 3, + height: 1, + ), + ), + Text( + '${thoughts[2]}', + style: TextStyle( + fontSize: 30, + color: ColorConstants.kWhite, + height: 1, + fontWeight: FontWeight.w500, + letterSpacing: 1.07, + ), + ), + const SizedBox(height: 35), + FullWdtBtn( + btnText: 'Let\'s Go', + onTap: () { + Get.back(); + // Get.offAll( + // () => ShowCaseWidget( + // builder: Builder( + // builder: (context) => const HomePage(), + // ), + // ), + // () => const HomePage(), + // ); + }, + ) + ], + ), + ], + ), + ), + ), + ], + ); + } + return const CircularProgressIndicator(); + }, + )), + )); + } +} diff --git a/gsf/lib/views/pages/test/page_manager.dart b/gsf/lib/views/pages/test/page_manager.dart new file mode 100644 index 0000000..35959cf --- /dev/null +++ b/gsf/lib/views/pages/test/page_manager.dart @@ -0,0 +1,99 @@ +import 'package:flutter/material.dart'; +import 'package:just_audio/just_audio.dart'; + +class PageManager { + final progressNotifier = ValueNotifier( + ProgressBarState( + current: Duration.zero, + buffered: Duration.zero, + total: Duration.zero, + ), + ); + final buttonNotifier = ValueNotifier(ButtonState.paused); + + static const url = + 'https://ghantalele.com/uploads/files/data-78/38825/Besharam%20Rang_192(Ghantalele.com).mp3'; + static const urlAssets = 'assets/audio/nature.mp3'; + late AudioPlayer _audioPlayer; + PageManager() { + _init(); + } + + void _init() async { + _audioPlayer = AudioPlayer(); + await _audioPlayer.setUrl(url); + // await _audioPlayer.setAsset(url); + + _audioPlayer.playerStateStream.listen((playerState) { + final isPlaying = playerState.playing; + final processingState = playerState.processingState; + if (processingState == ProcessingState.loading || + processingState == ProcessingState.buffering) { + buttonNotifier.value = ButtonState.loading; + } else if (!isPlaying) { + buttonNotifier.value = ButtonState.paused; + } else if (processingState != ProcessingState.completed) { + buttonNotifier.value = ButtonState.playing; + } else { + _audioPlayer.seek(Duration.zero); + _audioPlayer.pause(); + } + }); + + _audioPlayer.positionStream.listen((position) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: position, + buffered: oldState.buffered, + total: oldState.total, + ); + }); + + _audioPlayer.bufferedPositionStream.listen((bufferedPosition) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: oldState.current, + buffered: bufferedPosition, + total: oldState.total, + ); + }); + + _audioPlayer.durationStream.listen((totalDuration) { + final oldState = progressNotifier.value; + progressNotifier.value = ProgressBarState( + current: oldState.current, + buffered: oldState.buffered, + total: totalDuration ?? Duration.zero, + ); + }); + } + + void play() { + _audioPlayer.play(); + } + + void pause() { + _audioPlayer.pause(); + } + + void seek(Duration position) { + _audioPlayer.seek(position); + } + + void dispose() { + _audioPlayer.dispose(); + } +} + +class ProgressBarState { + ProgressBarState({ + required this.current, + required this.buffered, + required this.total, + }); + final Duration current; + final Duration buffered; + final Duration total; +} + +enum ButtonState { paused, playing, loading } diff --git a/gsf/lib/views/pages/test/past_session.dart b/gsf/lib/views/pages/test/past_session.dart new file mode 100644 index 0000000..fae805c --- /dev/null +++ b/gsf/lib/views/pages/test/past_session.dart @@ -0,0 +1,583 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:http/http.dart' as http; +import 'package:skeletons/skeletons.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../../modals/past_session_model.dart'; +import '../../../repository/endpoints.dart'; +import '../../../repository/response_data.dart'; +import '../../../repository/services/cj/past_session_services.dart'; +import '../../../view_model/global_controller.dart'; +import '../../theme.dart'; + +class PastSessionView extends StatefulWidget { + const PastSessionView({super.key}); + + @override + _PastSessionViewState createState() => _PastSessionViewState(); +} + +class _PastSessionViewState extends State { + @override + void initState() { + super.initState(); + // fetchData(); // Fetch data when the widget is initialized + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Past Session'), + ), + body: Column( + children: [ + Expanded( + child: previousSession(), + ), + ], + ), + ); + } + + previousSession() { + GlobalController globalContoller = Get.put(GlobalController()); + Future _launchInBrowser(String url) async { + var urlN = Uri.parse(url); + if (!await launchUrl( + urlN, + mode: LaunchMode.externalApplication, + )) { + throw Exception('Could not launch $url'); + } + } + + bool expandTile = false; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + FutureBuilder( + future: PastActivity().getPastActivityData(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // var week index + // print( + // 'Data!.result!.schedule! ${pastData!.result!.schedule![0].pastData![0].day}'); + + var pastDataInData = pastData!.result!.schedule!; + return Expanded( + child: pastData?.result != null + ? ListView.builder( + physics: const ScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: pastDataInData.length, + itemBuilder: (context, index) { + return + pastDataInData[index].pastData!.isNotEmpty? Container( + margin: const EdgeInsets.only( + bottom: 20, + ), // Set margin around each panel + child: ClipRRect( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30) + ), + + child: StatefulBuilder( + builder: (context, setState) { + return ExpansionPanelList( + dividerColor: + ColorConstants.kPrimaryColor, + elevation: 1, + expandedHeaderPadding: const EdgeInsets.all(0), + expansionCallback: + (int index, bool isExpanded) { + // isExpanded = !isExpanded; + if (isExpanded == false) { + setState(() { + expandTile = true; + }); + } else { + setState(() { + expandTile = false; + }); + } + }, + children: [ + ExpansionPanel( + headerBuilder: (BuildContext context, + bool isExpanded) { + return ListTile( + title: Text( + 'Week ${index+1}', // "Week ${((e.index) - listLen).abs()}", + style: const TextStyle( + color: ColorConstants + .kPrimaryColor, + ), + ), + ); + }, + body: Padding( + padding: const EdgeInsets.only( + bottom: 20, + left: 20, + right: 20, + ), + child: pastDataInData[index].pastData!.isEmpty + ? Center( + child: Text( + 'No Session found ☹️.', + style: TextStyle( + color: !globalContoller + .darkMode.value + ? Colors.black + : ColorConstants + .kPrimaryColor, + fontSize: 16, + ), + textAlign: + TextAlign.center, + ), + ) + : ListView.builder( + itemCount: + pastDataInData[index].pastData!.length, + shrinkWrap: true, + physics: ScrollPhysics(), + itemBuilder: + (context, index1) { + return Container( + decoration: + BoxDecoration( + border: Border.all( + color: ColorConstants + .kPrimaryColor, + ), + borderRadius: + BorderRadius + .circular(5), + ), + margin: EdgeInsets.only( + bottom: 20), + padding: EdgeInsets + .symmetric( + horizontal: 10, + vertical: 10, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Row( + children: [ + SvgPicture + .asset( + 'assets/image/calendar.svg'), + SizedBox( + width: + 10), + Text( + '${pastDataInData[index].pastData![index1].day}', + style: + TextStyle( + fontSize: + 14, + color: ColorConstants + .kWhite, + ), + ), + ], + ), + SizedBox( + height: 8), + Text( + '${pastDataInData[index].pastData![index1].activityName}', + style: + TextStyle( + fontSize: + 20, + color: ColorConstants + .kWhite, + fontFamily: + 'SFPRO', + letterSpacing: + 0.4, + fontWeight: + FontWeight + .bold, + ), + ), + SizedBox( + height: 10), + Row( + children: [ + SvgPicture + .asset( + 'assets/image/duration.svg'), + SizedBox( + width: + 10), + Text( + 'Duration ${pastDataInData[index].pastData![index1].duration} min', + style: + TextStyle( + fontSize: + 14, + color: ColorConstants + .kWhite, + ), + ), + Text( + ' - Yoga', + style: + TextStyle( + fontSize: + 14, + color: ColorConstants + .kWhite, + ), + ), + ], + ) + ], + ), + Container( + decoration: + BoxDecoration( + border: + Border.all( + color: ColorConstants + .kPrimaryColor, + width: 2, + ), + shape: BoxShape + .circle, + ), + child: + GestureDetector( + // redirect to Zoom for live session + onTap: () { + _launchInBrowser( + 'https://us02web.zoom.us/rec/share/Pcc6SAUO9DEjt2Cm25ZtN57ODUJNBobl4CYabomLyJl4wqseoq11hT5r454gIvZy.9xwrGs9_Un8vRIR4'); + // _launchURL(e.pastData![index].url); + }, + child: + const Padding( + padding: + EdgeInsets + .all( + 3.0), + child: Icon( + Icons + .play_arrow_rounded, + color: ColorConstants + .kPrimaryColor, + size: 35, + ), + ), + ), + ), + ], + ), + ); + }, + ), + ), + isExpanded: expandTile, + ), + ], + ); + }, + ), + ), + ):const SizedBox(); + }, + ) + : Center( + child: Text( + 'No Session found ☹️.', + style: TextStyle( + color: !globalContoller.darkMode.value + ? Colors.black + : ColorConstants.kPrimaryColor, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ), + ); + } + return Padding( + padding: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: 2, + itemBuilder: (context, index) => Container( + margin: const EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ), + ], + ), + ); + } +} + + + + +// Container( +// margin: EdgeInsets.only( +// bottom: 20, +// ), // Set margin around each panel +// child: ClipRRect( +// borderRadius: BorderRadius.circular(30), +// child: StatefulBuilder( +// builder: (context, setState) { +// return ExpansionPanelList( +// dividerColor: +// ColorConstants.kPrimaryColor, +// elevation: 1, +// expandedHeaderPadding: EdgeInsets.all(0), +// expansionCallback: +// (int index, bool isExpanded) { +// // isExpanded = !isExpanded; +// if (isExpanded == false) { +// setState(() { +// expandTile = true; +// }); +// } else { +// setState(() { +// expandTile = false; +// }); +// } +// }, +// children: [ +// ExpansionPanel( +// headerBuilder: (BuildContext context, +// bool isExpanded) { +// return ListTile( +// title: Text( +// 'Week ${(e.id)}', // "Week ${((e.index) - listLen).abs()}", +// style: TextStyle( +// color: ColorConstants +// .kPrimaryColor, +// ), +// ), +// ); +// }, +// body: Padding( +// padding: const EdgeInsets.only( +// bottom: 20, +// left: 20, +// right: 20, +// ), +// child: e.pastData!.isEmpty +// ? Center( +// child: Text( +// 'No Session found ☹️.', +// style: TextStyle( +// color: !globalContoller +// .darkMode.value +// ? Colors.black +// : ColorConstants +// .kPrimaryColor, +// fontSize: 16, +// ), +// textAlign: +// TextAlign.center, +// ), +// ) +// : ListView.builder( +// itemCount: +// e.pastData!.length, +// shrinkWrap: true, +// physics: ScrollPhysics(), +// itemBuilder: +// (context, index) { +// return Container( +// decoration: +// BoxDecoration( +// border: Border.all( +// color: ColorConstants +// .kPrimaryColor, +// ), +// borderRadius: +// BorderRadius +// .circular(5), +// ), +// margin: EdgeInsets.only( +// bottom: 20), +// padding: EdgeInsets +// .symmetric( +// horizontal: 10, +// vertical: 10, +// ), +// child: Row( +// mainAxisAlignment: +// MainAxisAlignment +// .spaceBetween, +// children: [ +// Column( +// mainAxisAlignment: +// MainAxisAlignment +// .start, +// crossAxisAlignment: +// CrossAxisAlignment +// .start, +// children: [ +// Row( +// children: [ +// SvgPicture +// .asset( +// 'assets/image/calendar.svg'), +// SizedBox( +// width: +// 10), +// Text( +// '${e.pastData![index].day}', +// style: +// TextStyle( +// fontSize: +// 14, +// color: ColorConstants +// .kWhite, +// ), +// ), +// ], +// ), +// SizedBox( +// height: 8), +// Text( +// '${e.pastData![index].activityName}', +// style: +// TextStyle( +// fontSize: +// 20, +// color: ColorConstants +// .kWhite, +// fontFamily: +// 'SFPRO', +// letterSpacing: +// 0.4, +// fontWeight: +// FontWeight +// .bold, +// ), +// ), +// SizedBox( +// height: 10), +// Row( +// children: [ +// SvgPicture +// .asset( +// 'assets/image/duration.svg'), +// SizedBox( +// width: +// 10), +// Text( +// 'Duration ${e.pastData![index].duration} min', +// style: +// TextStyle( +// fontSize: +// 14, +// color: ColorConstants +// .kWhite, +// ), +// ), +// Text( +// ' - Yoga', +// style: +// TextStyle( +// fontSize: +// 14, +// color: ColorConstants +// .kWhite, +// ), +// ), +// ], +// ) +// ], +// ), +// Container( +// decoration: +// BoxDecoration( +// border: +// Border.all( +// color: ColorConstants +// .kPrimaryColor, +// width: 2, +// ), +// shape: BoxShape +// .circle, +// ), +// child: +// GestureDetector( +// // redirect to Zoom for live session +// onTap: () { +// _launchInBrowser( +// 'https://us02web.zoom.us/rec/share/Pcc6SAUO9DEjt2Cm25ZtN57ODUJNBobl4CYabomLyJl4wqseoq11hT5r454gIvZy.9xwrGs9_Un8vRIR4'); +// // _launchURL(e.pastData![index].url); +// }, +// child: +// const Padding( +// padding: +// EdgeInsets +// .all( +// 3.0), +// child: Icon( +// Icons +// .play_arrow_rounded, +// color: ColorConstants +// .kPrimaryColor, +// size: 35, +// ), +// ), +// ), +// ), +// ], +// ), +// ); +// }, +// ), +// ), +// isExpanded: expandTile, +// ), +// ], +// ); +// }, +// ), +// ), +// ); diff --git a/gsf/lib/views/pages/test/scroll_test.dart b/gsf/lib/views/pages/test/scroll_test.dart new file mode 100644 index 0000000..6b91c95 --- /dev/null +++ b/gsf/lib/views/pages/test/scroll_test.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +class MyHomePagetest extends StatefulWidget { + const MyHomePagetest({Key? key}) : super(key: key); + + @override + _MyHomePagetestState createState() => _MyHomePagetestState(); +} + +class _MyHomePagetestState extends State { + ScrollController listScrollController = ScrollController(); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + + // Floating action button implemented with the + // auto scroll function to the bottom of list + floatingActionButton: FloatingActionButton( + onPressed: () { + if (listScrollController.hasClients) { + final position = listScrollController.position.maxScrollExtent; + listScrollController.animateTo( + position, + duration: const Duration(seconds: 3), + curve: Curves.easeOut, + ); + } + }, + isExtended: true, + tooltip: "Scroll to Bottom", + child: const Icon(Icons.arrow_downward), + ), + + // ListView with 100 list items + body: ListView.builder( + // Scroll Controller for functionality + controller: listScrollController, + itemCount: 100, + itemBuilder: (context, index) { + return ListTile( + title: Text("Item ${index + 1}"), + ); + }, + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/sliver_appbar.dart b/gsf/lib/views/pages/test/sliver_appbar.dart new file mode 100644 index 0000000..e5b976a --- /dev/null +++ b/gsf/lib/views/pages/test/sliver_appbar.dart @@ -0,0 +1,211 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../theme.dart'; + +class PodcastListTest extends StatelessWidget { + const PodcastListTest({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: ColorConstants.kBlack, + body: NestedScrollView( + headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { + return [ + SliverOverlapAbsorber( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + sliver: SliverAppBar( + backgroundColor: ColorConstants.kBlack, + titleSpacing: 0, + leadingWidth: 70, + stretch: true, + leading: Padding( + padding: const EdgeInsets.only( + top: 10, left: 18, right: 15, bottom: 10), + child: InkWell( + splashColor: const Color(0xff313030).withOpacity(0.5), + borderRadius: BorderRadius.circular(7), + onTap: () => Get.back(), + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: const Color(0xff313030), + borderRadius: BorderRadius.circular(7), + ), + child: const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Icon( + Icons.arrow_back_ios, + color: ColorConstants.kWhite, + size: 20, + ), + ), + ), + ), + ), + stretchTriggerOffset: 80, + automaticallyImplyLeading: false, + flexibleSpace: FlexibleSpaceBar( + titlePadding: const EdgeInsets.all(0.0), + // collapseMode: CollapseMode.pin, + // expandedTitleScale: 1, + background: Image.asset( + 'assets/image/podcast/podcastImg.jpg', + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + + title: innerBoxIsScrolled + ? SizedBox( + width: Get.size.width, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: 30), + Row( + // crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Text( + // 'Our Daily Latest Podcast', + // style: TextStyle( + // fontSize: 20, + // color: ColorConstants.kWhite, + // fontFamily: 'SFPRO', + // ), + // ), + Spacer(), + Text( + 'Set To Inspire', + style: TextStyle( + fontSize: 25, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + Spacer(), + Container( + width: 32, + height: 32, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor + .withOpacity(0.9), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.play_arrow_rounded, + color: ColorConstants.kBlack, + size: 30, + ), + ), + ], + ), + ], + ), + ) + : SizedBox( + width: Get.size.width, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Set To Inspire', + style: TextStyle( + fontSize: 25, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + fontWeight: FontWeight.w600, + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Our Daily Latest Podcast', + style: TextStyle( + fontSize: 20, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + ), + ), + Container( + width: 32, + height: 32, + decoration: BoxDecoration( + color: ColorConstants.kPrimaryColor + .withOpacity(0.9), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.play_arrow_rounded, + color: ColorConstants.kBlack, + size: 30, + ), + ), + ], + ), + ], + ), + ), + ), + pinned: true, + expandedHeight: 295, + ), + ) + ]; + }, + body: Builder(builder: (BuildContext context) { + return CustomScrollView( + slivers: [ + SliverOverlapInjector( + // This is the flip side of the SliverOverlapAbsorber above. + handle: + NestedScrollView.sliverOverlapAbsorberHandleFor(context), + ), + SliverToBoxAdapter( + child: Container( + height: 90, + color: Colors.black, + ), + ), + SliverToBoxAdapter( + child: Container( + height: 200, + color: Colors.red, + ), + ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 200, + color: Colors.green, + ), + ), + ), + SliverToBoxAdapter( + child: Container( + height: 200, + color: Colors.blue, + ), + ), + SliverToBoxAdapter( + child: Container( + height: 200, + color: Colors.red, + ), + ), + ], + ); + }), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/story_viewr.dart b/gsf/lib/views/pages/test/story_viewr.dart new file mode 100644 index 0000000..9d0ff8b --- /dev/null +++ b/gsf/lib/views/pages/test/story_viewr.dart @@ -0,0 +1,185 @@ +import 'package:flutter/material.dart'; +import 'package:story_view/story_view.dart'; + +class StoryViewr extends StatelessWidget { + final StoryController controller = StoryController(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Delicious Ghanaian Meals"), + ), + body: Container( + margin: EdgeInsets.all( + 8, + ), + child: ListView( + children: [ + Container( + height: 300, + child: StoryView( + controller: controller, + storyItems: [ + StoryItem.text( + title: + "Hello world!\nHave a look at some great Ghanaian delicacies. I'm sorry if your mouth waters. \n\nTap!", + backgroundColor: Colors.orange, + roundedTop: true, + ), + // StoryItem.inlineImage( + // NetworkImage( + // "https://image.ibb.co/gCZFbx/Banku-and-tilapia.jpg"), + // caption: Text( + // "Banku & Tilapia. The food to keep you charged whole day.\n#1 Local food.", + // style: TextStyle( + // color: Colors.white, + // backgroundColor: Colors.black54, + // fontSize: 17, + // ), + // ), + // ), + StoryItem.inlineImage( + url: + "https://image.ibb.co/cU4WGx/Omotuo-Groundnut-Soup-braperucci-com-1.jpg", + controller: controller, + caption: Text( + "Omotuo & Nkatekwan; You will love this meal if taken as supper.", + style: TextStyle( + color: Colors.white, + backgroundColor: Colors.black54, + fontSize: 17, + ), + ), + ), + StoryItem.inlineImage( + url: + "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif", + controller: controller, + caption: Text( + "Hektas, sektas and skatad", + style: TextStyle( + color: Colors.white, + backgroundColor: Colors.black54, + fontSize: 17, + ), + ), + ) + ], + onStoryShow: (s) { + print("Showing a story"); + }, + onComplete: () { + print("Completed a cycle"); + }, + progressPosition: ProgressPosition.bottom, + repeat: false, + inline: true, + ), + ), + Material( + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => MoreStories())); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: + BorderRadius.vertical(bottom: Radius.circular(8))), + padding: EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.arrow_forward, + color: Colors.white, + ), + SizedBox( + width: 16, + ), + Text( + "View more stories", + style: TextStyle(fontSize: 16, color: Colors.white), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ); + } +} + +class MoreStories extends StatefulWidget { + @override + _MoreStoriesState createState() => _MoreStoriesState(); +} + +class _MoreStoriesState extends State { + final storyController = StoryController(); + + @override + void dispose() { + storyController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("More"), + ), + body: StoryView( + storyItems: [ + StoryItem.text( + title: "I guess you'd love to see more of our food. That's great.", + backgroundColor: Colors.blue, + ), + StoryItem.text( + title: "Nice!\n\nTap to continue.", + backgroundColor: Colors.red, + textStyle: TextStyle( + fontFamily: 'Dancing', + fontSize: 40, + ), + ), + StoryItem.pageImage( + url: + "https://image.ibb.co/cU4WGx/Omotuo-Groundnut-Soup-braperucci-com-1.jpg", + caption: "Still sampling", + controller: storyController, + ), + StoryItem.pageImage( + url: "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif", + caption: "Working with gifs", + controller: storyController), + StoryItem.pageImage( + url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif", + caption: "Hello, from the other side", + controller: storyController, + ), + StoryItem.pageImage( + url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif", + caption: "Hello, from the other side2", + controller: storyController, + ), + ], + onStoryShow: (s) { + print("Showing a story"); + }, + onComplete: () { + print("Completed a cycle"); + }, + progressPosition: ProgressPosition.top, + repeat: false, + controller: storyController, + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/test.dart b/gsf/lib/views/pages/test/test.dart new file mode 100644 index 0000000..7c0f1e1 --- /dev/null +++ b/gsf/lib/views/pages/test/test.dart @@ -0,0 +1,556 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; + +import 'bottom_nav.dart'; +import 'bottomnvigation_controller.dart'; +import 'detailscreen.dart'; + +class MyApps extends StatelessWidget { + const MyApps({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter ShowCase', + theme: ThemeData( + primaryColor: const Color(0xffEE5366), + ), + debugShowCheckedModeBanner: false, + home: Scaffold(body: const MailPage() + + // ShowCaseWidget( + // onStart: (index, key) { + // log('onStart: $index, $key'); + // }, + // onComplete: (index, key) { + // log('onComplete: $index, $key'); + // if (index == 4) { + // SystemChrome.setSystemUIOverlayStyle( + // SystemUiOverlayStyle.light.copyWith( + // statusBarIconBrightness: Brightness.dark, + // statusBarColor: Colors.white, + // ), + // ); + // } + // }, + // blurValue: 1, + // builder: Builder(builder: (context) => const MailPage()), + // autoPlayDelay: const Duration(seconds: 3), + // ), + ), + ); + } +} + +class MailPage extends StatefulWidget { + const MailPage({Key? key}) : super(key: key); + + @override + _MailPageState createState() => _MailPageState(); +} + +class _MailPageState extends State { + final NavigationCrontrollers navControllerTest = + Get.put(NavigationCrontrollers()); + // final GlobalKey _one = GlobalKey(); + // final GlobalKey _two = GlobalKey(); + // final GlobalKey _three = GlobalKey(); + // final GlobalKey _four = GlobalKey(); + // final GlobalKey _five = GlobalKey(); + List mails = []; + + final scrollController = ScrollController(); + + @override + void initState() { + super.initState(); + //Start showcase view after current widget frames are drawn. + //NOTE: remove ambiguate function if you are using + //flutter version greater than 3.x and direct use WidgetsBinding.instance + // WidgetsBinding.instance.addPostFrameCallback( + // (_) => ShowCaseWidget.of(context).startShowCase([ + // navControllerTest.a, + // navControllerTest.b, + // navControllerTest.c, + // navControllerTest.d, + // navControllerTest.e, + // navControllerTest.f, + // navControllerTest.g, + // navControllerTest.h, + // navControllerTest.i, + // navControllerTest.j, + // ]), + // ); + + mails = [ + Mail( + sender: 'Medium', + sub: 'Showcase View', + msg: 'Check new showcase View', + date: '1 May', + isUnread: false, + ), + Mail( + sender: 'Quora', + sub: 'New Question for you', + msg: 'Hi, There is new question for you', + date: '2 May', + isUnread: true, + ), + Mail( + sender: 'Google', + sub: 'Flutter 1.5', + msg: 'We have launched Flutter 1.5', + date: '3 May', + isUnread: false, + ), + Mail( + sender: 'Github', + sub: 'Showcase View', + msg: 'New star on your showcase view.', + date: '4 May ', + isUnread: true, + ), + Mail( + sender: 'Simform', + sub: 'Credit card Plugin', + msg: 'Check out our credit card plugin', + date: '5 May', + isUnread: false, + ), + Mail( + sender: 'Flutter', + sub: 'Flutter is Future', + msg: 'Flutter launched for Web', + date: '6 May', + isUnread: true, + ), + Mail( + sender: 'Medium', + sub: 'Showcase View', + msg: 'Check new showcase View', + date: '7 May ', + isUnread: false, + ), + Mail( + sender: 'Simform', + sub: 'Credit card Plugin', + msg: 'Check out our credit card plugin', + date: '8 May', + isUnread: true, + ), + Mail( + sender: 'Flutter', + sub: 'Flutter is Future', + msg: 'Flutter launched for Web', + date: '9 May', + isUnread: false, + ), + ]; + } + + @override + void dispose() { + scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + bottom: false, + child: Column( + children: [ + const SizedBox( + height: 20, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Container( + padding: const EdgeInsets.only(left: 10, right: 8), + child: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: const Color(0xffF9F9F9), + border: Border.all( + color: const Color(0xffF3F3F3), + width: 2, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + GestureDetector( + onTap: () => print('menu button clicked'), + child: Icon( + Icons.menu, + color: Theme.of(context).primaryColor, + ), + ), + // Showcase( + // key: navControllerTest.a, + // description: 'Tap to see menu options', + // disableDefaultTargetGestures: true, + // child: + // ), + const SizedBox( + width: 10, + ), + const Text( + 'Search email', + style: TextStyle( + color: Colors.black45, + fontSize: 16, + letterSpacing: 0.4, + ), + ), + const Spacer(), + const Icon( + Icons.search, + color: Color(0xffADADAD), + ), + ], + ), + ), + ], + ), + ), + ), + ), + // Showcase( + // targetPadding: const EdgeInsets.all(5), + // key: navControllerTest.b, + // title: 'Profile', + // description: + // "Tap to see profile which contains user's name, profile picture, mobile number and country", + // tooltipBackgroundColor: Theme.of(context).primaryColor, + // textColor: Colors.white, + // targetShapeBorder: const CircleBorder(), + // child: + + // ), + Container( + padding: const EdgeInsets.all(5), + width: 45, + height: 45, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).primaryColor, + ), + child: Image.asset('assets/image/1.png'), + ), + const SizedBox( + width: 12, + ) + ], + ), + const SizedBox( + height: 10, + ), + Container( + padding: const EdgeInsets.only(left: 16, top: 4), + child: const Text( + 'PRIMARY', + style: TextStyle( + color: Colors.black, + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const Padding(padding: EdgeInsets.only(top: 8)), + Expanded( + child: ListView.builder( + controller: scrollController, + physics: const BouncingScrollPhysics(), + itemBuilder: (context, index) { + if (index == 0) { + return showcaseMailTile( + navControllerTest.c, true, context, mails.first); + } + return MailTile( + mail: mails[index % mails.length], + ); + }, + ), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + backgroundColor: Theme.of(context).primaryColor, + onPressed: () { + setState(() { + /* reset ListView to ensure that the showcased widgets are + * currently rendered so the showcased keys are available in the + * render tree. */ + scrollController.jumpTo(0); + // ShowCaseWidget.of(context).startShowCase([ + // navControllerTest.a, + // navControllerTest.b, + // navControllerTest.c, + // navControllerTest.d, + // navControllerTest.e + // ]); + }); + }, + child: const Icon( + Icons.add, + ), + ), + + // Showcase( + // key: navControllerTest.e, + // title: 'Compose Mail', + // description: 'Click here to compose mail', + // targetShapeBorder: const CircleBorder(), + // child: + + // ), + bottomNavigationBar: BottomNavigations(), + ); + } + + GestureDetector showcaseMailTile(GlobalKey> key, + bool showCaseDetail, BuildContext context, Mail mail) { + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => const Detail(), + ), + ); + }, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 8), + child: MailTile( + mail: mail, + showCaseKey: navControllerTest.d, + showCaseDetail: showCaseDetail, + ) + + // Showcase( + // key: key, + // description: 'Tap to check mail', + // disposeOnTap: true, + // onTargetClick: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (_) => const Detail(), + // ), + // ).then((_) { + // setState(() { + // ShowCaseWidget.of(context).startShowCase( + // [navControllerTest.d, navControllerTest.e]); + // }); + // }); + // }, + // child: + + // ), + ), + ); + } +} + +class SAvatarExampleChild extends StatelessWidget { + const SAvatarExampleChild({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(10), + child: Container( + width: 45, + height: 45, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Color(0xffFCD8DC), + ), + child: Center( + child: Text( + 'S', + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + ), + ), + ); + } +} + +class Mail { + Mail({ + required this.sender, + required this.sub, + required this.msg, + required this.date, + required this.isUnread, + }); + + String sender; + String sub; + String msg; + String date; + bool isUnread; +} + +class MailTile extends StatelessWidget { + const MailTile( + {required this.mail, + this.showCaseDetail = false, + this.showCaseKey, + Key? key}) + : super(key: key); + final bool showCaseDetail; + final GlobalKey>? showCaseKey; + final Mail mail; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.only(left: 6, right: 16, top: 8, bottom: 8), + color: mail.isUnread ? const Color(0xffFFF6F7) : Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (showCaseDetail) + // Showcase.withWidget( + // key: showCaseKey!, + // height: 50, + // width: 140, + // targetShapeBorder: const CircleBorder(), + // targetBorderRadius: const BorderRadius.all( + // Radius.circular(150), + // ), + // container: + + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Container( + // width: 45, + // height: 45, + // decoration: const BoxDecoration( + // shape: BoxShape.circle, + // color: Color(0xffFCD8DC), + // ), + // child: Center( + // child: Text( + // 'S', + // style: TextStyle( + // color: Theme.of(context).primaryColor, + // fontWeight: FontWeight.bold, + // fontSize: 16, + // ), + // ), + // ), + // ), + // const SizedBox( + // height: 10, + // ), + // const Text( + // "Your sender's profile ", + // style: TextStyle(color: Colors.white), + // ) + // ], + // ), + // child: const SAvatarExampleChild(), + // ) + // else + // const SAvatarExampleChild(), + const Padding(padding: EdgeInsets.only(left: 8)), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + mail.sender, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontWeight: mail.isUnread + ? FontWeight.bold + : FontWeight.normal, + fontSize: 17, + ), + ), + Text( + mail.sub, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 16, + ), + ), + Text( + mail.msg, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontWeight: FontWeight.normal, + color: mail.isUnread + ? Theme.of(context).primaryColor + : Colors.black, + fontSize: 15, + ), + ), + ], + ), + ) + ], + ), + ), + SizedBox( + width: 50, + child: Column( + children: [ + const SizedBox( + height: 5, + ), + Text( + mail.date, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 12, + color: Colors.grey, + ), + ), + const SizedBox( + height: 10, + ), + Icon( + mail.isUnread ? Icons.star : Icons.star_border, + color: mail.isUnread ? const Color(0xffFBC800) : Colors.grey, + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/test1.dart b/gsf/lib/views/pages/test/test1.dart new file mode 100644 index 0000000..aafb2cd --- /dev/null +++ b/gsf/lib/views/pages/test/test1.dart @@ -0,0 +1,155 @@ +import 'package:flutter/material.dart'; + +import 'colors_util.dart'; +import 'date_utils.dart' as date_util; + +class HorizonatalView extends StatefulWidget { + final String title; + const HorizonatalView({Key? key, required this.title}) : super(key: key); + + @override + _HorizonatalViewState createState() => _HorizonatalViewState(); +} + +class _HorizonatalViewState extends State { + double width = 0.0; + double height = 0.0; + late ScrollController scrollController; + List currentMonthList = List.empty(); + DateTime currentDateTime = DateTime.now(); + + @override + void initState() { + currentMonthList = date_util.DateUtils.daysInMonth(currentDateTime); + currentMonthList.sort((a, b) => a.day.compareTo(b.day)); + currentMonthList = currentMonthList.toSet().toList(); + scrollController = + ScrollController(initialScrollOffset: 37.0 * currentDateTime.day); + super.initState(); + } + + Widget titleView() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 20), + child: Text( + date_util.DateUtils.months[currentDateTime.month - 1] + + ' ' + + currentDateTime.year.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ); + } + + Widget hrizontalCapsuleListView() { + return SizedBox( + width: width, + height: 70, + child: ListView.builder( + controller: scrollController, + scrollDirection: Axis.horizontal, + physics: const ClampingScrollPhysics(), + shrinkWrap: true, + itemCount: currentMonthList.length, + itemBuilder: (BuildContext context, int index) { + return capsuleView(index); + }, + ), + ); + } + + Widget capsuleView(int index) { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), + child: GestureDetector( + onTap: () { + setState(() { + currentDateTime = currentMonthList[index]; + }); + }, + child: Container( + width: 45, + height: 67, + decoration: BoxDecoration( + color: (currentMonthList[index].day != currentDateTime.day) + ? Colors.red + : Colors.yellow, + borderRadius: BorderRadius.circular(40), + boxShadow: [ + BoxShadow( + offset: Offset(4, 4), + blurRadius: 4, + spreadRadius: 2, + color: Colors.black12, + ) + ]), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + currentMonthList[index].day.toString(), + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + height: 1, + color: + (currentMonthList[index].day != currentDateTime.day) + ? HexColor("465876") + : Colors.white, + ), + ), + Text( + date_util.DateUtils + .weekdays[currentMonthList[index].weekday - 1], + style: TextStyle( + fontSize: + (currentMonthList[index].day != currentDateTime.day) + ? 12 + : 14, + fontWeight: FontWeight.bold, + color: + (currentMonthList[index].day != currentDateTime.day) + ? HexColor("465876") + : Colors.white, + ), + ) + ], + ), + ), + ), + )); + } + + Widget topView() { + return SizedBox( + // height: height * 0.35, + width: width, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + titleView(), + hrizontalCapsuleListView(), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + width = MediaQuery.of(context).size.width; + height = MediaQuery.of(context).size.height; + return Scaffold( + backgroundColor: Colors.black, + body: Padding( + padding: const EdgeInsets.only(top: 180.0), + child: Stack( + children: [topView()], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/test_page.dart b/gsf/lib/views/pages/test/test_page.dart new file mode 100644 index 0000000..130aa71 --- /dev/null +++ b/gsf/lib/views/pages/test/test_page.dart @@ -0,0 +1,12 @@ +// import 'package:flutter/material.dart'; + +// class TestPage extends StatelessWidget { +// const TestPage({super.key}); + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// body: Center(child: Text("Shikha")), +// ); +// } +// } \ No newline at end of file diff --git a/gsf/lib/views/pages/test/time_zone.dart b/gsf/lib/views/pages/test/time_zone.dart new file mode 100644 index 0000000..faf3615 --- /dev/null +++ b/gsf/lib/views/pages/test/time_zone.dart @@ -0,0 +1,463 @@ +// // ignore_for_file: deprecated_member_use + +// import 'dart:convert'; + +// import 'package:flutter/material.dart'; +// import 'package:flutter_custom_tabs/flutter_custom_tabs.dart'; +// import 'package:flutter_svg/svg.dart'; +// import 'package:get/get.dart'; +// import 'package:gsp_app/view_model/utc_time_contoller.dart'; +// import 'package:intl/intl.dart'; +// // import 'package:url_launcher/url_launcher.dart'; + +// import '../../../modals/live_session_model.dart'; +// import '../../../view_model/global_controller.dart'; +// import '../../components/appbar.dart'; +// import '../../components/btn.dart'; +// import '../../theme.dart'; + +// class SessionsDetails extends StatefulWidget { +// final LiveActivityModel data; +// const SessionsDetails({required this.data, Key? key}) : super(key: key); + +// @override +// State createState() => _SessionsDetailsState(); +// } + +// class _SessionsDetailsState extends State { +// @override +// Widget build(BuildContext context) { +// // convertTimeInUtcWithouAmAndPm + +// var timeInUtc = convertUtcToLocalTime(widget.data.time); +// var spliUtcTime = timeInUtc.split(' '); +// var startTimeSessoin = spliUtcTime[0].split(':'); + +// var now = DateTime.now(); + +// var currentTimeFormatted = DateFormat('hh:mm a').format(now); + +// void mains() { +// var timeCurrentTime = currentTimeFormatted; +// var timeUtcBackendTime = timeInUtc; +// var durationTime = "${widget.data.dayDuration} minutes"; + +// // Define a date format for parsing times +// var timeFormat = DateFormat('hh:mm a'); + +// try { +// // Parse the time strings +// var currentTime = timeFormat.parse(timeCurrentTime); +// var backendTime = timeFormat.parse(timeUtcBackendTime); + +// // Parse the duration string +// var durationMatch = RegExp(r'(\d+) (\w+)').firstMatch(durationTime); +// var durationValue = int.parse(durationMatch!.group(1)!); +// var durationUnit = durationMatch.group(2)!; + +// // Calculate the new time after adding the duration +// var newTime = durationUnit == 'minutes' +// ? currentTime.add(Duration(minutes: durationValue)) +// : currentTime.add(Duration(hours: durationValue)); +// print('durationMatch ${newTime}'); + +// // Compare the times and display the appropriate message +// if (currentTime.isBefore(backendTime)) { +// print("Wait"); +// } else if (newTime.isAtSameMomentAs(backendTime)) { +// print("Join Now"); +// } else { +// print("Expire"); +// } +// } catch (e) { +// print("Invalid date format: $e"); +// } +// } + +// setState(() { +// mains(); +// }); + +// // print('Session Time current time ${currentTimeFormatted}'); +// // print('Session Time utc backend time ${timeInUtc}'); + +// // final tames = TimeOfDay( +// // hour: int.parse(startTimeSessoin[0]), +// // minute: int.parse(startTimeSessoin[1]), +// // ); +// // print('DATA OF INNER OF LIVE Sessions ${timeInUtc}'); + +// // var newFormateDate = DateFormat.Hm().format(DateTime.now().toLocal()); +// // var newTames= newFormateDate.split(":"); +// // print('newFormateDate ${newTames[0]}'); + +// // int newHour = int.parse(newTames[0]); +// // int newMinute = int.parse(newTames[1]); + +// // final currentTime = TimeOfDay.now(); +// final currentTime = TimeOfDay.now(); + +// // print('current time $currentTime'); + +// // print( +// // 'timeDifference hour multiplied with 60 ${currentTime.hour} minutes ${currentTime.minute} backend time ${widget.data.time} converted time ${timeInUtc}'); + +// // final timeDifference = currentTime.hour * 60 + +// // currentTime.minute - +// // (tames.hour * 60 + tames.minute); + +// String btnJoining = ''; + +// bool trueAndFalse = false; + +// // checkTimeSession() { +// // // print('check sessions'); +// // if (timeDifference <= widget.data.dayDuration) { +// // btnJoining = 'Please wait to join'; +// // trueAndFalse = false; +// // } + +// // if (timeDifference >= 0) { +// // btnJoining = 'Join Now'; +// // trueAndFalse = true; +// // } + +// // // if (timeDifference >= widget.data.dayDuration) { +// // // btnJoining = 'Session has been ended'; +// // // trueAndFalse = false; +// // // } +// // } +// // setState(() { +// // checkTimeSession(); +// // }); + +// // print( +// // 'timeDifference ${timeDifference} ${btnJoining} vwyecdghwed ${(timeDifference >= 0 && timeDifference <= data.dayDuration)}'); + +// GlobalController globalContoller = Get.put(GlobalController()); +// List benifitActivity = +// jsonDecode(widget.data.activityData[0].benefits.toString()); +// List preRequisit = +// jsonDecode(widget.data.activityData[0].preRequisites.toString()); +// // print('zoom link ${data.zoomLink}'); + +// _launchZoomMeeting(BuildContext context, String zoomLink) async { +// try { +// await launch( +// zoomLink, +// customTabsOption: CustomTabsOption( +// toolbarColor: Theme.of(context).primaryColor, +// enableDefaultShare: true, +// enableUrlBarHiding: true, +// showPageTitle: true, +// ), +// ); +// } catch (e) { +// print('Error launching Zoom: $e'); +// // Handle the error, e.g., show an error message to the user. +// } +// } + +// // void launchZoom(url) async { +// // print('ZOOM URL $url'); +// // final String zoomAppUrl = url; + +// // if (await canLaunch(zoomAppUrl)) { +// // await launch(zoomAppUrl); +// // } else { +// // showDialog( +// // context: context, +// // builder: (BuildContext context) => AlertDialog( +// // title: const Text('Zoom App Not Found'), +// // content: const Text( +// // 'To join this Zoom meeting, please install the Zoom app.'), +// // actions: [ +// // TextButton( +// // onPressed: () async { +// // const String zoomPlayStoreUrl = +// // 'https://play.google.com/store/apps/details?id=us.zoom.videomeetings'; +// // if (await canLaunch(zoomPlayStoreUrl)) { +// // await launch(zoomPlayStoreUrl); +// // } else { +// // throw 'Could not launch $zoomPlayStoreUrl'; +// // } +// // }, +// // child: const Text('Download'), +// // ), +// // TextButton( +// // onPressed: () => Navigator.pop(context), +// // child: const Text('Cancel'), +// // ), +// // ], +// // ), +// // ); +// // } +// // } + +// // Future joinZoomMeeting() async { +// // if (await launchUrl(Uri.parse(meetingUrl))) { +// // await launchUrl(Uri.parse(meetingUrl)); +// // } else { +// // throw 'Could not launch $meetingUrl'; +// // } +// // } +// // print('check time session ${(timeDifference >= 0 && timeDifference <= widget.data.dayDuration)}'); + +// return Scaffold( +// appBar: PreferredSize( +// preferredSize: const Size.fromHeight(60), +// child: CustomAppBars(titleHead: 'Live Session'), +// ), +// body: SingleChildScrollView( +// physics: const BouncingScrollPhysics(), +// child: Column( +// children: [ +// Container( +// width: Get.size.width * 1, +// height: 400, +// decoration: BoxDecoration( +// image: DecorationImage( +// image: NetworkImage(widget.data.activityDayBanner), +// alignment: Alignment.topCenter, +// fit: BoxFit.cover, +// ), +// ), +// child: Column( +// mainAxisAlignment: MainAxisAlignment.end, +// children: [ +// GestureDetector( +// onTap: () { +// // joinZoomMeeting(); +// }, +// child: Container( +// width: 60, +// height: 60, +// decoration: BoxDecoration( +// color: ColorConstants.kPrimaryColor.withOpacity(0.5), +// shape: BoxShape.circle, +// ), +// child: const Padding( +// padding: EdgeInsets.all(8.0), +// child: Icon( +// Icons.play_arrow, +// color: ColorConstants.kBlack, +// size: 35, +// ), +// ), +// ), +// ), +// const SizedBox(height: 20), +// Text( +// widget.data.activityName, +// style: const TextStyle( +// fontSize: 26, +// color: ColorConstants.kWhite, +// fontFamily: 'SFPRO', +// letterSpacing: 0.6, +// fontWeight: FontWeight.bold, +// ), +// ), +// const SizedBox(height: 12), +// SvgPicture.asset('assets/image/live-streaming.svg'), +// const SizedBox(height: 12), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 50), +// child: Container( +// decoration: BoxDecoration( +// border: Border.all( +// width: 1, +// color: ColorConstants.kWhite, +// ), +// borderRadius: BorderRadius.circular(10), +// ), +// child: Row( +// children: [ +// Expanded( +// flex: 2, +// child: Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Text( +// '${widget.data.dayDuration.toString()} min', +// // '', +// style: const TextStyle( +// fontSize: 20, +// color: Color(0xffffffff), +// // fontWeight: FontWeight.w500, +// ), +// ), +// const Text( +// 'Activity Duration', +// style: TextStyle( +// fontSize: 14, +// color: Color(0xffffffff), +// fontWeight: FontWeight.w300, +// ), +// ), +// ], +// ), +// ), +// Expanded( +// flex: 0, +// child: Container( +// width: 1, +// height: 50, +// color: const Color(0xffffffff), +// ), +// ), +// Expanded( +// flex: 2, +// child: Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Text( +// widget.data.subscription.planName +// .split(' ')[0], +// style: const TextStyle( +// fontSize: 20, +// color: Color(0xffffffff), +// ), +// ), +// const Text( +// 'Activity Level', +// style: TextStyle( +// fontSize: 14, +// color: Color(0xffffffff), +// fontWeight: FontWeight.w300, +// // height: 1, +// ), +// ), +// ], +// ), +// ), +// ], +// ), +// ), +// ), +// const SizedBox(height: 30), +// ], +// ), +// ), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 20), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// 'About the session', +// style: TextStyle( +// fontSize: 18, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// ), +// ), +// const SizedBox(height: 10), +// Text( +// widget.data.description.toString(), +// style: TextStyle( +// fontSize: 16, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// ), +// ), +// const SizedBox(height: 30), +// Text( +// 'How will this activity help', +// style: TextStyle( +// fontSize: 18, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack.withOpacity(0.7) +// : ColorConstants.kWhite, +// ), +// ), +// const SizedBox(height: 10), +// Wrap(children: [ +// for (var item in benifitActivity) +// Padding( +// padding: const EdgeInsets.only(right: 12.0, top: 10), +// child: Container( +// decoration: BoxDecoration( +// border: Border.all( +// color: ColorConstants.kPrimaryColor, +// width: 1, +// ), +// borderRadius: BorderRadius.circular(25), +// ), +// child: Padding( +// padding: const EdgeInsets.symmetric( +// horizontal: 15, vertical: 10), +// child: Text( +// item, +// style: TextStyle( +// fontSize: 14, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// ), +// ), +// ), +// ), +// ) +// ]), +// const SizedBox(height: 20), +// Text( +// 'How can you prepare yourself for the session', +// style: TextStyle( +// fontSize: 18, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// ), +// ), +// const SizedBox(height: 15), +// Wrap(children: [ +// for (var item in preRequisit) +// Padding( +// padding: const EdgeInsets.only(right: 12.0, top: 10), +// child: Container( +// decoration: BoxDecoration( +// border: Border.all( +// color: ColorConstants.kPrimaryColor, +// width: 1, +// ), +// borderRadius: BorderRadius.circular(25), +// ), +// child: Padding( +// padding: const EdgeInsets.symmetric( +// horizontal: 15, vertical: 10), +// child: Text( +// item, +// style: TextStyle( +// fontSize: 14, +// color: !globalContoller.darkMode.value +// ? ColorConstants.kBlack +// : ColorConstants.kWhite, +// ), +// ), +// ), +// ), +// ) +// ]), +// ], +// ), +// ), +// const SizedBox(height: 80), +// ], +// ), +// ), +// floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, +// floatingActionButton: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), +// child: FullWdtBtn( +// // disabled: (timeDifference >= 0 && timeDifference <= widget.data.dayDuration) ? false : true, +// btnText: 'Join Now', +// onTap: () => _launchZoomMeeting(context, widget.data.zoomLink), +// ), +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/upcoming_data_utc.dart b/gsf/lib/views/pages/test/upcoming_data_utc.dart new file mode 100644 index 0000000..027a164 --- /dev/null +++ b/gsf/lib/views/pages/test/upcoming_data_utc.dart @@ -0,0 +1,260 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; +import 'package:skeletons/skeletons.dart'; + +import '../../../modals/upcoming_session_model.dart'; +import '../../../repository/response_data.dart'; +import '../../../repository/services/cj/upcoming_activity_service.dart'; +import '../../../view_model/global_controller.dart'; +import '../../../view_model/utc_time_contoller.dart'; +import '../../components/btn.dart'; +import '../../components/page_animation.dart'; +import '../../theme.dart'; +import '../Sessions/count_me.dart'; + +class TestTimeInUpcoming extends StatefulWidget { + const TestTimeInUpcoming({super.key}); + + @override + State createState() => _TestTimeInUpcomingState(); +} + +class _TestTimeInUpcomingState extends State { + GlobalController globalContoller = Get.put(GlobalController()); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Test Time'), + ), + body: Column( + children: [ + Expanded( + child: upcomingSession(), + ) + ], + ), + ); + } + + upcomingSession() { + return FutureBuilder( + future: UpcomingActivityServices().getUpcomingActivitydataUtc(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + // print('snapshot data in upcomimg ${snapshot.data!.data}'); + List data = snapshot.data!.data; + // print( + // 'All data drive ${data[0].subscription.planName.split(' ')[0]}'); + String formatDate(String dateStr) { + DateTime date = DateTime.parse(dateStr).toLocal(); + String formattedDate = DateFormat('d MMMM y').format(date); + return formattedDate; + } + + // print('data[index].activityName ${data[0].activityData.first.techerData.teacherName}'); + + return (data.isNotEmpty) + ? Column( + children: [ + const SizedBox(height: 20), + Expanded( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: data.length, + itemBuilder: (context, index) { + + // final dateTime = + // data[index].date.toString().split(' ')[0]; + // DateTime dates = DateTime.parse(dateTime); + // String formattedDate = + // DateFormat('dd MMMM yyyy').format(dates); + var dateTimeStand = + '${data[index].subscription.planName.split(' ')[0]}: ${data[index].dayDuration} mins - ${convertUtcToLocalTime(data[index].time)}'; + print('dateTimeStand $dateTimeStand'); + return Padding( + padding: const EdgeInsets.only(bottom: 20), + child: OpenContainerWrappers( + closeBuild: Container( + height: 280, + width: Get.size.width, + decoration: BoxDecoration( + image: DecorationImage( + image: NetworkImage( + data[index].activityDayBanner, + ), + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + ), + child: Column( + children: [ + const Spacer(), + // Container( + // decoration: BoxDecoration( + // color: ColorConstants.kPrimaryColor + // .withOpacity(0.5), + // shape: BoxShape.circle, + // ), + // child: GestureDetector( + // // redirect on count me screen + // // onTap: () => Get.to(() => const VimeoPlayer()), + // child: const Padding( + // padding: EdgeInsets.all(8.0), + // child: Icon( + // Icons.play_arrow, + // color: ColorConstants.kBlack, + // size: 35, + // ), + // ), + // ), + // ), + const SizedBox(height: 10), + Text( + data[index].activityName, + style: TextStyle( + fontSize: 26, + color: ColorConstants.kWhite, + fontFamily: 'SFPRO', + letterSpacing: 0.4, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + '$dateTimeStand', + // '${data[index].subscription.planName}: ${data[index].activityDuration} mins - ${data[index].time.toString()} ${(int.parse(data[index].time.toString().split(':')[0])) < 12 ? 'AM' : 'PM'} - Yoga', + // '', + style: TextStyle( + fontSize: 18, + color: Color(0xffD9D9D9), + ), + ), + const SizedBox(height: 8), + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + border: Border.all( + color: const Color(0xffF5F5F5), + width: 1, + ), + shape: BoxShape.circle, + ), + child: Padding( + padding: const EdgeInsets.all(2.0), + child: ClipRRect( + borderRadius: + BorderRadius.circular(50), + child: Image.asset( + 'assets/image/gsf_avatar.png', + fit: BoxFit.cover, + filterQuality: + FilterQuality.high, + ), + ), + ), + ), + const SizedBox(height: 8), + Text( + 'With ${data[index].activityData.first.techerData.teacherName}', + style: TextStyle( + fontSize: 13, + color: ColorConstants.kWhite, + fontFamily: 'SFPRo', + ), + ), + const SizedBox(height: 7), + Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(22), + border: Border.all( + color: ColorConstants.kWhite, + width: 1, + ), + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10, vertical: 4), + child: Text( + formatDate(data[index].date), + style: TextStyle( + fontSize: 14, + color: ColorConstants.kWhite, + ), + ), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 50), + child: FullWdtBtn( + btnText: 'Count me in', + onTap: () => Get.to( + () => CountMe( + activityTitle: + data[index].activityName, + date: data[index].date, + timer: data[index].time, + // sDate: , + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ), + openBuild: CountMe( + activityTitle: data[index].activityName, + timer: data[index].time, + date: data[index].date, + ), + ), + ); + })), + ], + ) + : Center( + child: Text( + 'No Session Found ☹️.', + style: TextStyle( + color: + // !globalContoller.darkMode.value + // ? Colors.black + // : + ColorConstants.kPrimaryColor, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ); + } + return Padding( + padding: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: ListView.builder( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: 4, + itemBuilder: (context, index) => Container( + margin: EdgeInsets.only(bottom: 20), + child: SkeletonAvatar( + style: SkeletonAvatarStyle( + padding: const EdgeInsets.symmetric(horizontal: 8), + width: Get.width * 0.88, + height: 200, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/gsf/lib/views/pages/test/video_player.dart b/gsf/lib/views/pages/test/video_player.dart new file mode 100644 index 0000000..5a8b1bb --- /dev/null +++ b/gsf/lib/views/pages/test/video_player.dart @@ -0,0 +1,123 @@ +// import 'package:chewie/chewie.dart'; +// import 'package:flutter/material.dart'; +// import 'package:gsp_app/theme.dart'; +// import 'package:video_player/video_player.dart'; + +// class VideoPlayerView extends StatefulWidget { +// const VideoPlayerView({Key? key}) : super(key: key); + +// @override +// State createState() => _VideoPlayerViewState(); +// } + +// class _VideoPlayerViewState extends State { +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: const Text( +// 'Video Player', +// style: TextStyle( +// fontSize: 20, +// color: ColorConstants.kWhite, +// fontFamily: 'SFRPO', +// ), +// ), +// ), +// body: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 22.0, vertical: 20), +// child: Column( +// children: const [ +// Text( +// 'Video viwer will goes at down side', +// style: TextStyle( +// fontSize: 22, +// color: ColorConstants.kBlack, +// fontFamily: 'SFPRO', +// fontWeight: FontWeight.w600, +// ), +// ), +// Expanded( +// child: VideoPlayer( +// dataSourceType: DataSourceType.asset, +// url: 'assets/video/video.mp4', +// ), +// ) +// ], +// ), +// ), +// ); +// } +// } + +// class VideoPlayer extends StatefulWidget { +// const VideoPlayer({Key? key, required this.dataSourceType, required this.url}) +// : super(key: key); +// final String url; +// final DataSourceType dataSourceType; + +// @override +// State createState() => _VideoPlayerState(); +// } + +// class _VideoPlayerState extends State { +// late VideoPlayerController _videoPlayerController; +// ChewieController? chewieController; + +// Future loadVideoPlayer() async { +// _videoPlayerController = +// VideoPlayerController.network('https://vimeo.com/253989945'); +// await Future.wait([ +// _videoPlayerController.initialize(), +// ]); +// chewieController = ChewieController( +// videoPlayerController: _videoPlayerController, +// autoPlay: false, +// looping: false, +// ); +// setState(() {}); +// } + +// @override +// void initState() { +// super.initState(); +// loadVideoPlayer(); +// } + +// @override +// void dispose() { +// super.dispose(); +// _videoPlayerController.dispose(); +// chewieController?.dispose(); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// body: Column( +// children: [ +// // AspectRatio( +// // aspectRatio: 16 / 9, +// // child: Chewie(controller: chewieController), +// // ), +// AspectRatio( +// aspectRatio: 16 / 9, +// child: (chewieController != null) && +// chewieController!.videoPlayerController.value.isInitialized +// ? Chewie(controller: chewieController!) +// : Column( +// mainAxisAlignment: MainAxisAlignment.center, +// children: const [ +// CircularProgressIndicator(), +// SizedBox( +// height: 20, +// ), +// Text('Loading'), +// ], +// ), +// ), +// ], +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/vimeo_video_player.dart b/gsf/lib/views/pages/test/vimeo_video_player.dart new file mode 100644 index 0000000..b54262b --- /dev/null +++ b/gsf/lib/views/pages/test/vimeo_video_player.dart @@ -0,0 +1,36 @@ +// import 'package:flutter/material.dart'; +// import 'package:pod_player_new/pod_player_new.dart'; + +// class VidemoVidePlayer extends StatefulWidget { +// const VidemoVidePlayer({Key? key}) : super(key: key); + +// @override +// State createState() => _VidemoVidePlayerState(); +// } + +// class _VidemoVidePlayerState extends State { +// @override +// @override +// Widget build(BuildContext context) { +// var podPlayerController = PodPlayerController( +// playVideoFrom: PlayVideoFrom.network( +// 'https://player.vimeo.com/progressive_redirect/playback/838250799/rendition/720p/file.mp4?loc=external&signature=274e145f6401b0b45a6a4bd513f6f4ffec467f1c879514525df0a02de501abba'), +// podPlayerConfig: const PodPlayerConfig( +// autoPlay: false, +// isLooping: false, +// ), +// )..initialise() +// // ..disableFullScreen(context) +// ; +// return Scaffold( +// appBar: AppBar(), +// body: PodVideoPlayer( +// controller: podPlayerController, +// matchFrameAspectRatioToVideo: true, +// matchVideoAspectRatioToFrame: true, +// alwaysShowProgressBar: true, +// backgroundColor: Colors.black, +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/live_session.dart b/gsf/lib/views/pages/test/zoom_integration.dart/live_session.dart new file mode 100644 index 0000000..0b81ed7 --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/live_session.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_custom_tabs/flutter_custom_tabs.dart'; +// import 'package:url_launcher/url_launcher.dart'; + +class LiveSessionTest extends StatefulWidget { + const LiveSessionTest({super.key}); + + @override + State createState() => _LiveSessionTestState(); +} + +class _LiveSessionTestState extends State { + // final zoomLink = Uri.encodeFull( + // 'https://us05web.zoom.us/j/83122647084?pwd=NT8kQaYNSJoJgLhLjbPeoLR67XkKIY.1'); + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Test Live Session on zoom'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + OutlinedButton( + // onPressed: () { + // // Replace the Zoom meeting link below with your own + // final zoomLink = 'https://us05web.zoom.us/j/83122647084?pwd=NT8kQaYNSJoJgLhLjbPeoLR67XkKIY.1'; + // _launchZoomMeeting(zoomLink); + // }, + + onPressed: () { + // Replace the Zoom meeting link below with your own + final zoomLink = 'https://us05web.zoom.us/j/85083052578?pwd=OV2pGuDoCHbE74tMYswHmrfJuQit1R.1'; + _launchZoomMeeting(context, zoomLink); + }, + child: const Text('Click to go Live on Zoom'), + ) + ], + ), + ), + ); + } + // _launchZoomMeeting(String zoomLink) async { + // try { + // if (await canLaunch(zoomLink)) { + // await launch(zoomLink); + // } else { + // print('Could not launch Zoom: Invalid URL'); + // // Handle the error, e.g., show an error message to the user. + // } + // } catch (e) { + // print('Error launching Zoom: $e'); + // // Handle the error, e.g., show an error message to the user. + // } + // } + + + _launchZoomMeeting(BuildContext context, String zoomLink) async { + try { + await launch( + zoomLink, + customTabsOption: CustomTabsOption( + toolbarColor: Theme.of(context).primaryColor, + enableDefaultShare: true, + enableUrlBarHiding: true, + showPageTitle: true, + ), + ); + } catch (e) { + print('Error launching Zoom: $e'); + // Handle the error, e.g., show an error message to the user. + } + } +} diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/main_video.dart b/gsf/lib/views/pages/test/zoom_integration.dart/main_video.dart new file mode 100644 index 0000000..7f16914 --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/main_video.dart @@ -0,0 +1,57 @@ +// import 'package:flutter/material.dart'; +// import 'package:get/get.dart'; +// import 'package:gsp_app/views/theme.dart'; + +// import 'zoom_recorded_video_podPlayer.dart'; + +// class MainVideoRecodrd extends StatefulWidget { +// const MainVideoRecodrd({Key? key}) : super(key: key); + +// @override +// State createState() => _MainVideoRecodrdState(); +// } + +// class _MainVideoRecodrdState extends State { +// final listRecorded = [ +// 'https://player.vimeo.com/progressive_redirect/playback/838250799/rendition/720p/file.mp4?loc=external&signature=274e145f6401b0b45a6a4bd513f6f4ffec467f1c879514525df0a02de501abba', +// 'https://player.vimeo.com/progressive_redirect/playback/802199625/rendition/720p/file.mp4?loc=external&signature=1216c2b99f8cf0046a9bce1798d78dbbe69a5ea8f341334f21a79bfe1c90cb49', +// 'https://player.vimeo.com/progressive_redirect/playback/802200978/rendition/1080p/file.mp4?loc=external&signature=2524b7c1a1f841fa3de701bdd5e0c8fea0676dae2e5621e27f08d5bd95a61922', +// 'https://player.vimeo.com/progressive_redirect/playback/802200207/rendition/720p/file.mp4?loc=external&signature=eaa047c0e223f373da159641d09a5b28e57aae211e6d283c918d8efeabfe2c1b' +// ]; +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar(), +// body: ListView.builder( +// itemCount: listRecorded.length, +// shrinkWrap: true, +// itemBuilder: (context, index) { +// return GestureDetector( +// onTap: () { +// // print(index); +// Get.to( +// () => ZoomPodVideoPlayerRecorded( +// urlLink: listRecorded[index], +// ), +// ); +// }, +// child: Container( +// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), +// decoration: BoxDecoration( +// border: Border.all(color: ColorConstants.kPrimaryColor), +// ), +// margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// // Text('data'), +// Text((index + 1).toString()), +// ], +// ), +// ), +// ); +// }, +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/past__recoded_zoom.dart b/gsf/lib/views/pages/test/zoom_integration.dart/past__recoded_zoom.dart new file mode 100644 index 0000000..c1dc33d --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/past__recoded_zoom.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class PastRecordedZoom extends StatefulWidget { + const PastRecordedZoom({super.key}); + + @override + State createState() => _PastRecordedZoomState(); +} + +class _PastRecordedZoomState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Past Recorded Zoom Vide'), + ), + body: Center( + child: Column( + children: [ + OutlinedButton( + onPressed: () {}, + child: const Text('Click to watch recorded video'), + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/zoom_recorded_video_podPlayer.dart b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_recorded_video_podPlayer.dart new file mode 100644 index 0000000..cd5fae6 --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_recorded_video_podPlayer.dart @@ -0,0 +1,39 @@ +// import 'package:flutter/material.dart'; +// import 'package:pod_player_new/pod_player_new.dart'; + +// class ZoomPodVideoPlayerRecorded extends StatefulWidget { +// final String urlLink; +// const ZoomPodVideoPlayerRecorded({Key? key, required this.urlLink}) +// : super(key: key); + +// @override +// State createState() => +// _ZoomPodVideoPlayerRecordedState(); +// } + +// class _ZoomPodVideoPlayerRecordedState +// extends State { +// @override +// Widget build(BuildContext context) { +// var podPlayerController = PodPlayerController( +// playVideoFrom: PlayVideoFrom.network(widget.urlLink), +// podPlayerConfig: const PodPlayerConfig( +// autoPlay: false, +// isLooping: false, +// ), +// ) +// ..initialise() +// ..disableFullScreen(context); +// return Scaffold( +// appBar: AppBar(), +// body: PodVideoPlayer( +// videoTitle: Text('data'), +// controller: podPlayerController, +// matchFrameAspectRatioToVideo: true, +// matchVideoAspectRatioToFrame: true, +// alwaysShowProgressBar: true, +// backgroundColor: Colors.black, +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/zoom_redirect.dart b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_redirect.dart new file mode 100644 index 0000000..ec0445d --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_redirect.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/foundation/key.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class ZoomRedirect extends StatefulWidget { + const ZoomRedirect({Key? key}) : super(key: key); + + @override + State createState() => ZoomRedirectState(); +} + +class ZoomRedirectState extends State { + // void joinZoomMeeting() async { + // String meetingUrl = + // "https://us05web.zoom.us/j/84932374918?pwd=VzhXTUZLTHB3VXNjSm5WNlEyOU5QUT09"; + + // // Replace MEETING_ID and MEETING_PASSWORD with the actual values + + // if (await canLaunch(meetingUrl)) { + // await launch(meetingUrl); + // } else { + // throw 'Could not launch $meetingUrl'; + // } + // } + void downloadZoomApp() async { + final String zoomPlayStoreLink = + 'https://play.google.com/store/apps/details?id=us.zoom.videomeetings'; + + if (await canLaunch(zoomPlayStoreLink)) { + await launch(zoomPlayStoreLink); + } else { + throw 'Could not launch $zoomPlayStoreLink'; + } + } + + Future _launchZoom(url) async { + if (await canLaunch(url)) { + await launch(url); + } else { + throw 'Could not launch $url'; + } + } + + void launchZoomApp(String zoomLiveLink) async { + final url = 'zoomus://$zoomLiveLink'; + final isZoomInstalled = await canLaunch(url); + + if (isZoomInstalled) { + await launch(url); + } else { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Zoom App Not Found'), + content: GestureDetector( + onTap: downloadZoomApp, + child: const Text( + 'To join this Zoom meeting, please install the Zoom app.'), + ), + actions: [ + TextButton( + onPressed: downloadZoomApp, + child: const Text('OK'), + ), + ], + ), + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Zoom Redirect'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + OutlinedButton( + onPressed: () { + launchZoomApp( + 'https://us05web.zoom.us/j/84305285845?pwd=cFNVS2Z6K2lsNHBLYzdZOG9sWVpHdz09'); + }, + child: const Icon(Icons.play_arrow_outlined), + ), + const Text('Redirect on Zoom Link'), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/zoom_integration.dart/zoom_video_recorded.dart b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_video_recorded.dart new file mode 100644 index 0000000..af7f87b --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_integration.dart/zoom_video_recorded.dart @@ -0,0 +1,36 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class VimoeRecordedVideoPlayer extends StatefulWidget { + final String url; + const VimoeRecordedVideoPlayer({Key? key, required this.url}) + : super(key: key); + + @override + _VimoeRecordedVideoPlayerState createState() => + _VimoeRecordedVideoPlayerState(); +} + +class _VimoeRecordedVideoPlayerState extends State { + // var webViewController = + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Zoom Vimeo Video Recorded'), + ), + body: WebViewWidget( + controller: WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(ColorConstants.kBlack) + ..loadRequest( + Uri.parse(widget.url), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/zoom_recorded_video/main_video.dart b/gsf/lib/views/pages/test/zoom_recorded_video/main_video.dart new file mode 100644 index 0000000..7f16914 --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_recorded_video/main_video.dart @@ -0,0 +1,57 @@ +// import 'package:flutter/material.dart'; +// import 'package:get/get.dart'; +// import 'package:gsp_app/views/theme.dart'; + +// import 'zoom_recorded_video_podPlayer.dart'; + +// class MainVideoRecodrd extends StatefulWidget { +// const MainVideoRecodrd({Key? key}) : super(key: key); + +// @override +// State createState() => _MainVideoRecodrdState(); +// } + +// class _MainVideoRecodrdState extends State { +// final listRecorded = [ +// 'https://player.vimeo.com/progressive_redirect/playback/838250799/rendition/720p/file.mp4?loc=external&signature=274e145f6401b0b45a6a4bd513f6f4ffec467f1c879514525df0a02de501abba', +// 'https://player.vimeo.com/progressive_redirect/playback/802199625/rendition/720p/file.mp4?loc=external&signature=1216c2b99f8cf0046a9bce1798d78dbbe69a5ea8f341334f21a79bfe1c90cb49', +// 'https://player.vimeo.com/progressive_redirect/playback/802200978/rendition/1080p/file.mp4?loc=external&signature=2524b7c1a1f841fa3de701bdd5e0c8fea0676dae2e5621e27f08d5bd95a61922', +// 'https://player.vimeo.com/progressive_redirect/playback/802200207/rendition/720p/file.mp4?loc=external&signature=eaa047c0e223f373da159641d09a5b28e57aae211e6d283c918d8efeabfe2c1b' +// ]; +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar(), +// body: ListView.builder( +// itemCount: listRecorded.length, +// shrinkWrap: true, +// itemBuilder: (context, index) { +// return GestureDetector( +// onTap: () { +// // print(index); +// Get.to( +// () => ZoomPodVideoPlayerRecorded( +// urlLink: listRecorded[index], +// ), +// ); +// }, +// child: Container( +// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), +// decoration: BoxDecoration( +// border: Border.all(color: ColorConstants.kPrimaryColor), +// ), +// margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// // Text('data'), +// Text((index + 1).toString()), +// ], +// ), +// ), +// ); +// }, +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/zoom_recorded_video/zoom_recorded_video_podPlayer.dart b/gsf/lib/views/pages/test/zoom_recorded_video/zoom_recorded_video_podPlayer.dart new file mode 100644 index 0000000..cd5fae6 --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_recorded_video/zoom_recorded_video_podPlayer.dart @@ -0,0 +1,39 @@ +// import 'package:flutter/material.dart'; +// import 'package:pod_player_new/pod_player_new.dart'; + +// class ZoomPodVideoPlayerRecorded extends StatefulWidget { +// final String urlLink; +// const ZoomPodVideoPlayerRecorded({Key? key, required this.urlLink}) +// : super(key: key); + +// @override +// State createState() => +// _ZoomPodVideoPlayerRecordedState(); +// } + +// class _ZoomPodVideoPlayerRecordedState +// extends State { +// @override +// Widget build(BuildContext context) { +// var podPlayerController = PodPlayerController( +// playVideoFrom: PlayVideoFrom.network(widget.urlLink), +// podPlayerConfig: const PodPlayerConfig( +// autoPlay: false, +// isLooping: false, +// ), +// ) +// ..initialise() +// ..disableFullScreen(context); +// return Scaffold( +// appBar: AppBar(), +// body: PodVideoPlayer( +// videoTitle: Text('data'), +// controller: podPlayerController, +// matchFrameAspectRatioToVideo: true, +// matchVideoAspectRatioToFrame: true, +// alwaysShowProgressBar: true, +// backgroundColor: Colors.black, +// ), +// ); +// } +// } diff --git a/gsf/lib/views/pages/test/zoom_redirect.dart b/gsf/lib/views/pages/test/zoom_redirect.dart new file mode 100644 index 0000000..ec0445d --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_redirect.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/foundation/key.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class ZoomRedirect extends StatefulWidget { + const ZoomRedirect({Key? key}) : super(key: key); + + @override + State createState() => ZoomRedirectState(); +} + +class ZoomRedirectState extends State { + // void joinZoomMeeting() async { + // String meetingUrl = + // "https://us05web.zoom.us/j/84932374918?pwd=VzhXTUZLTHB3VXNjSm5WNlEyOU5QUT09"; + + // // Replace MEETING_ID and MEETING_PASSWORD with the actual values + + // if (await canLaunch(meetingUrl)) { + // await launch(meetingUrl); + // } else { + // throw 'Could not launch $meetingUrl'; + // } + // } + void downloadZoomApp() async { + final String zoomPlayStoreLink = + 'https://play.google.com/store/apps/details?id=us.zoom.videomeetings'; + + if (await canLaunch(zoomPlayStoreLink)) { + await launch(zoomPlayStoreLink); + } else { + throw 'Could not launch $zoomPlayStoreLink'; + } + } + + Future _launchZoom(url) async { + if (await canLaunch(url)) { + await launch(url); + } else { + throw 'Could not launch $url'; + } + } + + void launchZoomApp(String zoomLiveLink) async { + final url = 'zoomus://$zoomLiveLink'; + final isZoomInstalled = await canLaunch(url); + + if (isZoomInstalled) { + await launch(url); + } else { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Zoom App Not Found'), + content: GestureDetector( + onTap: downloadZoomApp, + child: const Text( + 'To join this Zoom meeting, please install the Zoom app.'), + ), + actions: [ + TextButton( + onPressed: downloadZoomApp, + child: const Text('OK'), + ), + ], + ), + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Zoom Redirect'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + OutlinedButton( + onPressed: () { + launchZoomApp( + 'https://us05web.zoom.us/j/84305285845?pwd=cFNVS2Z6K2lsNHBLYzdZOG9sWVpHdz09'); + }, + child: const Icon(Icons.play_arrow_outlined), + ), + const Text('Redirect on Zoom Link'), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/test/zoom_video_recorded.dart b/gsf/lib/views/pages/test/zoom_video_recorded.dart new file mode 100644 index 0000000..af7f87b --- /dev/null +++ b/gsf/lib/views/pages/test/zoom_video_recorded.dart @@ -0,0 +1,36 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class VimoeRecordedVideoPlayer extends StatefulWidget { + final String url; + const VimoeRecordedVideoPlayer({Key? key, required this.url}) + : super(key: key); + + @override + _VimoeRecordedVideoPlayerState createState() => + _VimoeRecordedVideoPlayerState(); +} + +class _VimoeRecordedVideoPlayerState extends State { + // var webViewController = + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Zoom Vimeo Video Recorded'), + ), + body: WebViewWidget( + controller: WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(ColorConstants.kBlack) + ..loadRequest( + Uri.parse(widget.url), + ), + ), + ); + } +} diff --git a/gsf/lib/views/pages/vimeo_video_plyaer.dart b/gsf/lib/views/pages/vimeo_video_plyaer.dart new file mode 100644 index 0000000..2d437ca --- /dev/null +++ b/gsf/lib/views/pages/vimeo_video_plyaer.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:vimeo_video_player/vimeo_video_player.dart'; + +class VimeoPlayer extends StatefulWidget { + // ignore: prefer_typing_uninitialized_variables + final urlLink; + const VimeoPlayer({Key? key, required this.urlLink}) : super(key: key); + + @override + _VimeoPlayerState createState() => _VimeoPlayerState(); +} + +class _VimeoPlayerState extends State { + String? _vimeoVideoUrl = ''; + @override + void initState() { + _vimeoVideoUrl = widget.urlLink; + super.initState(); + } + + /// also support url like this: 'www.vimeo.com/70591644', 'vimeo.com/70591644' + + @override + Widget build(BuildContext context) { + return Scaffold( + // backgroundColor: Colors.black, + body: SafeArea( + child: Stack( + children: [ + VimeoVideoPlayer( + url: _vimeoVideoUrl!, + systemUiOverlay: const [ + SystemUiOverlay.top, + SystemUiOverlay.bottom, + ], + // vimeoPlayerModel: VimeoPlayerModel( + // ), + ), + Positioned( + top: 0, + left: 0, + child: GestureDetector( + onTap: () => Get.back(), + child: const Icon( + Icons.close, + size: 40, + color: ColorConstants.kWhite, + ), + ), + ), + ], + ), + ), + ); + } + + @override + void dispose() { + super.dispose(); + } +} diff --git a/gsf/lib/views/short_video_player/sv_player.dart b/gsf/lib/views/short_video_player/sv_player.dart new file mode 100644 index 0000000..c84efbc --- /dev/null +++ b/gsf/lib/views/short_video_player/sv_player.dart @@ -0,0 +1,190 @@ +import 'package:get/get.dart'; +import 'package:gsp_app/views/theme.dart'; +import 'package:pod_player/pod_player.dart'; +// import 'package:pod_player_new/pod_player_new.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +class SvPlayer extends StatefulWidget { + const SvPlayer({ + required this.pageController, + required this.videoUrl, + required this.currentPageIndex, + required this.pagesCount, + //required this.podPlayerController, + Key? key, + }) : super(key: key); + + final String videoUrl; + final PageController pageController; + final int currentPageIndex; + final int pagesCount; + //final PodPlayerController podPlayerController; + + @override + State createState() => _SvPlayer(); +} + +class _SvPlayer extends State { + bool isOverlayVisible = false; + PodPlayerController? podPlayerController; + @override + void initState() { + // podPlayerController = PodPlayerController( + // playVideoFrom: PlayVideoFrom.network(widget.videoUrl), + // podPlayerConfig: const PodPlayerConfig( + // autoPlay: true, + // isLooping: true, + // ), + // ) + // ..initialise().then((value) { + // // storeUrlInCache(widget.videoUrl); + // setState(() { + // podPlayerController.play(); + // }); + // }) + // ..disableFullScreen(context); + initializePlayer(widget.videoUrl); + + super.initState(); + } + + //Initialize Video Player + void initializePlayer(String url) async { + final fileInfo = await DefaultCacheManager().getFileFromCache(url); + if (fileInfo == null) { + podPlayerController = PodPlayerController( + playVideoFrom: PlayVideoFrom.network(widget.videoUrl), + podPlayerConfig: const PodPlayerConfig( + autoPlay: true, + isLooping: true, + ), + ) + ..initialise().then((value) { + // if (mounted) { + setState(() { + podPlayerController!.play(); + setListener(); + }); + // } + storeUrlInCache(widget.videoUrl); + }) + ..disableFullScreen(context); + } else { + final file = fileInfo.file; + podPlayerController = PodPlayerController( + playVideoFrom: PlayVideoFrom.file(file), + podPlayerConfig: const PodPlayerConfig( + autoPlay: true, + isLooping: true, + ), + ) + ..initialise().then((value) { + // if (mounted) { + setState(() { + podPlayerController!.play(); + setListener(); + }); + // } + }) + ..disableFullScreen(context); + } + } + + //:cached Url Data + storeUrlInCache(String url) async { + await DefaultCacheManager().getSingleFile(url).then((value) { + print('downloaded successfully done for $url'); + }); + } + + setListener() { + podPlayerController!.addListener(() { + if (!podPlayerController!.isVideoPlaying) { + isOverlayVisible = true; + } else { + isOverlayVisible = false; + } + if (podPlayerController!.currentVideoPosition.inMilliseconds > + podPlayerController!.totalVideoLength.inMilliseconds - 980) { + if (widget.currentPageIndex == widget.pagesCount - 1) { + widget.pageController.jumpToPage(0); + } + if (widget.currentPageIndex < widget.pagesCount - 1) { + widget.pageController.animateToPage( + widget.currentPageIndex + 1, + duration: const Duration(milliseconds: 800), + curve: Curves.easeOut, + ); + } + } + }); + } + + @override + Widget build(BuildContext context) { + return podPlayerController == null + ? const Scaffold( + body: Center( + child: CircularProgressIndicator( + color: ColorConstants.kPrimaryColor, + ))) + : podPlayerController!.isInitialised + ? Scaffold( + // backgroundColor: Colors.black, + body: PodVideoPlayer( + controller: podPlayerController!, + matchFrameAspectRatioToVideo: true, + matchVideoAspectRatioToFrame: true, + alwaysShowProgressBar: true, + backgroundColor: Colors.black, + podProgressBarConfig: const PodProgressBarConfig( + height: 0, + ), + // videoThumbnail: const DecorationImage( + // /// load from asset: AssetImage('asset_path') + // image: NetworkImage( + // 'https://images.unsplash.com/photo-1569317002804-ab77bcf1bce4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8dW5zcGxhc2h8ZW58MHx8MHx8&w=1000&q=80', + // ), + // ), + overlayBuilder: (options) { + return GestureDetector( + onTap: () { + isOverlayVisible = !isOverlayVisible; + debugPrint('SHOW UI $isOverlayVisible'); + isOverlayVisible + ? podPlayerController!.pause() + : podPlayerController!.play(); + }, + child: Opacity( + opacity: isOverlayVisible ? 1 : 0, + child: Container( + color: Colors.transparent, + height: Get.size.height - 300, + width: Get.size.width, + child: const Icon( + Icons.play_arrow, + size: 58, + color: Colors.white, + ), + ), + ), + ); + }, + ), + ) + : const Scaffold( + body: Center( + child: CircularProgressIndicator( + color: ColorConstants.kPrimaryColor, + ))); + } + + @override + void dispose() { + if (podPlayerController != null) { + podPlayerController!.dispose(); + } + super.dispose(); + } +} diff --git a/gsf/lib/views/short_video_player/sv_webview.dart b/gsf/lib/views/short_video_player/sv_webview.dart new file mode 100644 index 0000000..3ef8267 --- /dev/null +++ b/gsf/lib/views/short_video_player/sv_webview.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:gsp_app/modals/short_clip_model.dart'; +import 'package:webview_flutter/webview_flutter.dart'; +import 'package:share_plus/share_plus.dart'; + +import '../components/appbar.dart'; +import '../theme.dart'; + +// +class SvpWebView extends StatefulWidget { + const SvpWebView({ + required this.index, + required this.clips, + Key? key, + }) : super(key: key); + + final List clips; + final int index; + + @override + State createState() => _SvpWebView(); +} + +class _SvpWebView extends State { + Uri generateVideoUri(String videoLink) { + String videoId = videoLink.split("/").last; + Uri uri = + Uri.parse("https://player.vimeo.com/video/$videoId?loop=1&autopause=0"); + return uri; + } + + late PageController pageController; + + @override + void initState() { + super.initState(); + pageController = PageController(initialPage: widget.index); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: SafeArea( + child: DefaultTextStyle( + style: const TextStyle(color: Colors.white), + child: PageView.builder( + controller: pageController, + scrollDirection: Axis.vertical, + itemCount: widget.clips.length, + itemBuilder: (context, index) { + bool showFullDesc = false; + var webViewController = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(Colors.black) + ..loadRequest(generateVideoUri(widget.clips[index].videoUrl)); + return Scaffold( + backgroundColor: Colors.black, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars( + backgroundColor: + Theme.of(context).appBarTheme.backgroundColor, + titleHead: widget.clips[index].title, + rightAction: IconButton( + onPressed: () { + Share.share(widget.clips[index].videoUrl); + }, + icon: const Icon(Icons.share_outlined), + ), + ), + ), + body: Stack( + children: [ + Expanded( + child: WebViewWidget(controller: webViewController), + ), + + /*//title row + Positioned( + top: 0, + right: 2, + child: SizedBox( + width: MediaQuery.of(context).size.width, + child: Row( + children: [ + IconButton( + onPressed: () => Get.back(), + icon: const Icon(Icons.arrow_back)), + Expanded( + child: Text( + widget.clips[index].title, + overflow: TextOverflow.fade, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + // StatefulBuilder( + // builder: (context, setLikeBtnState) { + // return IconButton( + // onPressed: () { + // // setLikeBtnState(() { + // // shortsJson[index]["isLiked"] = + // // !shortsJson[index]["isLiked"]; + // // }); + // }, + // icon: Icon(shortsJson[index]["isLiked"] + // ? Icons.thumb_up + // : Icons.thumb_up_outlined), + // ); + // }, + // ), + IconButton( + onPressed: () { + Share.share( + widget.clips[index].videoUrl); + }, + icon: const Icon(Icons.share_outlined), + ) + ], + ), + ), + ), + */ + //description + Positioned( + bottom: 0, + left: 8, + right: 8, + child: StatefulBuilder( + builder: (context, setDescState) { + return SizedBox( + width: MediaQuery.of(context).size.width, + child: InkWell( + child: Text( + widget.clips[index].description, + maxLines: showFullDesc ? 30 : 2, + textAlign: TextAlign.justify, + style: const TextStyle( + fontSize: 16, + overflow: TextOverflow.ellipsis, + ), + ), + onTap: () { + setDescState(() { + showFullDesc = !showFullDesc; + }); + }, + ), + ); + }, + ), + ) + ], + ), + ); + }, + ), + ), + ), + ); + } +} diff --git a/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.dart b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.dart new file mode 100644 index 0000000..5919271 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.dart @@ -0,0 +1,165 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:injectable/injectable.dart'; +import 'package:video_player/video_player.dart'; + +import '../core/constants.dart'; +import '../main.dart'; +import '../service/api_service.dart'; + +part 'preload_bloc.freezed.dart'; +part 'preload_event.dart'; +part 'preload_state.dart'; + +@injectable +@prod +class PreloadBloc extends Bloc { + PreloadBloc() : super(PreloadState.initial()) { + on(_mapEventToState); + } + + void _mapEventToState(PreloadEvent event, Emitter emit) async { + await event.map( + setLoading: (e) { + emit(state.copyWith(isLoading: true)); + }, + getVideosFromApi: (e) async { + /// Fetch first 5 videos from api + final List _urls = await ApiService.getVideos(); + state.urls.addAll(_urls); + + /// Initialize 1st video + await _initializeControllerAtIndex(0); + + /// Play 1st video + _playControllerAtIndex(0); + + /// Initialize 2nd video + await _initializeControllerAtIndex(1); + + emit(state.copyWith(reloadCounter: state.reloadCounter + 1)); + }, + // initialize: (e) async* {}, + onVideoIndexChanged: (e) { + /// Condition to fetch new videos + final bool shouldFetch = (e.index + kPreloadLimit) % kNextLimit == 0 && + state.urls.length == e.index + kPreloadLimit; + + if (shouldFetch) { + createIsolate(e.index); + } + + /// Next / Prev video decider + if (e.index > state.focusedIndex) { + _playNext(e.index); + } else { + _playPrevious(e.index); + } + + emit(state.copyWith(focusedIndex: e.index)); + }, + updateUrls: (e) { + /// Add new urls to current urls + state.urls.addAll(e.urls); + + /// Initialize new url + _initializeControllerAtIndex(state.focusedIndex + 1); + + emit(state.copyWith( + reloadCounter: state.reloadCounter + 1, isLoading: false)); + log('🚀🚀🚀 NEW VIDEOS ADDED'); + }, + ); + } + + void _playNext(int index) { + /// Stop [index - 1] controller + _stopControllerAtIndex(index - 1); + + /// Dispose [index - 2] controller + _disposeControllerAtIndex(index - 2); + + /// Play current video (already initialized) + _playControllerAtIndex(index); + + /// Initialize [index + 1] controller + _initializeControllerAtIndex(index + 1); + } + + void _playPrevious(int index) { + /// Stop [index + 1] controller + _stopControllerAtIndex(index + 1); + + /// Dispose [index + 2] controller + _disposeControllerAtIndex(index + 2); + + /// Play current video (already initialized) + _playControllerAtIndex(index); + + /// Initialize [index - 1] controller + _initializeControllerAtIndex(index - 1); + } + + Future _initializeControllerAtIndex(int index) async { + if (state.urls.length > index && index >= 0) { + /// Create new controller + final VideoPlayerController _controller = + VideoPlayerController.network(state.urls[index]); + + /// Add to [controllers] list + state.controllers[index] = _controller; + + /// Initialize + await _controller.initialize(); + + log('🚀🚀🚀 INITIALIZED $index'); + } + } + + void _playControllerAtIndex(int index) { + if (state.urls.length > index && index >= 0) { + /// Get controller at [index] + final VideoPlayerController _controller = state.controllers[index]!; + + /// Play controller + _controller.setVolume(0.0); + _controller.play(); + + log('🚀🚀🚀 PLAYING $index'); + } + } + + void _stopControllerAtIndex(int index) { + if (state.urls.length > index && index >= 0) { + /// Get controller at [index] + final VideoPlayerController _controller = state.controllers[index]!; + + /// Pause + _controller.pause(); + + /// Reset postiton to beginning + _controller.seekTo(const Duration()); + + log('🚀🚀🚀 STOPPED $index'); + } + } + + void _disposeControllerAtIndex(int index) { + if (state.urls.length > index && index >= 0) { + /// Get controller at [index] + final VideoPlayerController? _controller = state.controllers[index]; + + /// Dispose controller + _controller?.dispose(); + + if (_controller != null) { + state.controllers.remove(_controller); + } + + log('🚀🚀🚀 DISPOSED $index'); + } + } +} diff --git a/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.freezed.dart b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.freezed.dart new file mode 100644 index 0000000..5b785e9 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_bloc.freezed.dart @@ -0,0 +1,822 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target + +part of 'preload_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +/// @nodoc +mixin _$PreloadEvent { + @optionalTypeArgs + TResult when({ + required TResult Function() getVideosFromApi, + required TResult Function() setLoading, + required TResult Function(List urls) updateUrls, + required TResult Function(int index) onVideoIndexChanged, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_GetVideosFromApi value) getVideosFromApi, + required TResult Function(_SetLoading value) setLoading, + required TResult Function(_UpdateUrls value) updateUrls, + required TResult Function(_OnVideoIndexChanged value) onVideoIndexChanged, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PreloadEventCopyWith<$Res> { + factory $PreloadEventCopyWith( + PreloadEvent value, $Res Function(PreloadEvent) then) = + _$PreloadEventCopyWithImpl<$Res>; +} + +/// @nodoc +class _$PreloadEventCopyWithImpl<$Res> implements $PreloadEventCopyWith<$Res> { + _$PreloadEventCopyWithImpl(this._value, this._then); + + final PreloadEvent _value; + // ignore: unused_field + final $Res Function(PreloadEvent) _then; +} + +/// @nodoc +abstract class _$$_GetVideosFromApiCopyWith<$Res> { + factory _$$_GetVideosFromApiCopyWith( + _$_GetVideosFromApi value, $Res Function(_$_GetVideosFromApi) then) = + __$$_GetVideosFromApiCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$_GetVideosFromApiCopyWithImpl<$Res> + extends _$PreloadEventCopyWithImpl<$Res> + implements _$$_GetVideosFromApiCopyWith<$Res> { + __$$_GetVideosFromApiCopyWithImpl( + _$_GetVideosFromApi _value, $Res Function(_$_GetVideosFromApi) _then) + : super(_value, (v) => _then(v as _$_GetVideosFromApi)); + + @override + _$_GetVideosFromApi get _value => super._value as _$_GetVideosFromApi; +} + +/// @nodoc + +class _$_GetVideosFromApi implements _GetVideosFromApi { + const _$_GetVideosFromApi(); + + @override + String toString() { + return 'PreloadEvent.getVideosFromApi()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$_GetVideosFromApi); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() getVideosFromApi, + required TResult Function() setLoading, + required TResult Function(List urls) updateUrls, + required TResult Function(int index) onVideoIndexChanged, + }) { + return getVideosFromApi(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + }) { + return getVideosFromApi?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (getVideosFromApi != null) { + return getVideosFromApi(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_GetVideosFromApi value) getVideosFromApi, + required TResult Function(_SetLoading value) setLoading, + required TResult Function(_UpdateUrls value) updateUrls, + required TResult Function(_OnVideoIndexChanged value) onVideoIndexChanged, + }) { + return getVideosFromApi(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + }) { + return getVideosFromApi?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (getVideosFromApi != null) { + return getVideosFromApi(this); + } + return orElse(); + } +} + +abstract class _GetVideosFromApi implements PreloadEvent { + const factory _GetVideosFromApi() = _$_GetVideosFromApi; +} + +/// @nodoc +abstract class _$$_SetLoadingCopyWith<$Res> { + factory _$$_SetLoadingCopyWith( + _$_SetLoading value, $Res Function(_$_SetLoading) then) = + __$$_SetLoadingCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$_SetLoadingCopyWithImpl<$Res> extends _$PreloadEventCopyWithImpl<$Res> + implements _$$_SetLoadingCopyWith<$Res> { + __$$_SetLoadingCopyWithImpl( + _$_SetLoading _value, $Res Function(_$_SetLoading) _then) + : super(_value, (v) => _then(v as _$_SetLoading)); + + @override + _$_SetLoading get _value => super._value as _$_SetLoading; +} + +/// @nodoc + +class _$_SetLoading implements _SetLoading { + const _$_SetLoading(); + + @override + String toString() { + return 'PreloadEvent.setLoading()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$_SetLoading); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() getVideosFromApi, + required TResult Function() setLoading, + required TResult Function(List urls) updateUrls, + required TResult Function(int index) onVideoIndexChanged, + }) { + return setLoading(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + }) { + return setLoading?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (setLoading != null) { + return setLoading(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_GetVideosFromApi value) getVideosFromApi, + required TResult Function(_SetLoading value) setLoading, + required TResult Function(_UpdateUrls value) updateUrls, + required TResult Function(_OnVideoIndexChanged value) onVideoIndexChanged, + }) { + return setLoading(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + }) { + return setLoading?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (setLoading != null) { + return setLoading(this); + } + return orElse(); + } +} + +abstract class _SetLoading implements PreloadEvent { + const factory _SetLoading() = _$_SetLoading; +} + +/// @nodoc +abstract class _$$_UpdateUrlsCopyWith<$Res> { + factory _$$_UpdateUrlsCopyWith( + _$_UpdateUrls value, $Res Function(_$_UpdateUrls) then) = + __$$_UpdateUrlsCopyWithImpl<$Res>; + $Res call({List urls}); +} + +/// @nodoc +class __$$_UpdateUrlsCopyWithImpl<$Res> extends _$PreloadEventCopyWithImpl<$Res> + implements _$$_UpdateUrlsCopyWith<$Res> { + __$$_UpdateUrlsCopyWithImpl( + _$_UpdateUrls _value, $Res Function(_$_UpdateUrls) _then) + : super(_value, (v) => _then(v as _$_UpdateUrls)); + + @override + _$_UpdateUrls get _value => super._value as _$_UpdateUrls; + + @override + $Res call({ + Object? urls = freezed, + }) { + return _then(_$_UpdateUrls( + urls == freezed + ? _value._urls + : urls // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +class _$_UpdateUrls implements _UpdateUrls { + const _$_UpdateUrls(final List urls) : _urls = urls; + + final List _urls; + @override + List get urls { + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_urls); + } + + @override + String toString() { + return 'PreloadEvent.updateUrls(urls: $urls)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_UpdateUrls && + const DeepCollectionEquality().equals(other._urls, _urls)); + } + + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(_urls)); + + @JsonKey(ignore: true) + @override + _$$_UpdateUrlsCopyWith<_$_UpdateUrls> get copyWith => + __$$_UpdateUrlsCopyWithImpl<_$_UpdateUrls>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() getVideosFromApi, + required TResult Function() setLoading, + required TResult Function(List urls) updateUrls, + required TResult Function(int index) onVideoIndexChanged, + }) { + return updateUrls(urls); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + }) { + return updateUrls?.call(urls); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (updateUrls != null) { + return updateUrls(urls); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_GetVideosFromApi value) getVideosFromApi, + required TResult Function(_SetLoading value) setLoading, + required TResult Function(_UpdateUrls value) updateUrls, + required TResult Function(_OnVideoIndexChanged value) onVideoIndexChanged, + }) { + return updateUrls(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + }) { + return updateUrls?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (updateUrls != null) { + return updateUrls(this); + } + return orElse(); + } +} + +abstract class _UpdateUrls implements PreloadEvent { + const factory _UpdateUrls(final List urls) = _$_UpdateUrls; + + List get urls => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$$_UpdateUrlsCopyWith<_$_UpdateUrls> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$_OnVideoIndexChangedCopyWith<$Res> { + factory _$$_OnVideoIndexChangedCopyWith(_$_OnVideoIndexChanged value, + $Res Function(_$_OnVideoIndexChanged) then) = + __$$_OnVideoIndexChangedCopyWithImpl<$Res>; + $Res call({int index}); +} + +/// @nodoc +class __$$_OnVideoIndexChangedCopyWithImpl<$Res> + extends _$PreloadEventCopyWithImpl<$Res> + implements _$$_OnVideoIndexChangedCopyWith<$Res> { + __$$_OnVideoIndexChangedCopyWithImpl(_$_OnVideoIndexChanged _value, + $Res Function(_$_OnVideoIndexChanged) _then) + : super(_value, (v) => _then(v as _$_OnVideoIndexChanged)); + + @override + _$_OnVideoIndexChanged get _value => super._value as _$_OnVideoIndexChanged; + + @override + $Res call({ + Object? index = freezed, + }) { + return _then(_$_OnVideoIndexChanged( + index == freezed + ? _value.index + : index // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc + +class _$_OnVideoIndexChanged implements _OnVideoIndexChanged { + const _$_OnVideoIndexChanged(this.index); + + @override + final int index; + + @override + String toString() { + return 'PreloadEvent.onVideoIndexChanged(index: $index)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_OnVideoIndexChanged && + const DeepCollectionEquality().equals(other.index, index)); + } + + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(index)); + + @JsonKey(ignore: true) + @override + _$$_OnVideoIndexChangedCopyWith<_$_OnVideoIndexChanged> get copyWith => + __$$_OnVideoIndexChangedCopyWithImpl<_$_OnVideoIndexChanged>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() getVideosFromApi, + required TResult Function() setLoading, + required TResult Function(List urls) updateUrls, + required TResult Function(int index) onVideoIndexChanged, + }) { + return onVideoIndexChanged(index); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + }) { + return onVideoIndexChanged?.call(index); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? getVideosFromApi, + TResult Function()? setLoading, + TResult Function(List urls)? updateUrls, + TResult Function(int index)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (onVideoIndexChanged != null) { + return onVideoIndexChanged(index); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_GetVideosFromApi value) getVideosFromApi, + required TResult Function(_SetLoading value) setLoading, + required TResult Function(_UpdateUrls value) updateUrls, + required TResult Function(_OnVideoIndexChanged value) onVideoIndexChanged, + }) { + return onVideoIndexChanged(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + }) { + return onVideoIndexChanged?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_GetVideosFromApi value)? getVideosFromApi, + TResult Function(_SetLoading value)? setLoading, + TResult Function(_UpdateUrls value)? updateUrls, + TResult Function(_OnVideoIndexChanged value)? onVideoIndexChanged, + required TResult orElse(), + }) { + if (onVideoIndexChanged != null) { + return onVideoIndexChanged(this); + } + return orElse(); + } +} + +abstract class _OnVideoIndexChanged implements PreloadEvent { + const factory _OnVideoIndexChanged(final int index) = _$_OnVideoIndexChanged; + + int get index => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$$_OnVideoIndexChangedCopyWith<_$_OnVideoIndexChanged> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$PreloadState { + List get urls => throw _privateConstructorUsedError; + Map get controllers => + throw _privateConstructorUsedError; + int get focusedIndex => throw _privateConstructorUsedError; + int get reloadCounter => throw _privateConstructorUsedError; + bool get isLoading => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $PreloadStateCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PreloadStateCopyWith<$Res> { + factory $PreloadStateCopyWith( + PreloadState value, $Res Function(PreloadState) then) = + _$PreloadStateCopyWithImpl<$Res>; + $Res call( + {List urls, + Map controllers, + int focusedIndex, + int reloadCounter, + bool isLoading}); +} + +/// @nodoc +class _$PreloadStateCopyWithImpl<$Res> implements $PreloadStateCopyWith<$Res> { + _$PreloadStateCopyWithImpl(this._value, this._then); + + final PreloadState _value; + // ignore: unused_field + final $Res Function(PreloadState) _then; + + @override + $Res call({ + Object? urls = freezed, + Object? controllers = freezed, + Object? focusedIndex = freezed, + Object? reloadCounter = freezed, + Object? isLoading = freezed, + }) { + return _then(_value.copyWith( + urls: urls == freezed + ? _value.urls + : urls // ignore: cast_nullable_to_non_nullable + as List, + controllers: controllers == freezed + ? _value.controllers + : controllers // ignore: cast_nullable_to_non_nullable + as Map, + focusedIndex: focusedIndex == freezed + ? _value.focusedIndex + : focusedIndex // ignore: cast_nullable_to_non_nullable + as int, + reloadCounter: reloadCounter == freezed + ? _value.reloadCounter + : reloadCounter // ignore: cast_nullable_to_non_nullable + as int, + isLoading: isLoading == freezed + ? _value.isLoading + : isLoading // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +abstract class _$$_PreloadStateCopyWith<$Res> + implements $PreloadStateCopyWith<$Res> { + factory _$$_PreloadStateCopyWith( + _$_PreloadState value, $Res Function(_$_PreloadState) then) = + __$$_PreloadStateCopyWithImpl<$Res>; + @override + $Res call( + {List urls, + Map controllers, + int focusedIndex, + int reloadCounter, + bool isLoading}); +} + +/// @nodoc +class __$$_PreloadStateCopyWithImpl<$Res> + extends _$PreloadStateCopyWithImpl<$Res> + implements _$$_PreloadStateCopyWith<$Res> { + __$$_PreloadStateCopyWithImpl( + _$_PreloadState _value, $Res Function(_$_PreloadState) _then) + : super(_value, (v) => _then(v as _$_PreloadState)); + + @override + _$_PreloadState get _value => super._value as _$_PreloadState; + + @override + $Res call({ + Object? urls = freezed, + Object? controllers = freezed, + Object? focusedIndex = freezed, + Object? reloadCounter = freezed, + Object? isLoading = freezed, + }) { + return _then(_$_PreloadState( + urls: urls == freezed + ? _value.urls + : urls // ignore: cast_nullable_to_non_nullable + as List, + controllers: controllers == freezed + ? _value.controllers + : controllers // ignore: cast_nullable_to_non_nullable + as Map, + focusedIndex: focusedIndex == freezed + ? _value.focusedIndex + : focusedIndex // ignore: cast_nullable_to_non_nullable + as int, + reloadCounter: reloadCounter == freezed + ? _value.reloadCounter + : reloadCounter // ignore: cast_nullable_to_non_nullable + as int, + isLoading: isLoading == freezed + ? _value.isLoading + : isLoading // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc + +class _$_PreloadState implements _PreloadState { + _$_PreloadState( + {required this.urls, + required this.controllers, + required this.focusedIndex, + required this.reloadCounter, + required this.isLoading}); + + @override + final List urls; + @override + final Map controllers; + @override + final int focusedIndex; + @override + final int reloadCounter; + @override + final bool isLoading; + + @override + String toString() { + return 'PreloadState(urls: $urls, controllers: $controllers, focusedIndex: $focusedIndex, reloadCounter: $reloadCounter, isLoading: $isLoading)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_PreloadState && + const DeepCollectionEquality().equals(other.urls, urls) && + const DeepCollectionEquality() + .equals(other.controllers, controllers) && + const DeepCollectionEquality() + .equals(other.focusedIndex, focusedIndex) && + const DeepCollectionEquality() + .equals(other.reloadCounter, reloadCounter) && + const DeepCollectionEquality().equals(other.isLoading, isLoading)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(urls), + const DeepCollectionEquality().hash(controllers), + const DeepCollectionEquality().hash(focusedIndex), + const DeepCollectionEquality().hash(reloadCounter), + const DeepCollectionEquality().hash(isLoading)); + + @JsonKey(ignore: true) + @override + _$$_PreloadStateCopyWith<_$_PreloadState> get copyWith => + __$$_PreloadStateCopyWithImpl<_$_PreloadState>(this, _$identity); +} + +abstract class _PreloadState implements PreloadState { + factory _PreloadState( + {required final List urls, + required final Map controllers, + required final int focusedIndex, + required final int reloadCounter, + required final bool isLoading}) = _$_PreloadState; + + @override + List get urls => throw _privateConstructorUsedError; + @override + Map get controllers => + throw _privateConstructorUsedError; + @override + int get focusedIndex => throw _privateConstructorUsedError; + @override + int get reloadCounter => throw _privateConstructorUsedError; + @override + bool get isLoading => throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$$_PreloadStateCopyWith<_$_PreloadState> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/gsf/lib/views/short_video_player/svp_lib/bloc/preload_event.dart b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_event.dart new file mode 100644 index 0000000..fd74a56 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_event.dart @@ -0,0 +1,11 @@ +part of 'preload_bloc.dart'; + +@freezed +class PreloadEvent with _$PreloadEvent { + // const factory PreloadEvent.initialize() = _Initialize; + const factory PreloadEvent.getVideosFromApi() = _GetVideosFromApi; + const factory PreloadEvent.setLoading() = _SetLoading; + const factory PreloadEvent.updateUrls(List urls) = _UpdateUrls; + const factory PreloadEvent.onVideoIndexChanged(int index) = + _OnVideoIndexChanged; +} diff --git a/gsf/lib/views/short_video_player/svp_lib/bloc/preload_state.dart b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_state.dart new file mode 100644 index 0000000..44a84c9 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/bloc/preload_state.dart @@ -0,0 +1,20 @@ +part of 'preload_bloc.dart'; + +@Freezed(makeCollectionsUnmodifiable: false) +class PreloadState with _$PreloadState { + factory PreloadState({ + required List urls, + required Map controllers, + required int focusedIndex, + required int reloadCounter, + required bool isLoading, + }) = _PreloadState; + + factory PreloadState.initial() => PreloadState( + focusedIndex: 0, + reloadCounter: 0, + isLoading: false, + urls: [], + controllers: {}, + ); +} diff --git a/gsf/lib/views/short_video_player/svp_lib/core/build_context.dart b/gsf/lib/views/short_video_player/svp_lib/core/build_context.dart new file mode 100644 index 0000000..794f5ea --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/core/build_context.dart @@ -0,0 +1,8 @@ +import 'package:flutter/material.dart'; + +import '../injection.dart'; +import '../service/navigation_service.dart'; + +/// Global BuildContext +final BuildContext context = + getIt().navigationKey.currentContext!; diff --git a/gsf/lib/views/short_video_player/svp_lib/core/constants.dart b/gsf/lib/views/short_video_player/svp_lib/core/constants.dart new file mode 100644 index 0000000..a3303ed --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/core/constants.dart @@ -0,0 +1,11 @@ +// Customize +const int kPreloadLimit = 3; +// const int kPreloadLimit = 0; + +// Customize +int kNextLimit = 5; +// int kNextLimit = 0; + +// For better UX, latency should be minimum. +// For demo: 2s is taken but something under a second will be better +const int kLatency = 0; diff --git a/gsf/lib/views/short_video_player/svp_lib/injection.config.dart b/gsf/lib/views/short_video_player/svp_lib/injection.config.dart new file mode 100644 index 0000000..82c392b --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/injection.config.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// InjectableConfigGenerator +// ************************************************************************** + +import 'package:get_it/get_it.dart' as _i1; +import 'package:injectable/injectable.dart' as _i2; + +import 'bloc/preload_bloc.dart' as _i4; +import 'service/navigation_service.dart' as _i3; + +const String _prod = 'prod'; +// ignore_for_file: unnecessary_lambdas +// ignore_for_file: lines_longer_than_80_chars +/// initializes the registration of provided dependencies inside of [GetIt] +_i1.GetIt $initGetIt(_i1.GetIt get, + {String? environment, _i2.EnvironmentFilter? environmentFilter}) { + final gh = _i2.GetItHelper(get, environment, environmentFilter); + gh.lazySingleton<_i3.NavigationService>(() => _i3.NavigationService()); + gh.factory<_i4.PreloadBloc>(() => _i4.PreloadBloc(), registerFor: {_prod}); + return get; +} diff --git a/gsf/lib/views/short_video_player/svp_lib/injection.dart b/gsf/lib/views/short_video_player/svp_lib/injection.dart new file mode 100644 index 0000000..ac0620b --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/injection.dart @@ -0,0 +1,11 @@ +import 'package:get_it/get_it.dart'; +import 'package:injectable/injectable.dart'; + +import 'injection.config.dart'; + +final GetIt getIt = GetIt.instance; + +@injectableInit +void configureInjection(String env) { + $initGetIt(getIt, environment: env); +} diff --git a/gsf/lib/views/short_video_player/svp_lib/main.dart b/gsf/lib/views/short_video_player/svp_lib/main.dart new file mode 100644 index 0000000..5388c7b --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/main.dart @@ -0,0 +1,80 @@ +import 'dart:isolate'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:injectable/injectable.dart'; + +import 'core/constants.dart'; +import 'service/api_service.dart'; +import 'bloc/preload_bloc.dart'; +import 'core/build_context.dart'; +import 'injection.dart'; + +// void main() async { +// WidgetsFlutterBinding.ensureInitialized(); +// configureInjection(Environment.prod); +// runApp(MyApp()); +// } + +/// Isolate to fetch videos in the background so that the video experience is not disturbed. +/// Without isolate, the video will be paused whenever there is an API call +/// because the main thread will be busy fetching new video URLs. +/// +/// https://blog.codemagic.io/understanding-flutter-isolates/ +Future createIsolate(int index) async { + // Set loading to true + BlocProvider.of(context, listen: false) + .add(PreloadEvent.setLoading()); + + ReceivePort mainReceivePort = ReceivePort(); + + Isolate.spawn(getVideosTask, mainReceivePort.sendPort); + + SendPort isolateSendPort = await mainReceivePort.first; + + ReceivePort isolateResponseReceivePort = ReceivePort(); + + isolateSendPort.send([index, isolateResponseReceivePort.sendPort]); + + final isolateResponse = await isolateResponseReceivePort.first; + final _urls = isolateResponse; + + // Update new urls + BlocProvider.of(context, listen: false) + .add(PreloadEvent.updateUrls(_urls)); +} + +void getVideosTask(SendPort mySendPort) async { + ReceivePort isolateReceivePort = ReceivePort(); + + mySendPort.send(isolateReceivePort.sendPort); + + await for (var message in isolateReceivePort) { + if (message is List) { + final int index = message[0]; + + final SendPort isolateResponseSendPort = message[1]; + + final List _urls = + await ApiService.getVideos(id: index + kPreloadLimit); + + isolateResponseSendPort.send(_urls); + } + } +} + +// class MyApp extends StatelessWidget { +// final NavigationService _navigationService = getIt(); + +// @override +// Widget build(BuildContext context) { +// return BlocProvider( +// create: (_) => getIt()..add(PreloadEvent.getVideosFromApi()), +// child: MaterialApp( +// key: _navigationService.navigationKey, +// debugShowCheckedModeBanner: false, +// home: VideoPage(), +// ), +// ); +// } +// } diff --git a/gsf/lib/views/short_video_player/svp_lib/service/api_service.dart b/gsf/lib/views/short_video_player/svp_lib/service/api_service.dart new file mode 100644 index 0000000..c4041fb --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/service/api_service.dart @@ -0,0 +1,62 @@ +import '../core/constants.dart'; + +class ApiService { + static List videos = [ + 'https://assets.mixkit.co/videos/preview/mixkit-woman-turning-off-her-alarm-clock-42897-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-pair-of-plantain-stalks-in-a-close-up-shot-42956-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-aerial-view-of-city-traffic-at-night-11-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-countryside-meadow-4075-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-texture-of-different-fruits-42959-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-landscape-of-mountains-and-sunset-3128-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-woman-washing-her-hair-while-taking-a-bath-42915-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-clouds-and-blue-sky-2408-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-different-types-of-fresh-fruit-in-presentation-video-42941-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-forest-stream-in-the-sunlight-529-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-stunning-sunset-seen-from-the-sea-4119-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-meadow-surrounded-by-trees-on-a-sunny-afternoon-40647-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-fruit-texture-in-a-humid-environment-42958-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-close-up-shot-of-a-turntable-playing-a-record-42920-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-woman-serving-eggs-in-a-pan-for-breakfast-42909-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-close-view-of-a-record-rotating-on-a-turntable-42921-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-young-woman-finishing-preparing-her-breakfast-42911-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-waterfall-in-forest-2213-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-close-up-view-of-a-rotating-vinyl-record-42922-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-going-down-a-curved-highway-down-a-mountain-41576-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-lake-surrounded-by-dry-grass-in-the-savanna-5030-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-aerial-panorama-of-a-landscape-with-mountains-and-a-lake-4249-large.mp4/', + 'https://assets.mixkit.co/videos/preview/mixkit-curvy-road-on-a-tree-covered-hill-41537-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-frying-diced-bacon-in-a-skillet-43063-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-young-woman-taking-a-shower-42916-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-rain-falling-on-the-water-of-a-lake-seen-up-18312-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-people-pouring-a-warm-drink-around-a-campfire-513-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-stars-in-space-1610-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-fireworks-illuminating-the-beach-sky-4157-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-huge-trees-in-a-large-green-forest-5040-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-close-up-shot-of-a-computers-internal-system-42924-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-lots-of-chips-and-dice-arranged-on-a-game-table-42931-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-fresh-apples-in-a-row-on-a-natural-background-42946-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-very-close-shot-of-the-leaves-of-a-tree-wet-18310-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-woman-preparing-her-lunch-in-the-morning-42908-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-woman-flipping-her-egg-omelet-42910-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-top-aerial-shot-of-seashore-with-rocks-1090-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-close-tour-through-the-middle-of-an-open-book-42926-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-white-sand-beach-and-palm-trees-1564-large.mp4', + 'https://assets.mixkit.co/videos/preview/mixkit-young-woman-waking-up-in-the-morning-42896-large.mp4' + ]; + + /// Simulate api call + static Future> getVideos({int id = 0}) async { + // No more videos + if ((id >= videos.length)) { + return []; + } + + await Future.delayed(const Duration(seconds: kLatency)); + + if ((id + kNextLimit >= videos.length)) { + return videos.sublist(id, videos.length); + } + + return videos.sublist(id, id + kNextLimit); + } +} diff --git a/gsf/lib/views/short_video_player/svp_lib/service/navigation_service.dart b/gsf/lib/views/short_video_player/svp_lib/service/navigation_service.dart new file mode 100644 index 0000000..9a71e11 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/service/navigation_service.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:injectable/injectable.dart'; + +@lazySingleton +class NavigationService { + final GlobalKey _navigationKey = GlobalKey(); + + GlobalKey get navigationKey => _navigationKey; +} diff --git a/gsf/lib/views/short_video_player/svp_lib/video_page.dart b/gsf/lib/views/short_video_player/svp_lib/video_page.dart new file mode 100644 index 0000000..2b78c06 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_lib/video_page.dart @@ -0,0 +1,495 @@ +import 'package:another_flushbar/flushbar.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_branch_sdk/flutter_branch_sdk.dart'; +import 'package:get/get.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:video_player/video_player.dart'; + +import '../../../modals/short_clip_likes_model.dart'; +import '../../../modals/short_clip_model.dart'; +import '../../../repository/services/short_clip_service.dart'; +import '../../theme.dart'; +import 'bloc/preload_bloc.dart'; +import 'injection.dart'; + +class VideoPage extends StatefulWidget { + VideoPage({ + super.key, + required this.fetchedClips, + required this.fetchedLikes, + required this.index, + }); + + List fetchedClips = []; + List fetchedLikes = []; + static VideoPlayerController? currentController; + static List videoControllers = []; + int index; + + @override + State createState() => _VideoPageState(); +} + +class _VideoPageState extends State { + bool isPgLoading = true; + bool showFullDesc = false; + bool showLikeBtnLoader = false; + bool showShareBtnLoader = false; + BranchContentMetaData metadata = BranchContentMetaData(); + BranchUniversalObject? buo; + BranchLinkProperties lp = BranchLinkProperties(); + BranchEvent? eventStandard; + BranchEvent? eventCustom; + static const imageURL = + 'https://raw.githubusercontent.com/RodrigoSMarques/flutter_branch_sdk/master/assets/branch_logo_qrcode.jpeg'; + + late List controllers; + late PageController pageController; + + @override + void initState() { + pageController = PageController(initialPage: widget.index); + controllers = widget.fetchedClips + .map((e) => VideoPlayerController.networkUrl(Uri.parse(e.videoUrl))) + .toList(); + + controllers[widget.index].initialize(); + if (widget.index + 1 < controllers.length) { + controllers[widget.index + 1].initialize(); + } + if (widget.index + 2 < controllers.length) { + controllers[widget.index + 2].initialize(); + } + if (widget.index - 1 >= 0) { + controllers[widget.index - 1].initialize(); + } + if (widget.index - 2 >= 0) { + controllers[widget.index - 2].initialize(); + } + + controllers[widget.index] + ..play() + ..setLooping(true); + + super.initState(); + } + + int prevPgIndex = 0; + + @override + void dispose() { + for (var element in controllers) { + element.dispose(); + } + super.dispose(); + } + + void initDeepLinkData(int index) { + metadata = BranchContentMetaData() + // ..addCustomMetadata('custom_string', 'gsf product title') + ..addCustomMetadata('custom_number', index.toString()); + // ..addCustomMetadata('custom_bool', true) + // ..addCustomMetadata('custom_list_number', [1, 2, 3, 4, 5]) + // ..addCustomMetadata('custom_list_string', ['a', 'b', 'c']); + //--optional Custom Metadata + // ..contentSchema = BranchContentSchema.COMMERCE_PRODUCT + // ..price = 50.99 + // ..currencyType = BranchCurrencyType.BRL + // ..quantity = 50 + // ..sku = 'sku' + // ..productName = 'productName' + // ..productBrand = 'productBrand' + // ..productCategory = BranchProductCategory.ELECTRONICS + // ..productVariant = 'productVariant' + // ..condition = BranchCondition.NEW + // ..rating = 100 + // ..ratingAverage = 50 + // ..ratingMax = 100 + // ..ratingCount = 2 + // ..setAddress( + // street: 'street', + // city: 'city', + // region: 'ES', + // country: 'Brazil', + // postalCode: '99999-987') + // ..setLocation(31.4521685, -114.7352207); + + buo = BranchUniversalObject( + canonicalIdentifier: 'flutter/branch', + //parameter canonicalUrl + //If your content lives both on the web and in the app, make sure you set its canonical URL + // (i.e. the URL of this piece of content on the web) when building any BUO. + // By doing so, we’ll attribute clicks on the links that you generate back to their original web page, + // even if the user goes to the app instead of your website! This will help your SEO efforts. + // canonicalUrl: 'https://flutter.dev', + title: 'GSF', + imageUrl: imageURL, + contentDescription: 'View on GSF now', + /* + contentMetadata: BranchContentMetaData() + ..addCustomMetadata('custom_string', 'abc') + ..addCustomMetadata('custom_number', 12345) + ..addCustomMetadata('custom_bool', true) + ..addCustomMetadata('custom_list_number', [1, 2, 3, 4, 5]) + ..addCustomMetadata('custom_list_string', ['a', 'b', 'c']), + */ + contentMetadata: metadata, + keywords: ['Plugin', 'Branch', 'Flutter'], + publiclyIndex: true, + locallyIndex: true, + expirationDateInMilliSec: DateTime.now() + .add(const Duration(days: 365)) + .millisecondsSinceEpoch); + + lp = BranchLinkProperties( + channel: 'facebook', + feature: 'sharing', + //parameter alias + //Instead of our standard encoded short url, you can specify the vanity alias. + // For example, instead of a random string of characters/integers, you can set the vanity alias as *.app.link/devonaustin. + // Aliases are enforced to be unique** and immutable per domain, and per link - they cannot be reused unless deleted. + //alias: 'https://branch.io' //define link url, + stage: 'new share', + campaign: 'campaign', + tags: ['one', 'two', 'three']) + ..addControlParam('\$uri_redirect_mode', '1') + ..addControlParam('\$ios_nativelink', true) + ..addControlParam('\$match_duration', 7200) + ..addControlParam('\$always_deeplink', true) + ..addControlParam('\$android_redirect_timeout', 750) + ..addControlParam('referring_user_id', 'user_id'); + + // eventStandard = BranchEvent.standardEvent(BranchStandardEvent.ADD_TO_CART) + // //--optional Event data + // ..transactionID = '12344555' + // ..currency = BranchCurrencyType.BRL + // ..revenue = 1.5 + // ..shipping = 10.2 + // ..tax = 12.3 + // ..coupon = 'test_coupon' + // ..affiliation = 'test_affiliation' + // ..eventDescription = 'Event_description' + // ..searchQuery = 'item 123' + // ..adType = BranchEventAdType.BANNER + // ..addCustomData( + // 'Custom_Event_Property_Key1', 'Custom_Event_Property_val1') + // ..addCustomData( + // 'Custom_Event_Property_Key2', 'Custom_Event_Property_val2'); + + // eventCustom = BranchEvent.customEvent('Custom_event') + // ..addCustomData( + // 'Custom_Event_Property_Key1', 'Custom_Event_Property_val1') + // ..addCustomData( + // 'Custom_Event_Property_Key2', 'Custom_Event_Property_val2'); + } + + Future generateLink(BuildContext context) async { + BranchResponse response = + await FlutterBranchSdk.getShortUrl(buo: buo!, linkProperties: lp); + if (response.success) { + if (context.mounted) { + //showGeneratedLink(context, response.result); + // shareLink(); + print("Link is ${response.result}"); + } + return response.result.toString(); + } else { + await Flushbar( + // title: 'Hey Ninja', + message: 'Error : ${response.errorCode} - ${response.errorMessage}', + duration: const Duration(seconds: 2), + ).show(context); + return "Error"; + } + } + + late ShortClipLikesModel shortClipLikesModel; + sortLikes( + ShortClipModel shortClipModel, + ) { + try { + // print('shortClipLikesModel ${shortClipLikesModel.isLiked}'); + shortClipLikesModel = widget.fetchedLikes.singleWhere( + (likesModel) => likesModel.shortClipId == shortClipModel.id); + debugPrint("shortClipLikesModelisLiked ${shortClipLikesModel.isLiked}"); + } catch (e) { + shortClipLikesModel = ShortClipLikesModel( + shortClipId: shortClipModel.id, + isLiked: false, + ); + widget.fetchedLikes.add(shortClipLikesModel); + } + } + + bool _isonce = true; + callSetstateOnce() { + if (_isonce) { + Future.delayed(const Duration(milliseconds: 500), () { + setState(() { + _isonce = false; + }); + }); + } + } + + @override + Widget build(BuildContext context) { + return Theme( + data: ThemeData( + iconTheme: const IconThemeData(color: Colors.white), + scaffoldBackgroundColor: + (Theme.of(context).brightness != Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + child: DefaultTextStyle( + style: const TextStyle(color: Colors.white), + child: PageView.builder( + controller: pageController, + itemCount: controllers.length, + scrollDirection: Axis.vertical, + onPageChanged: (index) { + //on swipe up + if (index > prevPgIndex) { + controllers[index - 1] + ..pause() + ..seekTo(Duration.zero); + controllers[index].play(); + if (index + 1 < controllers.length) { + controllers[index + 1].initialize(); + } + if (index + 2 < controllers.length) { + controllers[index + 2].initialize(); + } + } + + //on swipe down + if (index < prevPgIndex) { + controllers[index + 1] + ..pause() + ..seekTo(Duration.zero); + controllers[index].play(); + if (index - 1 >= 0) { + controllers[index - 1].initialize(); + } + if (index - 2 >= 0) { + controllers[index - 2].initialize(); + } + } + + prevPgIndex = index; + }, + itemBuilder: (context, index) { + // Is at end and isLoading + // final bool _isLoading = + // (state.isLoading && index == state.urls.length - 1); + + ShortClipModel shortClipModel = widget.fetchedClips[index]; + sortLikes(shortClipModel); + callSetstateOnce(); + // VideoPage.currentController = state.controllers[index]; + + // if (state.controllers[index]!.value.isPlaying) { + // state.controllers[index]!.setVolume(1); + // } + // VideoPage.videoControllers.add(state.controllers[index]!); + + return Stack( + children: [ + VideoPlayer(controllers[index]), + //like & share + likeAndShare(shortClipModel, index), + //title & description + titleAndDescription(shortClipModel) + ], + ); + }, + ), + ), + ); + } + + Widget likeAndShare(ShortClipModel shortClipModel, index) { + return Positioned( + top: 32, + right: 6, + child: Column( + children: [ + //share + StatefulBuilder( + builder: (context, setShareBtnState) { + return Column( + children: [ + if (!showShareBtnLoader) + FloatingActionButton.small( + heroTag: "btn1", + elevation: 0, + backgroundColor: const Color.fromARGB(100, 0, 0, 0), + onPressed: () { + // podPlayerController.pause(); + setShareBtnState(() => showShareBtnLoader = true); + initDeepLinkData(index); + generateLink( + context, + // shortClipModel + // .videoUrl + ).then((value) => setShareBtnState(() { + showShareBtnLoader = false; + Share.shareWithResult( + value, + subject: shortClipModel.title, + ).then((value) { + // podPlayerController.play() + }); + })); + }, + child: const Padding( + padding: EdgeInsets.only(right: 2), + child: Icon(Icons.share_outlined), + ), + ), + if (showShareBtnLoader) + const FloatingActionButton.small( + heroTag: "btn2", + elevation: 0, + backgroundColor: Color.fromARGB(100, 0, 0, 0), + onPressed: null, + child: Padding( + padding: EdgeInsets.only(right: 2), + child: SizedBox( + width: 21, + height: 21, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2.8, + ), + ), + ), + ), + ], + ); + }, + ), + const SizedBox(height: 6), + + //like + StatefulBuilder(builder: (context, setLikeBtnSet) { + // print( + // 'showLikeBtnLoader ${showLikeBtnLoader}'); + // print( + // 'shortClipModellikes ${shortClipModel.likes}'); + return Column( + children: [ + if (!showLikeBtnLoader) + FloatingActionButton.small( + heroTag: "btn3", + elevation: 0, + backgroundColor: const Color.fromARGB(100, 0, 0, 0), + onPressed: () { + setLikeBtnSet(() { + showLikeBtnLoader = true; + }); + ShortClipService() + .likeOrUnlikeClip(shortClipModel.id) + .then((isLiked) { + print('isLiked only $isLiked'); + setLikeBtnSet(() { + shortClipLikesModel.isLiked = isLiked; + // print('isLikedOnly ${isLiked}'); + isLiked + ? shortClipModel.likes++ + : shortClipModel.likes--; + showLikeBtnLoader = false; + }); + }); + }, + child: Icon(shortClipLikesModel.isLiked + ? Icons.thumb_up + : Icons.thumb_up_outlined), + ), + if (showLikeBtnLoader) + const FloatingActionButton.small( + heroTag: "btn4", + elevation: 0, + backgroundColor: Color.fromARGB(100, 0, 0, 0), + onPressed: null, + child: Padding( + padding: EdgeInsets.only(right: 2), + child: SizedBox( + width: 21, + height: 21, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2.8, + ), + ), + ), + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 2, + ), + decoration: BoxDecoration( + color: const Color.fromARGB(100, 0, 0, 0), + borderRadius: BorderRadius.circular(4), + ), + child: Text(shortClipModel.likes.toString()), + ), + ], + ); + }) + ], + ), + ); + } + + Widget titleAndDescription(ShortClipModel shortClipModel) { + return Positioned( + bottom: 38, + child: Container( + width: Get.size.width, + color: const Color.fromARGB(100, 0, 0, 0), + padding: const EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //title + Text( + shortClipModel.title, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + const SizedBox(height: 8), + + //description + StatefulBuilder( + builder: (context, setDescState) { + return SizedBox( + width: MediaQuery.of(context).size.width, + child: InkWell( + child: Text( + shortClipModel.description, + maxLines: showFullDesc ? 30 : 2, + textAlign: TextAlign.justify, + style: const TextStyle( + fontSize: 16, + overflow: TextOverflow.ellipsis, + ), + ), + onTap: () { + setDescState(() { + showFullDesc = !showFullDesc; + }); + }, + ), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/short_video_player/svp_main.dart b/gsf/lib/views/short_video_player/svp_main.dart new file mode 100644 index 0000000..7697ad4 --- /dev/null +++ b/gsf/lib/views/short_video_player/svp_main.dart @@ -0,0 +1,644 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:another_flushbar/flushbar.dart'; +// import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_branch_sdk/flutter_branch_sdk.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:gsp_app/repository/services/short_clip_service.dart'; +import 'package:gsp_app/views/pages/splash.dart'; +import 'package:gsp_app/views/short_video_player/sv_player.dart'; +import 'package:gsp_app/views/short_video_player/svp_lib/service/api_service.dart'; +import 'package:gsp_app/views/short_video_player/svp_lib/video_page.dart'; +import 'package:pod_player/pod_player.dart'; +// import 'package:pod_player_new/pod_player_new.dart'; +import 'package:share_plus/share_plus.dart'; + +import '../components/appbar.dart'; +import '../../modals/short_clip_likes_model.dart'; +import '../../modals/short_clip_model.dart'; +import 'package:async/async.dart'; + +import '../theme.dart'; +import 'svp_lib/core/constants.dart'; + +class SvpMain extends StatefulWidget { + SvpMain({ + required this.index, + required this.fromHome, + // required this.clips, + // required this.clipLikesModel, + Key? key, + }) : super(key: key); + + // final List clips; + // final List clipLikesModel; + final int index; + bool fromHome; + + @override + State createState() => _SvpMain(); +} + +class _SvpMain extends State { + bool showFullDesc = false; + bool showLikeBtnLoader = false; + bool showShareBtnLoader = false; + late PageController pageController = + PageController(initialPage: widget.index); + + FutureGroup fetchClipsAndLikes = FutureGroup(); + BranchContentMetaData metadata = BranchContentMetaData(); + BranchUniversalObject? buo; + BranchLinkProperties lp = BranchLinkProperties(); + BranchEvent? eventStandard; + BranchEvent? eventCustom; + static const imageURL = + 'https://raw.githubusercontent.com/RodrigoSMarques/flutter_branch_sdk/master/assets/branch_logo_qrcode.jpeg'; + + // Future generateShareLink(int index, String videoUrl) async { + // final dynamicLinkParams = DynamicLinkParameters( + // link: Uri.parse("https://gsfbeta.page.link/tobR?clipIndex=$index"), + // uriPrefix: "https://gsfbeta.page.link/", + // longDynamicLink: Uri.parse( + // "https://gsfbeta.page.link/tobR?link=$videoUrl?clipIndex=$index&apn=com.getsetfit.gsf"), + // androidParameters: + // const AndroidParameters(packageName: "com.getsetfit.gsf"), + // iosParameters: const IOSParameters(bundleId: '') + // // iosParameters: const IOSParameters(bundleId: "com.example.app.ios"), + // ); + // final dynamicLink = + // await FirebaseDynamicLinks.instance.buildLink(dynamicLinkParams); + // return dynamicLink.toString(); + // } + + void initDeepLinkData(int index) { + metadata = BranchContentMetaData() + // ..addCustomMetadata('custom_string', 'gsf product title') + ..addCustomMetadata('custom_number', index.toString()); + // ..addCustomMetadata('custom_bool', true) + // ..addCustomMetadata('custom_list_number', [1, 2, 3, 4, 5]) + // ..addCustomMetadata('custom_list_string', ['a', 'b', 'c']); + //--optional Custom Metadata + // ..contentSchema = BranchContentSchema.COMMERCE_PRODUCT + // ..price = 50.99 + // ..currencyType = BranchCurrencyType.BRL + // ..quantity = 50 + // ..sku = 'sku' + // ..productName = 'productName' + // ..productBrand = 'productBrand' + // ..productCategory = BranchProductCategory.ELECTRONICS + // ..productVariant = 'productVariant' + // ..condition = BranchCondition.NEW + // ..rating = 100 + // ..ratingAverage = 50 + // ..ratingMax = 100 + // ..ratingCount = 2 + // ..setAddress( + // street: 'street', + // city: 'city', + // region: 'ES', + // country: 'Brazil', + // postalCode: '99999-987') + // ..setLocation(31.4521685, -114.7352207); + + buo = BranchUniversalObject( + canonicalIdentifier: 'flutter/branch', + //parameter canonicalUrl + //If your content lives both on the web and in the app, make sure you set its canonical URL + // (i.e. the URL of this piece of content on the web) when building any BUO. + // By doing so, we’ll attribute clicks on the links that you generate back to their original web page, + // even if the user goes to the app instead of your website! This will help your SEO efforts. + // canonicalUrl: 'https://flutter.dev', + title: 'GSF', + imageUrl: imageURL, + contentDescription: 'View on GSF now', + /* + contentMetadata: BranchContentMetaData() + ..addCustomMetadata('custom_string', 'abc') + ..addCustomMetadata('custom_number', 12345) + ..addCustomMetadata('custom_bool', true) + ..addCustomMetadata('custom_list_number', [1, 2, 3, 4, 5]) + ..addCustomMetadata('custom_list_string', ['a', 'b', 'c']), + */ + contentMetadata: metadata, + keywords: ['Plugin', 'Branch', 'Flutter'], + publiclyIndex: true, + locallyIndex: true, + expirationDateInMilliSec: DateTime.now() + .add(const Duration(days: 365)) + .millisecondsSinceEpoch); + + lp = BranchLinkProperties( + channel: 'facebook', + feature: 'sharing', + //parameter alias + //Instead of our standard encoded short url, you can specify the vanity alias. + // For example, instead of a random string of characters/integers, you can set the vanity alias as *.app.link/devonaustin. + // Aliases are enforced to be unique** and immutable per domain, and per link - they cannot be reused unless deleted. + //alias: 'https://branch.io' //define link url, + stage: 'new share', + campaign: 'campaign', + tags: ['one', 'two', 'three']) + ..addControlParam('\$uri_redirect_mode', '1') + ..addControlParam('\$ios_nativelink', true) + ..addControlParam('\$match_duration', 7200) + ..addControlParam('\$always_deeplink', true) + ..addControlParam('\$android_redirect_timeout', 750) + ..addControlParam('referring_user_id', 'user_id'); + + // eventStandard = BranchEvent.standardEvent(BranchStandardEvent.ADD_TO_CART) + // //--optional Event data + // ..transactionID = '12344555' + // ..currency = BranchCurrencyType.BRL + // ..revenue = 1.5 + // ..shipping = 10.2 + // ..tax = 12.3 + // ..coupon = 'test_coupon' + // ..affiliation = 'test_affiliation' + // ..eventDescription = 'Event_description' + // ..searchQuery = 'item 123' + // ..adType = BranchEventAdType.BANNER + // ..addCustomData( + // 'Custom_Event_Property_Key1', 'Custom_Event_Property_val1') + // ..addCustomData( + // 'Custom_Event_Property_Key2', 'Custom_Event_Property_val2'); + + // eventCustom = BranchEvent.customEvent('Custom_event') + // ..addCustomData( + // 'Custom_Event_Property_Key1', 'Custom_Event_Property_val1') + // ..addCustomData( + // 'Custom_Event_Property_Key2', 'Custom_Event_Property_val2'); + } + + Future generateLink(BuildContext context) async { + BranchResponse response = + await FlutterBranchSdk.getShortUrl(buo: buo!, linkProperties: lp); + if (response.success) { + if (context.mounted) { + //showGeneratedLink(context, response.result); + // shareLink(); + print("Link is ${response.result}"); + } + return response.result.toString(); + } else { + await Flushbar( + // title: 'Hey Ninja', + message: 'Error : ${response.errorCode} - ${response.errorMessage}', + duration: const Duration(seconds: 2), + ).show(context); + return "Error"; + } + } + + // initializePlayerController(ShortClipModel shortClipModel) { + // podPlayerController = PodPlayerController( + // playVideoFrom: PlayVideoFrom.vimeo(shortClipModel.videoUrl), + // podPlayerConfig: const PodPlayerConfig( + // autoPlay: true, + // isLooping: false, + // ), + // ) + // ..initialise() + // ..disableFullScreen(context); + // } + + // //Initialize Video Player + // void initializePlayer(ShortClipModel shortClipModel) async { + // final fileInfo = + // await DefaultCacheManager().getFileFromCache(shortClipModel.videoUrl); + // if (fileInfo == null) { + // podPlayerController = PodPlayerController( + // playVideoFrom: PlayVideoFrom.network(shortClipModel.videoUrl), + // podPlayerConfig: const PodPlayerConfig( + // autoPlay: true, + // isLooping: true, + // ), + // ) + // ..initialise().then((value) { + // setState(() { + // podPlayerController.play(); + // }); + // storeUrlInCache(shortClipModel.videoUrl); + // }) + // ..disableFullScreen(context); + // } else { + // final file = fileInfo.file; + // podPlayerController = PodPlayerController( + // playVideoFrom: PlayVideoFrom.file(file), + // podPlayerConfig: const PodPlayerConfig( + // autoPlay: true, + // isLooping: true, + // ), + // ) + // ..initialise().then((value) { + // setState(() { + // podPlayerController.play(); + // }); + // }) + // ..disableFullScreen(context); + // } + // } + + // //:cached Url Data + // storeUrlInCache(String url) async { + // await DefaultCacheManager().getSingleFile(url).then((value) { + // print('downloaded successfully done for $url'); + // }); + // } + + late ShortClipLikesModel shortClipLikesModel; + sortLikes( + ShortClipModel shortClipModel, List fetchedLikes) { + try { + // print('shortClipLikesModel ${shortClipLikesModel.isLiked}'); + shortClipLikesModel = fetchedLikes.singleWhere( + (likesModel) => likesModel.shortClipId == shortClipModel.id); + debugPrint("shortClipLikesModelisLiked ${shortClipLikesModel.isLiked}"); + } catch (e) { + shortClipLikesModel = ShortClipLikesModel( + shortClipId: shortClipModel.id, + isLiked: false, + ); + fetchedLikes.add(shortClipLikesModel); + } + } + + bool _isonce = true; + callSetstateOnce() { + if (_isonce) { + Future.delayed(const Duration(milliseconds: 500), () { + setState(() { + _isonce = false; + }); + }); + } + } + + List videoPlayerControllers = []; + + @override + void initState() { + videoPlayerControllers = ShortClipTemp.tempClips + .map((e) => VideoPlayerController.contentUri(Uri.parse(e.videoUrl))) + .toList(); + videoPlayerControllers[widget.index] + ..initialize() + ..setLooping(true) + ..play(); + if (widget.index + 1 < videoPlayerControllers.length) { + videoPlayerControllers[widget.index + 1] + ..initialize() + ..setLooping(true); + } + if (widget.index - 1 >= 0) { + videoPlayerControllers[widget.index - 1] + ..initialize() + ..setLooping(true); + } + super.initState(); + } + + int prevPgIndex = 0; + + @override + void dispose() { + for (final ctrl in videoPlayerControllers) { + ctrl.dispose(); + } + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () { + for (final ctrl in videoPlayerControllers) { + ctrl.dispose(); + } + return Future.value(true); + }, + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(50), + child: CustomAppBars( + fromHome: widget.fromHome, + backgroundColor: Theme.of(context).appBarTheme.backgroundColor, + titleHead: "Bites", + ), + ), + body: Builder(builder: (context) { + List fetchedClips = ShortClipTemp.tempClips; + List fetchedLikes = ShortClipTemp.tempclipLikes; + + int videoIndex = widget.index; + + //update bloc videos + ApiService.videos = + fetchedClips.sublist(videoIndex).map((e) => e.videoUrl).toList(); + kNextLimit = ApiService.videos.length; + + List myLikes = []; + for (ShortClipLikesModel like in fetchedLikes) { + myLikes.add(like); + } + for (ShortClipModel clip + in fetchedClips.sublist(fetchedLikes.length)) { + myLikes + .add(ShortClipLikesModel(shortClipId: clip.id, isLiked: false)); + } + + // return VideoPage( + // fetchedClips: fetchedClips, + // fetchedLikes: myLikes, + // index: widget.index, + // ); + + return SafeArea( + child: Theme( + data: ThemeData( + iconTheme: const IconThemeData(color: Colors.white), + scaffoldBackgroundColor: + (Theme.of(context).brightness != Brightness.light) + ? ColorConstants.kBlack + : ColorConstants.kWhite, + ), + child: DefaultTextStyle( + style: const TextStyle(color: Colors.white), + child: PageView.builder( + controller: pageController, + scrollDirection: Axis.vertical, + itemCount: fetchedClips.length, + onPageChanged: (index) { + //on swipe up (NEXT) + if (index > prevPgIndex) { + if (index - 2 >= 0) { + videoPlayerControllers[index - 2].dispose(); + } + + videoPlayerControllers[index - 1] + ..pause() + ..seekTo(Duration.zero); + + videoPlayerControllers[index].play(); + + if (index + 1 < videoPlayerControllers.length) { + videoPlayerControllers[index + 1] = + VideoPlayerController.networkUrl(Uri.parse( + ShortClipTemp.tempClips[index + 1].videoUrl)); + videoPlayerControllers[index + 1] + ..initialize() + ..setLooping(true); + } + } + + //on swipe down (PREV) + if (index < prevPgIndex) { + if (index - 1 >= 0) { + videoPlayerControllers[index - 1] = + VideoPlayerController.networkUrl(Uri.parse( + ShortClipTemp.tempClips[index - 1].videoUrl)); + videoPlayerControllers[index - 1] + ..initialize() + ..setLooping(true); + } + + videoPlayerControllers[index + 1] + ..pause() + ..seekTo(Duration.zero); + + videoPlayerControllers[index].play(); + + if (index + 2 < videoPlayerControllers.length) { + videoPlayerControllers[index + 2].dispose(); + } + } + + prevPgIndex = index; + }, + + // itemBuilder: (context, index) { + // return VideoPlayer(videoPlayerControllers[index]); + // } + + itemBuilder: (context, index) { + ShortClipModel shortClipModel = fetchedClips[index]; + sortLikes(shortClipModel, fetchedLikes); + // initializePlayer(shortClipModel); + callSetstateOnce(); + return Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + // SvPlayer( + // //podPlayerController: podPlayerController, + // pageController: pageController, + // videoUrl: shortClipModel.videoUrl, + // currentPageIndex: index, + // pagesCount: fetchedClips.length, + // ), + VideoPlayer(videoPlayerControllers[index]), + + //like & share + likeAndShare(shortClipModel, index), + //title & description + titleAndDescription( + shortClipModel, + ) + ], + ); + }, + )), + ), + ); + }), + ), + ); + } + + Widget likeAndShare(ShortClipModel shortClipModel, index) { + return Positioned( + top: 32, + right: 6, + child: Column( + children: [ + //share + StatefulBuilder( + builder: (context, setShareBtnState) { + return Column( + children: [ + if (!showShareBtnLoader) + FloatingActionButton.small( + heroTag: "btn1", + elevation: 0, + backgroundColor: const Color.fromARGB(100, 0, 0, 0), + onPressed: () { + // podPlayerController.pause(); + setShareBtnState(() => showShareBtnLoader = true); + initDeepLinkData(index); + generateLink( + context, + // shortClipModel + // .videoUrl + ).then((value) => setShareBtnState(() { + showShareBtnLoader = false; + Share.shareWithResult( + value, + subject: shortClipModel.title, + ).then((value) { + // podPlayerController.play() + }); + })); + }, + child: const Padding( + padding: EdgeInsets.only(right: 2), + child: Icon(Icons.share_outlined), + ), + ), + if (showShareBtnLoader) + const FloatingActionButton.small( + heroTag: "btn2", + elevation: 0, + backgroundColor: Color.fromARGB(100, 0, 0, 0), + onPressed: null, + child: Padding( + padding: EdgeInsets.only(right: 2), + child: SizedBox( + width: 21, + height: 21, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2.8, + ), + ), + ), + ), + ], + ); + }, + ), + const SizedBox(height: 6), + + //like + StatefulBuilder(builder: (context, setLikeBtnSet) { + // print( + // 'showLikeBtnLoader ${showLikeBtnLoader}'); + // print( + // 'shortClipModellikes ${shortClipModel.likes}'); + return Column( + children: [ + if (!showLikeBtnLoader) + FloatingActionButton.small( + heroTag: "btn3", + elevation: 0, + backgroundColor: const Color.fromARGB(100, 0, 0, 0), + onPressed: () { + setLikeBtnSet(() { + showLikeBtnLoader = true; + }); + ShortClipService() + .likeOrUnlikeClip(shortClipModel.id) + .then((isLiked) { + print('isLiked only $isLiked'); + setLikeBtnSet(() { + shortClipLikesModel.isLiked = isLiked; + // print('isLikedOnly ${isLiked}'); + isLiked + ? shortClipModel.likes++ + : shortClipModel.likes--; + showLikeBtnLoader = false; + }); + }); + }, + child: Icon(shortClipLikesModel.isLiked + ? Icons.thumb_up + : Icons.thumb_up_outlined), + ), + if (showLikeBtnLoader) + const FloatingActionButton.small( + heroTag: "btn4", + elevation: 0, + backgroundColor: Color.fromARGB(100, 0, 0, 0), + onPressed: null, + child: Padding( + padding: EdgeInsets.only(right: 2), + child: SizedBox( + width: 21, + height: 21, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2.8, + ), + ), + ), + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 2, + ), + decoration: BoxDecoration( + color: const Color.fromARGB(100, 0, 0, 0), + borderRadius: BorderRadius.circular(4), + ), + child: Text(shortClipModel.likes.toString()), + ), + ], + ); + }) + ], + ), + ); + } + + Widget titleAndDescription( + ShortClipModel shortClipModel, + ) { + return Positioned( + bottom: 38, + child: Container( + width: Get.size.width, + color: const Color.fromARGB(100, 0, 0, 0), + padding: const EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //title + Text( + shortClipModel.title, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + const SizedBox(height: 8), + + //description + StatefulBuilder( + builder: (context, setDescState) { + return SizedBox( + width: MediaQuery.of(context).size.width, + child: InkWell( + child: Text( + shortClipModel.description, + maxLines: showFullDesc ? 30 : 2, + textAlign: TextAlign.justify, + style: const TextStyle( + fontSize: 16, + overflow: TextOverflow.ellipsis, + ), + ), + onTap: () { + setDescState(() { + showFullDesc = !showFullDesc; + }); + }, + ), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/gsf/lib/views/theme.dart b/gsf/lib/views/theme.dart new file mode 100644 index 0000000..63ce7fb --- /dev/null +++ b/gsf/lib/views/theme.dart @@ -0,0 +1,154 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; + +class ThemseServices { + final box = GetStorage(); + final key = 'isDarkMode'; + + saveThemeToBox(bool isDarkMode) => box.write(key, isDarkMode); + + bool loadThemeFromBox() => box.read(key) ?? true; + ThemeMode get theme => loadThemeFromBox() ? ThemeMode.dark : ThemeMode.light; + void switchTheme() { + Get.changeThemeMode(loadThemeFromBox() ? ThemeMode.light : ThemeMode.dark); + saveThemeToBox(!loadThemeFromBox()); + } +} + +class ColorConstants { + static const kPrimaryColor = Color(0xFFBBF046); + static const kWhite = Color(0xFFffffff); + static const kBlack = Color(0xFF000000); + static const kErroColor = Color(0xFFE90000); + + static const periodsColor = Color(0xFFE24747); +} + +abstract class AppColors { + static const kPrimaryColor = Color(0xFFBBF046); + static const kWhite = Color(0xFFffffff); + static const kBlack = Color(0xFF000000); + static const kErroColor = Color(0xFFE90000); + + static const primary = Color(0xffCC9900); + static const secondary = Color(0xFFF40000); + // static const accent = Color(0xFFD6755B); + static const textDark = Color(0xFF000000); + static const textLigth = Color(0xFFffffff); + // static const textFaded = Color(0xFF9899A5); + static const iconLight = Color(0xFF000000); + static const iconDark = textLigth; + static const textHighlight = secondary; + static const cardLight = Color(0xFFF9FAFE); + static const cardDark = Color(0xFF303334); +} + +abstract class _LightColors { + static const background = Color(0xffffffff); + // static const card = background; +} + +abstract class _DarkColors { + static const background = Color(0xFF000000); + static const card = AppColors.cardDark; +} + +/// Reference to the application theme. +abstract class AppTheme { + // static const accentColor = AppColors.accent; + static final visualDensity = VisualDensity.adaptivePlatformDensity; + + /// Light theme and its settings. + static ThemeData light() => ThemeData( + appBarTheme: const AppBarTheme( + backgroundColor: ColorConstants.kWhite, + // backgroundColor: Colors.transparent, + // elevation: 0, + ), + bottomNavigationBarTheme: const BottomNavigationBarThemeData( + backgroundColor: ColorConstants.kWhite, + ), + brightness: Brightness.light, + fontFamily: 'SFPRO', + // accentColor: accentColor, + visualDensity: visualDensity, + // iconTheme: IconThemeData( + // color: Colors.black + // ), + // backgroundColor: const Color(0xffffffff), + // textTheme:GoogleFonts.mulishTextTheme().apply(bodyColor: AppColors.textDark), + // textTheme: TextTheme( + // headline1: + // const TextStyle(fontSize: 28.0).apply(color: AppColors.textDark), + // ), + drawerTheme: DrawerThemeData( + backgroundColor: Colors.white, + ), + scaffoldBackgroundColor: _LightColors.background, + // cardColor: _LightColors.card, + primaryColor: Colors.red, + primaryTextTheme: const TextTheme( + titleLarge: TextStyle(color: AppColors.textDark), + ), + iconTheme: const IconThemeData(color: AppColors.iconLight), + colorScheme: const ColorScheme.light() + .copyWith(background: _LightColors.background), + ); + + /// Dark theme and its settings. + static ThemeData dark() => ThemeData( + appBarTheme: + AppBarTheme(backgroundColor: Color.fromARGB(255, 16, 16, 16)), + brightness: Brightness.dark, + fontFamily: 'SFPRO', + // accentColor: accentColor, + visualDensity: visualDensity, + bottomNavigationBarTheme: const BottomNavigationBarThemeData( + backgroundColor: Color(0xff1C1B1B), + ), + // iconTheme: IconThemeData( + // color: Colors.white + // ), + + // textTheme: GoogleFonts.interTextTheme().apply(bodyColor: AppColors.textLigth), + // backgroundColor: _DarkColors.background, + drawerTheme: DrawerThemeData( + backgroundColor: const Color(0xff212121), + ), + colorScheme: const ColorScheme.dark(), + scaffoldBackgroundColor: _DarkColors.background, + cardColor: _DarkColors.card, + primaryColor: const Color(0xff000000), + primaryTextTheme: const TextTheme( + titleLarge: TextStyle(color: AppColors.textLigth), + ), + iconTheme: const IconThemeData(color: AppColors.iconDark), + ); +} + +// theme end=============== + +class QuizTextStyles { + // static final brightness = Get.theme.brightness; + static TextStyle heading = TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w400, + color: ColorConstants.kWhite, + fontSize: 17, + ); + static const TextStyle body = TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w300, + color: Color(0xFFD9D9D9), + fontSize: 14, + ); + static const TextStyle label = TextStyle( + fontFamily: "SFPRO", + fontWeight: FontWeight.w700, + color: Color(0xFFBBF046), + fontSize: 17, + ); +} diff --git a/gsf/pubspec.lock b/gsf/pubspec.lock new file mode 100644 index 0000000..3d3c508 --- /dev/null +++ b/gsf/pubspec.lock @@ -0,0 +1,2033 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "4826f97faae3af9761f26c52e56b2aa5ffd18d2c1721d984ad85137721c25f43" + url: "https://pub.dev" + source: hosted + version: "31.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "8942974ee5dc932427704ede5e0db8b5f2b8f22172964544b56e6bd37f6c3634" + url: "https://pub.dev" + source: hosted + version: "1.3.12" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "7337610c3f9cd13e6b7c6bb0f410644091cf63c9a1436e73352a70f3286abb03" + url: "https://pub.dev" + source: hosted + version: "2.8.0" + animated_horizontal_calendar: + dependency: "direct main" + description: + name: animated_horizontal_calendar + sha256: dd9606d6e83e796ee4e2eb933b12a7340a3fe0b4058d2938cc2c82d20bf303d3 + url: "https://pub.dev" + source: hosted + version: "0.0.3" + animations: + dependency: "direct main" + description: + name: animations + sha256: fe8a6bdca435f718bb1dc8a11661b2c22504c6da40ef934cee8327ed77934164 + url: "https://pub.dev" + source: hosted + version: "2.0.7" + another_flushbar: + dependency: "direct main" + description: + name: another_flushbar + sha256: "19bf9520230ec40b300aaf9dd2a8fefcb277b25ecd1c4838f530566965befc2a" + url: "https://pub.dev" + source: hosted + version: "1.12.30" + archive: + dependency: transitive + description: + name: archive + sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" + url: "https://pub.dev" + source: hosted + version: "3.3.7" + args: + dependency: transitive + description: + name: args + sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + audio_session: + dependency: transitive + description: + name: audio_session + sha256: e4acc4e9eaa32436dfc5d7aed7f0a370f2d7bb27ee27de30d6c4f220c2a05c73 + url: "https://pub.dev" + source: hosted + version: "0.1.13" + audio_video_progress_bar: + dependency: "direct main" + description: + name: audio_video_progress_bar + sha256: "67f3a5ea70d48b48caaf29f5a0606284a6aa3a393736daf9e82bec985d2f9b70" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + audioplayers: + dependency: "direct main" + description: + name: audioplayers + sha256: bb506873ab4fb663db9b47243754ef669adf684dbe6ba8b57c26e27b834065c4 + url: "https://pub.dev" + source: hosted + version: "1.2.0" + audioplayers_android: + dependency: transitive + description: + name: audioplayers_android + sha256: "53969a1c5d94ebdaef72e334f1c0ea2f3946ab2baa8d398a9584ac27baf4f037" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + audioplayers_darwin: + dependency: transitive + description: + name: audioplayers_darwin + sha256: dcd5a4ceef5aa3d04e8ae49441f13a3d9f93fe6e9e88fe121ff6b6f391b2a40b + url: "https://pub.dev" + source: hosted + version: "1.0.4" + audioplayers_linux: + dependency: transitive + description: + name: audioplayers_linux + sha256: ea1cb9a5c9389b38f293ee1375b22b02fb1d1f7a2e1517fcb674297dd074dc7b + url: "https://pub.dev" + source: hosted + version: "1.0.2" + audioplayers_platform_interface: + dependency: transitive + description: + name: audioplayers_platform_interface + sha256: "589c3106d0c656540e81ac2c7a78a9414a4a6534ae7b77f06ddb5d6aa5dc653c" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + audioplayers_web: + dependency: transitive + description: + name: audioplayers_web + sha256: "13fb044a443276223774f8ed1f8d2b82f443cf8980edd0e172e55967c1556a49" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: "87964ddece7275b97277935df67af60536155914c81c633f708914b99433129b" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + blobs: + dependency: "direct main" + description: + name: blobs + sha256: "7fb3f0d9928e73c646d5ad418a6755eae825a5572f1334f3c3a7d74fd471e9c3" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + bloc: + dependency: transitive + description: + name: bloc + sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e + url: "https://pub.dev" + source: hosted + version: "8.1.3" + bluetooth_enable_fork: + dependency: "direct main" + description: + name: bluetooth_enable_fork + sha256: d53d588600356bcba6168e011a40b26d482f6b00dd08ce986cbaa6bb1e6d5068 + url: "https://pub.dev" + source: hosted + version: "0.1.6" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: de3ecca84980ee5e632888a04f4a72d8e3c390104fd5edb3a724785f66e9e97a + url: "https://pub.dev" + source: hosted + version: "2.0.3" + build_config: + dependency: transitive + description: + name: build_config + sha256: "9160104f468c8117f7dddd3c94d8f440d0f82a324bf29eb84e0b434cff7a0e03" + url: "https://pub.dev" + source: hosted + version: "0.4.7" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "02d9e94f2b7f6e4de0f0cd24dc9e2cd0c00fec082265ca89d3b32282cb7381bc" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "4666aef1d045c5ca15ebba63e400bd4e4fbd9f0dd06e791b51ab210da78a27f7" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + build_runner: + dependency: transitive + description: + name: build_runner + sha256: cd95f4d4a6a13b0dc1408b0a4b086bffdac08dcb61e45a0e1f2f58905d4c97a5 + url: "https://pub.dev" + source: hosted + version: "1.12.2" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "653b9dfd0472476ca837ef62786717434b8fa4f5e5521c85d7376dd3234aefeb" + url: "https://pub.dev" + source: hosted + version: "6.1.12" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0" + url: "https://pub.dev" + source: hosted + version: "8.4.4" + carousel_slider: + dependency: "direct main" + description: + name: carousel_slider + sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" + url: "https://pub.dev" + source: hosted + version: "4.2.1" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + charcode: + dependency: transitive + description: + name: charcode + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + url: "https://pub.dev" + source: hosted + version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + circular_countdown_timer: + dependency: "direct main" + description: + name: circular_countdown_timer + sha256: "9ba5fbc076cedbcbf6190ed86762e679f43d7c67cdd903ea34df059dabdc08d4" + url: "https://pub.dev" + source: hosted + version: "0.2.3" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + url: "https://pub.dev" + source: hosted + version: "0.3.5" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "48ae73ba8dbf1923de91e0fd65736148f63f6c6fb0925bdda05c1df0298c55e1" + url: "https://pub.dev" + source: hosted + version: "3.7.0" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + connectivity_plus: + dependency: "direct main" + description: + name: connectivity_plus + sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + url: "https://pub.dev" + source: hosted + version: "1.2.4" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + url: "https://pub.dev" + source: hosted + version: "0.3.3+4" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + csslib: + dependency: transitive + description: + name: csslib + sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + url: "https://pub.dev" + source: hosted + version: "0.17.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "6e8086e1d3c2f6bc15056ee248c4ddc48c2bc71287c0961bf801a08633ed4333" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + dbus: + dependency: transitive + description: + name: dbus + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" + source: hosted + version: "0.7.8" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: f52ab3b76b36ede4d135aab80194df8925b553686f0fa12226b4e2d658e45903 + url: "https://pub.dev" + source: hosted + version: "8.2.2" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 + url: "https://pub.dev" + source: hosted + version: "7.0.0" + dio: + dependency: "direct main" + description: + name: dio + sha256: ce75a1b40947fea0a0e16ce73337122a86762e38b982e1ccb909daa3b9bc4197 + url: "https://pub.dev" + source: hosted + version: "5.3.2" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: "193e97bfe9fd3d89317bddb6129653781fa9b62d99811d49f633e67ea449a62c" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" + event_bus: + dependency: "direct main" + description: + name: event_bus + sha256: "44baa799834f4c803921873e7446a2add0f3efa45e101a054b1f0ab9b95f8edc" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "45f3f9babfc6f56fb94c3cd11584cf3c9672868228373b699b94427010e01dc3" + url: "https://pub.dev" + source: hosted + version: "2.22.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0631a2ec971dbc540275e2fa00c3a8a2676f0a7adbc3c197d6fba569db689d97" + url: "https://pub.dev" + source: hosted + version: "2.8.1" + firebase_crashlytics: + dependency: "direct main" + description: + name: firebase_crashlytics + sha256: "0d09f0e17b4174d850fd26a5036d51bb1b3e09c36a35ffcdc9dfa99fdbd6e9bb" + url: "https://pub.dev" + source: hosted + version: "3.4.4" + firebase_crashlytics_platform_interface: + dependency: transitive + description: + name: firebase_crashlytics_platform_interface + sha256: "7ebb08dc5d53da3ca4122f2e84837dbfb1c3e6cc15731d5998893a5d41037a97" + url: "https://pub.dev" + source: hosted + version: "3.6.12" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "749b3342ea3e95cbf61a0fec31a62606e837377b8b6d0caa7367a7ef80f38b7d" + url: "https://pub.dev" + source: hosted + version: "0.55.2" + flick_video_player: + dependency: transitive + description: + name: flick_video_player + sha256: edd39b56b74a11a627fa560507797896af951d4b1439f4c403edbcfe10af2047 + url: "https://pub.dev" + source: hosted + version: "0.5.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_background: + dependency: "direct main" + description: + name: flutter_background + sha256: "035c31a738509d67ee70bbf174e5aa7db462c371e838ec8259700c5c4e7ca17f" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1" + url: "https://pub.dev" + source: hosted + version: "8.1.4" + flutter_blue_plus: + dependency: "direct main" + description: + name: flutter_blue_plus + sha256: "810351799eaf51c08152737615c345e9eb83e13b20adcd91ec0c78cd59dc260d" + url: "https://pub.dev" + source: hosted + version: "1.12.13" + flutter_branch_sdk: + dependency: "direct main" + description: + name: flutter_branch_sdk + sha256: "7e5a90cc252c95fbd65b11f01412a7edb1f2fd505f4253a51a93b47f53d85e33" + url: "https://pub.dev" + source: hosted + version: "6.6.0" + flutter_cache_manager: + dependency: "direct main" + description: + name: flutter_cache_manager + sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" + url: "https://pub.dev" + source: hosted + version: "3.3.1" + flutter_countdown_timer: + dependency: "direct main" + description: + name: flutter_countdown_timer + sha256: dfcbd7d6f76a5589f78f3f3ba2f9ea2e199368eccc1adce4153ce985b9587bc5 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + flutter_custom_tabs: + dependency: "direct main" + description: + name: flutter_custom_tabs + sha256: bebb9552438eb3aea8f8511d48e41abdd0d05ff3e9a74622a4d1acd2bffd242c + url: "https://pub.dev" + source: hosted + version: "1.0.4" + flutter_custom_tabs_platform_interface: + dependency: transitive + description: + name: flutter_custom_tabs_platform_interface + sha256: bbd2d9a2ff22d27e079a35302ddd3da9f2328110c370d56c81655a7ba306fee2 + url: "https://pub.dev" + source: hosted + version: "1.0.1" + flutter_custom_tabs_web: + dependency: transitive + description: + name: flutter_custom_tabs_web + sha256: d735abff9a1b215018dfe2584f131fe0a3bb0e3b685fbd6ae8a55cf5c4d7dcd8 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_html: + dependency: "direct main" + description: + name: flutter_html + sha256: "342c7908f0a67bcec62b6e0f7cf23e23bafe7f64693665dd35be98d5e783bdfd" + url: "https://pub.dev" + source: hosted + version: "3.0.0-alpha.6" + flutter_isolate: + dependency: "direct main" + description: + name: flutter_isolate + sha256: "994ddec596da4ca12ca52154fd59404077584643eb7e3f1008a55fda9fe0b76b" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + sha256: "02dcaf49d405f652b7160e882bacfc02cb497041bb2eab2a49b1c393cf9aac12" + url: "https://pub.dev" + source: hosted + version: "0.12.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + flutter_native_splash: + dependency: "direct dev" + description: + name: flutter_native_splash + sha256: af665ef80a213a9ed502845a3d7a61b9acca4100ee7e9f067a7440bc3acd6730 + url: "https://pub.dev" + source: hosted + version: "2.2.19" + flutter_pdfview: + dependency: "direct main" + description: + name: flutter_pdfview + sha256: d9735fd8991609910742a25c63a5f87060849e57e60112c677b802ddb64bed72 + url: "https://pub.dev" + source: hosted + version: "1.3.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf + url: "https://pub.dev" + source: hosted + version: "2.0.9" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" + url: "https://pub.dev" + source: hosted + version: "1.1.6" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + sha256: "2f9c4d3f4836421f7067a28f8939814597b27614e021da9d63e5d3fb6e212d25" + url: "https://pub.dev" + source: hosted + version: "8.2.1" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338 + url: "https://pub.dev" + source: hosted + version: "2.2.0" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: "5c23f3613f50586c0bbb2b8f970240ae66b3bd992088cf60dd5ee2e6f7dde3a8" + url: "https://pub.dev" + source: hosted + version: "9.0.2" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "2ba24690aee0a3e1b6b7bd47c2711a50c874e95e4c758346589d35194adf6d6a" + url: "https://pub.dev" + source: hosted + version: "4.1.7" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: "22b60ca3b8c0f58e6a9688ff855ee39ab813ca3f0c0609a48d282f6631266f2e" + url: "https://pub.dev" + source: hosted + version: "2.2.5" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: af4d69231452f9620718588f41acc4cb58312368716bfff2e92e770b46ce6386 + url: "https://pub.dev" + source: hosted + version: "4.0.7" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: f68a122da48fcfff68bbc9846bb0b74ef651afe84a1b1f6ec20939de4d6860e1 + url: "https://pub.dev" + source: hosted + version: "2.1.6" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: f5911c88e23f48b598dd506c7c19eff0e001645bdc03bb6fecb9f4549208354d + url: "https://pub.dev" + source: hosted + version: "0.1.1" + get: + dependency: "direct main" + description: + name: get + sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" + url: "https://pub.dev" + source: hosted + version: "4.6.5" + get_it: + dependency: transitive + description: + name: get_it + sha256: "529de303c739fca98cd7ece5fca500d8ff89649f1bb4b4e94fb20954abcd7468" + url: "https://pub.dev" + source: hosted + version: "7.6.0" + get_storage: + dependency: "direct main" + description: + name: get_storage + sha256: "39db1fffe779d0c22b3a744376e86febe4ade43bf65e06eab5af707dc84185a2" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + glob: + dependency: transitive + description: + name: glob + sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: b3cadd2cd59a4103fd5f6bc572ca75111264698784e927aa471921c3477d5475 + url: "https://pub.dev" + source: hosted + version: "10.0.0" + graphs: + dependency: transitive + description: + name: graphs + sha256: e84da18c5bd9854f4222e62d762e0ffd290726ffc5785dcb976f8c16ff797f5e + url: "https://pub.dev" + source: hosted + version: "1.0.0" + health: + dependency: "direct main" + description: + name: health + sha256: "6ab749b720d9a70f13893f2b05ca0e88f9ab4c5f7e1acc9ea177726969421d06" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + html: + dependency: transitive + description: + name: html + sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb" + url: "https://pub.dev" + source: hosted + version: "0.15.2" + http: + dependency: "direct main" + description: + name: http + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" + source: hosted + version: "0.13.5" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + icdevicemanager_flutter: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.0.1" + image: + dependency: transitive + description: + name: image + sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf + url: "https://pub.dev" + source: hosted + version: "4.0.17" + image_cropper: + dependency: "direct main" + description: + name: image_cropper + sha256: e08311fcf0cdba367715a5036aec8d8e9b3ab84479909dc2156dd5bf872edefb + url: "https://pub.dev" + source: hosted + version: "3.0.2" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + sha256: "09e93a8ec0435adcaa23622ac090442872f18145d70b9ff605ffedcf97d56255" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + sha256: "62349e3aab63873ea9b9ab9f69d036ab8a0d74b3004beec4303981386cb9273f" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: f202f5d730eb8219e35e80c4461fb3a779940ad30ce8fde1586df756e3af25e6 + url: "https://pub.dev" + source: hosted + version: "0.8.7+3" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "1ea6870350f56af8dab716459bd9d5dc76947e29e07a2ba1d0c172eaaf4f269c" + url: "https://pub.dev" + source: hosted + version: "0.8.6+7" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c" + url: "https://pub.dev" + source: hosted + version: "2.1.12" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: a1546ff5861fc15812953d4733b520c3d371cec3d2859a001ff04c46c4d81883 + url: "https://pub.dev" + source: hosted + version: "0.8.7+3" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8" + url: "https://pub.dev" + source: hosted + version: "2.6.3" + injectable: + dependency: "direct main" + description: + name: injectable + sha256: f71eb879124ed286cbd2210337b91ff5f345f146187c1f1891c172e0ac06443a + url: "https://pub.dev" + source: hosted + version: "1.5.4" + internet_connection_checker: + dependency: "direct main" + description: + name: internet_connection_checker + sha256: "6836d1e2193b3deab615820084a69521ec245550aba6e0a91b21c3757129872e" + url: "https://pub.dev" + source: hosted + version: "0.0.1+4" + intl: + dependency: "direct main" + description: + name: intl + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + url: "https://pub.dev" + source: hosted + version: "0.17.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + url: "https://pub.dev" + source: hosted + version: "4.8.0" + just_audio: + dependency: "direct main" + description: + name: just_audio + sha256: "7e6d31508dacd01a066e3889caf6282e5f1eb60707c230203b21a83af5c55586" + url: "https://pub.dev" + source: hosted + version: "0.9.32" + just_audio_platform_interface: + dependency: transitive + description: + name: just_audio_platform_interface + sha256: eff112d5138bea3ba544b6338b1e0537a32b5e1425e4d0dc38f732771cda7c84 + url: "https://pub.dev" + source: hosted + version: "4.2.0" + just_audio_web: + dependency: transitive + description: + name: just_audio_web + sha256: "89d8db6f19f3821bb6bf908c4bfb846079afb2ab575b783d781a6bf119e3abaf" + url: "https://pub.dev" + source: hosted + version: "0.4.7" + lints: + dependency: transitive + description: + name: lints + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" + source: hosted + version: "1.0.1" + local_auth: + dependency: "direct main" + description: + name: local_auth + sha256: "0cf238be2bfa51a6c9e7e9cfc11c05ea39f2a3a4d3e5bb255d0ebc917da24401" + url: "https://pub.dev" + source: hosted + version: "2.1.6" + local_auth_android: + dependency: transitive + description: + name: local_auth_android + sha256: "2ccfadbb6fbc63e6674ad58a350b06188829e62669d67a0c752c4e43cb88272a" + url: "https://pub.dev" + source: hosted + version: "1.0.21" + local_auth_ios: + dependency: transitive + description: + name: local_auth_ios + sha256: "604078f6492fe7730fc5bb8e4f2cfe2bc287a9b499ea0ff30a29925fc1873728" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + local_auth_platform_interface: + dependency: transitive + description: + name: local_auth_platform_interface + sha256: "9e160d59ef0743e35f1b50f4fb84dc64f55676b1b8071e319ef35e7f3bc13367" + url: "https://pub.dev" + source: hosted + version: "1.0.7" + local_auth_windows: + dependency: transitive + description: + name: local_auth_windows + sha256: bfe0deede77fb36faa62799977074f35ac096d7cafce0c29a44a173d2a2a4b94 + url: "https://pub.dev" + source: hosted + version: "1.0.7" + logger: + dependency: transitive + description: + name: logger + sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f" + url: "https://pub.dev" + source: hosted + version: "1.4.0" + logging: + dependency: transitive + description: + name: logging + sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + lottie: + dependency: "direct main" + description: + name: lottie + sha256: "23522951540d20a57a60202ed7022e6376bed206a4eee1c347a91f58bd57eb9f" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + matcher: + dependency: transitive + description: + name: matcher + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" + source: hosted + version: "0.12.13" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + modal_bottom_sheet: + dependency: "direct main" + description: + name: modal_bottom_sheet + sha256: ef533916a2c3089571c32bd34e410faca77a6849a3f28f748e0794525c5658a0 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + numerus: + dependency: transitive + description: + name: numerus + sha256: "436759d84f233b40107d0cc31cfa92d24e0960afeb2e506be70926d4cddffd9e" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + onesignal_flutter: + dependency: "direct main" + description: + name: onesignal_flutter + sha256: f4e54ad09bbfc2401b5d3e9cda6b31577facf0dd119d282d008df5710f5665d0 + url: "https://pub.dev" + source: hosted + version: "3.5.1" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "10259b111176fba5c505b102e3a5b022b51dd97e30522e906d6922c745584745" + url: "https://pub.dev" + source: hosted + version: "3.1.2" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + path: + dependency: transitive + description: + name: path + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" + source: hosted + version: "1.8.2" + path_drawing: + dependency: transitive + description: + name: path_drawing + sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 + url: "https://pub.dev" + source: hosted + version: "1.0.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4 + url: "https://pub.dev" + source: hosted + version: "2.0.14" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: da97262be945a72270513700a92b39dd2f4a54dad55d061687e2e37a6390366a + url: "https://pub.dev" + source: hosted + version: "2.0.25" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: ad4c4d011830462633f03eb34445a45345673dfd4faf1ab0b4735fbd93b19183 + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130 + url: "https://pub.dev" + source: hosted + version: "2.1.5" + pedantic: + dependency: transitive + description: + name: pedantic + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + pedometer: + dependency: "direct main" + description: + name: pedometer + sha256: e8c574dae778276fa848873c6ea2015a636a91e8572a4a652b04a4fcd6c54259 + url: "https://pub.dev" + source: hosted + version: "4.0.1" + percent_indicator: + dependency: "direct main" + description: + name: percent_indicator + sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c + url: "https://pub.dev" + source: hosted + version: "4.2.3" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" + url: "https://pub.dev" + source: hosted + version: "10.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" + url: "https://pub.dev" + source: hosted + version: "10.2.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85 + url: "https://pub.dev" + source: hosted + version: "9.0.8" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" + url: "https://pub.dev" + source: hosted + version: "3.9.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b + url: "https://pub.dev" + source: hosted + version: "0.1.2" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + photo_view: + dependency: "direct main" + description: + name: photo_view + sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb" + url: "https://pub.dev" + source: hosted + version: "0.14.0" + pin_code_fields: + dependency: "direct main" + description: + name: pin_code_fields + sha256: c8652519d14688f3fe2a8288d86910a46aa0b9046d728f292d3bf6067c31b4c7 + url: "https://pub.dev" + source: hosted + version: "7.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pod_player: + dependency: "direct main" + description: + name: pod_player + sha256: "8790d21d63d543399cda3d48b1e946271971f8d78125350bc66c3bb57bfea2d8" + url: "https://pub.dev" + source: hosted + version: "0.0.6" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + url: "https://pub.dev" + source: hosted + version: "3.7.3" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" + provider: + dependency: transitive + description: + name: provider + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" + source: hosted + version: "6.0.5" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: ec85d7d55339d85f44ec2b682a82fea340071e8978257e5a43e69f79e98ef50c + url: "https://pub.dev" + source: hosted + version: "1.2.2" + rename: + dependency: "direct main" + description: + name: rename + sha256: b0d9407186d834ad73aba9938da95a20208c4be99f151d9f376ac62a08d08bad + url: "https://pub.dev" + source: hosted + version: "2.1.1" + rounded_loading_button: + dependency: "direct main" + description: + name: rounded_loading_button + sha256: ec4af194330ba688527749059b7c1a3d1ddda6c18794ec4b0696f0cb3b9784ff + url: "https://pub.dev" + source: hosted + version: "2.1.0" + rxdart: + dependency: "direct main" + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: "692261968a494e47323dcc8bc66d8d52e81bc27cb4b808e4e8d7e8079d4cc01a" + url: "https://pub.dev" + source: hosted + version: "6.3.2" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "7fa90471a6875d26ad78c7e4a675874b2043874586891128dc5899662c97db46" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d + url: "https://pub.dev" + source: hosted + version: "2.2.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + shelf: + dependency: transitive + description: + name: shelf + sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + url: "https://pub.dev" + source: hosted + version: "1.4.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + shimmer: + dependency: "direct main" + description: + name: shimmer + sha256: "1f1009b5845a1f88f1c5630212279540486f97409e9fc3f63883e71070d107bf" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + skeletons: + dependency: "direct main" + description: + name: skeletons + sha256: "5b2d08ae7f908ee1f7007ca99f8dcebb4bfc1d3cb2143dec8d112a5be5a45c8f" + url: "https://pub.dev" + source: hosted + version: "0.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + slide_countdown: + dependency: "direct main" + description: + name: slide_countdown + sha256: "8f45cff7c07b3f11825f52edae71e984888ccba918cef74eb479abeaa4665106" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9 + url: "https://pub.dev" + source: hosted + version: "2.2.8+4" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "8f7603f3f8f126740bc55c4ca2d1027aab4b74a1267a3e31ce51fe40e3b65b8f" + url: "https://pub.dev" + source: hosted + version: "2.4.5+1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + story_view: + dependency: "direct main" + description: + name: story_view + sha256: e1a647ef0682e46a3de5254a46ac3b809b5c2a509998365966958f977a127db4 + url: "https://pub.dev" + source: hosted + version: "0.14.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + stream_duration: + dependency: transitive + description: + name: stream_duration + sha256: a29e071bf3e5d284e1e7dce98dbbaf547e16543c4802ec4f1a5c74e516c71af5 + url: "https://pub.dev" + source: hosted + version: "3.2.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + syncfusion_flutter_charts: + dependency: "direct main" + description: + name: syncfusion_flutter_charts + sha256: "0222ac9d8cb6c671f014effe9bd5c0aef35eadb16471355345ba87cc0ac007b3" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + sha256: "3979f0b1c5a97422cadae52d476c21fa3e0fb671ef51de6cae1d646d8b99fe1f" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_flutter_datepicker: + dependency: "direct main" + description: + name: syncfusion_flutter_datepicker + sha256: e4d4794d54f3a315046031d431a27e0d7350544b1bef0bcd1d2acf58f940dd37 + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_flutter_pdf: + dependency: transitive + description: + name: syncfusion_flutter_pdf + sha256: cebcafc60d52d52e0789c18b6332c2bd378f0a6cca006fe0373293bcc6a66e6d + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_flutter_pdfviewer: + dependency: "direct main" + description: + name: syncfusion_flutter_pdfviewer + sha256: "797a704efd843a606150d3d6317d5f2191173c334a5e5056b7f37855a8093af3" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_pdfviewer_macos: + dependency: transitive + description: + name: syncfusion_pdfviewer_macos + sha256: "6f2a9cdfc80aff8a13caba8d36527b3d68f5cb3530a7f2b29d269fbcff745afd" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_pdfviewer_platform_interface: + dependency: transitive + description: + name: syncfusion_pdfviewer_platform_interface + sha256: "646230861e103d33173a4909a184a00b2aa5a01819d38b05ccbf99da51be9314" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_pdfviewer_web: + dependency: transitive + description: + name: syncfusion_pdfviewer_web + sha256: ba0b72766f445ae171a5363df20abd50be0c1bc4576044df6afba3377a419de1 + url: "https://pub.dev" + source: hosted + version: "20.4.54" + syncfusion_pdfviewer_windows: + dependency: transitive + description: + name: syncfusion_pdfviewer_windows + sha256: "4cc6c92c211636550c4beb998f2db8f76d4f20eccbc8160730f2add0c8e23411" + url: "https://pub.dev" + source: hosted + version: "20.4.54" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" + source: hosted + version: "0.4.16" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + transparent_image: + dependency: "direct main" + description: + name: transparent_image + sha256: e8991d955a2094e197ca24c645efec2faf4285772a4746126ca12875e54ca02f + url: "https://pub.dev" + source: hosted + version: "2.0.1" + tutorial_coach_mark: + dependency: "direct main" + description: + name: tutorial_coach_mark + sha256: ba60583d1b500111bf5040eb24330862b25162d926f72923b8e45c16621878b0 + url: "https://pub.dev" + source: hosted + version: "1.2.9" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + uni_links: + dependency: "direct main" + description: + name: uni_links + sha256: "051098acfc9e26a9fde03b487bef5d3d228ca8f67693480c6f33fd4fbb8e2b6e" + url: "https://pub.dev" + source: hosted + version: "0.5.1" + uni_links_platform_interface: + dependency: transitive + description: + name: uni_links_platform_interface + sha256: "929cf1a71b59e3b7c2d8a2605a9cf7e0b125b13bc858e55083d88c62722d4507" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + uni_links_web: + dependency: transitive + description: + name: uni_links_web + sha256: "7539db908e25f67de2438e33cc1020b30ab94e66720b5677ba6763b25f6394df" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + universal_html: + dependency: transitive + description: + name: universal_html + sha256: ed4f24120c9b1b4721d44e439f7a47d09d9f1b7b868bc84c9d6d373a4a8732af + url: "https://pub.dev" + source: hosted + version: "2.2.1" + universal_io: + dependency: transitive + description: + name: universal_io + sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e" + url: "https://pub.dev" + source: hosted + version: "6.1.10" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: a52628068d282d01a07cd86e6ba99e497aa45ce8c91159015b2416907d78e411 + url: "https://pub.dev" + source: hosted + version: "6.0.27" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "206fb8334a700ef7754d6a9ed119e7349bc830448098f21a69bf1b4ed038cabc" + url: "https://pub.dev" + source: hosted + version: "3.0.4" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa" + url: "https://pub.dev" + source: hosted + version: "2.0.16" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: a83ba3607a507758669cfafb03f9de09bf6e6280c14d9b9cb18f013e406dcacd + url: "https://pub.dev" + source: hosted + version: "3.0.5" + uuid: + dependency: transitive + description: + name: uuid + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" + source: hosted + version: "3.0.7" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vibration: + dependency: "direct main" + description: + name: vibration + sha256: "1dc9d1a0d62b12f1276eb7146b21585db5fe01771b8ca0234fefdf74ba51f963" + url: "https://pub.dev" + source: hosted + version: "1.7.6" + video_player: + dependency: "direct main" + description: + name: video_player + sha256: "74b86e63529cf5885130c639d74cd2f9232e7c8a66cbecbddd1dcb9dbd060d1e" + url: "https://pub.dev" + source: hosted + version: "2.7.2" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: e7de6fabe5d96048cd8f4d710f25c3df84bb3cab8b22da6c082bd8f39e316984 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: "90468226c8687adf7b567d9bb42c25588783c4d30509af1fbd663b2dd049f700" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a + url: "https://pub.dev" + source: hosted + version: "6.2.1" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: fb3bbeaf0302cb0c31340ebd6075487939aa1fe3b379d1a8784ef852b679940e + url: "https://pub.dev" + source: hosted + version: "2.0.15" + vimeo_video_player: + dependency: "direct main" + description: + name: vimeo_video_player + sha256: e15dc0ff68bec6b23c1be2e0a3ae02430721f4263387cc2f53cc153feab44f65 + url: "https://pub.dev" + source: hosted + version: "0.0.8" + wakelock: + dependency: transitive + description: + name: wakelock + sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" + url: "https://pub.dev" + source: hosted + version: "0.6.2" + wakelock_macos: + dependency: transitive + description: + name: wakelock_macos + sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + wakelock_platform_interface: + dependency: transitive + description: + name: wakelock_platform_interface + sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" + url: "https://pub.dev" + source: hosted + version: "0.3.0" + wakelock_web: + dependency: transitive + description: + name: wakelock_web + sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + wakelock_windows: + dependency: transitive + description: + name: wakelock_windows + sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + sha256: "47663d51a9061451aa3880a214ee9a65dcbb933b77bc44388e194279ab3ccaf6" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: "489c4162cbddea9116a9622f0f881c3cc26317d119322150d7608f2223ffa72d" + url: "https://pub.dev" + source: hosted + version: "3.5.2" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: "6341f92977609be71391f4d4dcd64bfaa8ac657af1dfb2e231b5c1724e8c6c36" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: "2ef3f65fd49061c18e4d837a411308f2850417f2d0a7c11aad2c3857bee12c18" + url: "https://pub.dev" + source: hosted + version: "3.3.0" + win32: + dependency: transitive + description: + name: win32 + sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 + url: "https://pub.dev" + source: hosted + version: "3.1.4" + workmanager: + dependency: "direct main" + description: + name: workmanager + sha256: e0be7e35d644643f164ee45d2ce14414f0e0fdde19456aa66065f35a0b1d2ea1 + url: "https://pub.dev" + source: hosted + version: "0.5.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + xml: + dependency: transitive + description: + name: xml + sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + url: "https://pub.dev" + source: hosted + version: "6.2.2" + yaml: + dependency: transitive + description: + name: yaml + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + youtube_explode_dart: + dependency: transitive + description: + name: youtube_explode_dart + sha256: "07889a6229a63e78f8d45a3b852897c2e0fa42e96c4daa38d411be211575bc38" + url: "https://pub.dev" + source: hosted + version: "1.12.4" +sdks: + dart: ">=2.19.0 <3.0.0" + flutter: ">=3.7.0" diff --git a/gsf/pubspec.yaml b/gsf/pubspec.yaml new file mode 100644 index 0000000..6322123 --- /dev/null +++ b/gsf/pubspec.yaml @@ -0,0 +1,236 @@ +name: gsp_app +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.1.0+3 + +environment: + sdk: ">=2.19.0 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + flutter_svg: ^1.0.3 + get: ^4.6.5 + image_cropper: ^3.0.1 + image_picker: ^0.8.7 + carousel_slider: ^4.1.1 + + modal_bottom_sheet: ^2.1.2 + flutter_branch_sdk: any + health: any + + pin_code_fields: ^7.4.0 + intl: ^0.17.0 + percent_indicator: ^4.2.1 + vibration: ^1.7.6 + audioplayers: ^1.1.1 + url_launcher: ^6.1.7 + fl_chart: ^0.55.2 + vimeo_video_player: + get_storage: ^2.0.3 + animations: ^2.0.2 + lottie: + just_audio: ^0.9.30 + audio_video_progress_bar: + rxdart: ^0.27.7 + dropdown_button2: + connectivity_plus: ^4.0.2 + local_auth: ^2.1.3 + shared_preferences: ^2.0.16 + internet_connection_checker: ^0.0.1+3 + path_provider: ^2.0.10 + event_bus: ^2.0.0 + fluttertoast: ^8.1.2 + http: any + permission_handler: ^10.2.0 + webview_flutter: ^4.0.5 + shimmer: ^2.0.0 + pod_player: any + share_plus: ^6.3.1 + onesignal_flutter: ^3.5.0 + rounded_loading_button: ^2.1.0 + flutter_html: ^3.0.0-alpha.6 + skeletons: ^0.0.3 + uni_links: ^0.5.1 + flutter_blue_plus: ^1.12.13 + bluetooth_enable_fork: ^0.1.6 + transparent_image: ^2.0.1 + tutorial_coach_mark: ^1.2.9 + geolocator: ^9.0.2 + workmanager: ^0.5.1 + icdevicemanager_flutter: + # When depending on this package from a real application you should use: + # flutter_swift: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + story_view: ^0.14.0 + flutter_countdown_timer: ^4.1.0 + flutter_pdfview: ^1.3.1 + photo_view: ^0.14.0 + blobs: ^2.0.0 + slide_countdown: ^0.6.0 + go_router: ^10.0.0 + rename: ^2.1.1 + # image_downloader: ^0.30.0 + another_flushbar: ^1.12.30 + dio: ^5.3.2 + flutter_custom_tabs: ^1.0.4 + pedometer: ^4.0.1 + syncfusion_flutter_charts: ^20.2.36 + syncfusion_flutter_pdfviewer: any + flutter_cache_manager: ^3.3.1 + animated_horizontal_calendar: ^0.0.3 + firebase_crashlytics: any + firebase_core: ^2.4.1 + flutter_background: ^1.2.0 + package_info_plus: any + circular_countdown_timer: ^0.2.3 + syncfusion_flutter_datepicker: any + # flutter_background_service: ^5.0.4 + # flutter_local_notifications: any + flutter_bloc: ^8.1.2 + video_player: ^2.6.1 + flutter_isolate: ^2.0.2 + injectable: ^1.4.1 + + + # flutter_launcher_icons: ^0.12.0 +# dependency_overrides: +# win32: '4.0.0' # Use a compatible version + + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.0 + flutter_launcher_icons: ^0.12.0 + flutter_native_splash: ^2.2.4 + +flutter_native_splash: + android: true + ios: false + web: false + background_image: "assets/image/splash.png" + +flutter_icons: + android: true + ios: false + image_path: "assets/image/android_logo.png" + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/image/ + - assets/image/profile/ + - assets/image/feedback_img/ + - assets/image/menuicon/ + - assets/image/sidebarIcons/ + - assets/image/profileIcons/ + - assets/image/podcast/ + - assets/image/faq/ + - assets/image/feedback/ + - assets/image/blog/ + - assets/image/setting/ + - assets/image/courses/ + - assets/audio/ + - assets/image/quiz_imgs/ + - assets/image/mood_icons/active/ + - assets/image/mood_icons/inactive/ + - assets/image/badges/ + - assets/image/arrows/ + - assets/image/filter_leaderboard/ + - assets/image/filter_leaderboard/filters/ + - assets/image/filter_leaderboard/gender/ + - assets/image/filter_leaderboard/date_range/ + - assets/image/filter_leaderboard/group_level/ + - assets/image/overview_guide/ + - assets/lottie/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regaudioplayersarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Poppins + fonts: + - asset: assets/fonts/Poppins-Thin.ttf + weight: 100 + - asset: assets/fonts/Poppins-ExtraLight.ttf + weight: 200 + - asset: assets/fonts/Poppins-Light.ttf + weight: 300 + - asset: assets/fonts/Poppins-Regular.ttf + weight: 400 + - asset: assets/fonts/Poppins-Medium.ttf + weight: 500 + - asset: assets/fonts/Poppins-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Poppins-Bold.ttf + weight: 700 + - asset: assets/fonts/Poppins-ExtraBold.ttf + weight: 800 + # - asset: fonts/Schyler-Italic.ttf + # style: italic + - family: SFPRO + fonts: + - asset: assets/fonts/FontsFree-Net-SFProText-Light-1.ttf + weight: 300 + - asset: assets/fonts/FontsFree-Net-SFProText-Regular-1.ttf + weight: 400 + - asset: assets/fonts/FontsFree-Net-SFProText-Semibold-1.ttf + weight: 500 + - asset: assets/fonts/FontsFree-Net-SFProText-Heavy-1.ttf + weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/gsf/test/widget_test.dart b/gsf/test/widget_test.dart new file mode 100644 index 0000000..c250c4b --- /dev/null +++ b/gsf/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:gsp_app/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/gsf/web/favicon.png b/gsf/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/gsf/web/favicon.png differ diff --git a/gsf/web/icons/Icon-192.png b/gsf/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/gsf/web/icons/Icon-192.png differ diff --git a/gsf/web/icons/Icon-512.png b/gsf/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/gsf/web/icons/Icon-512.png differ diff --git a/gsf/web/icons/Icon-maskable-192.png b/gsf/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/gsf/web/icons/Icon-maskable-192.png differ diff --git a/gsf/web/icons/Icon-maskable-512.png b/gsf/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/gsf/web/icons/Icon-maskable-512.png differ diff --git a/gsf/web/index.html b/gsf/web/index.html new file mode 100644 index 0000000..e78738a --- /dev/null +++ b/gsf/web/index.html @@ -0,0 +1,211 @@ +<<<<<<< HEAD + + + + + + + + + + + + + + + + + + + + gsp_app + + + + + + + +======= + + + + + + + + + + + + + + + + + + + + gsp_app + + + + + + + +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/web/manifest.json b/gsf/web/manifest.json new file mode 100644 index 0000000..13c02be --- /dev/null +++ b/gsf/web/manifest.json @@ -0,0 +1,73 @@ +<<<<<<< HEAD +{ + "name": "gsp_app", + "short_name": "gsp_app", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} +======= +{ + "name": "gsp_app", + "short_name": "gsp_app", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/.gitignore b/gsf/windows/.gitignore new file mode 100644 index 0000000..3863074 --- /dev/null +++ b/gsf/windows/.gitignore @@ -0,0 +1,37 @@ +<<<<<<< HEAD +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ +======= +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/CMakeLists.txt b/gsf/windows/CMakeLists.txt new file mode 100644 index 0000000..10aba30 --- /dev/null +++ b/gsf/windows/CMakeLists.txt @@ -0,0 +1,193 @@ +<<<<<<< HEAD +cmake_minimum_required(VERSION 3.14) +project(gsp_app LANGUAGES CXX) + +set(BINARY_NAME "gsp_app") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) +======= +cmake_minimum_required(VERSION 3.14) +project(gsp_app LANGUAGES CXX) + +set(BINARY_NAME "gsp_app") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/flutter/CMakeLists.txt b/gsf/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..71586f7 --- /dev/null +++ b/gsf/windows/flutter/CMakeLists.txt @@ -0,0 +1,209 @@ +<<<<<<< HEAD +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) +======= +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/flutter/generated_plugin_registrant.cc b/gsf/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..05ab922 --- /dev/null +++ b/gsf/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,38 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + AudioplayersWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + GeolocatorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("GeolocatorWindows")); + LocalAuthPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("LocalAuthPlugin")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); +} diff --git a/gsf/windows/flutter/generated_plugin_registrant.h b/gsf/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/gsf/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/gsf/windows/flutter/generated_plugins.cmake b/gsf/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..07d3ac9 --- /dev/null +++ b/gsf/windows/flutter/generated_plugins.cmake @@ -0,0 +1,32 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_windows + connectivity_plus + firebase_core + geolocator_windows + local_auth_windows + permission_handler_windows + share_plus + syncfusion_pdfviewer_windows + url_launcher_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/gsf/windows/runner/CMakeLists.txt b/gsf/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..33ba418 --- /dev/null +++ b/gsf/windows/runner/CMakeLists.txt @@ -0,0 +1,37 @@ +<<<<<<< HEAD +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) +======= +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/Runner.rc b/gsf/windows/runner/Runner.rc new file mode 100644 index 0000000..9e6968a --- /dev/null +++ b/gsf/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "gsp_app" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "gsp_app" "\0" + VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "gsp_app.exe" "\0" + VALUE "ProductName", "gsp_app" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/gsf/windows/runner/flutter_window.cpp b/gsf/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..b1caead --- /dev/null +++ b/gsf/windows/runner/flutter_window.cpp @@ -0,0 +1,125 @@ +<<<<<<< HEAD +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} +======= +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/flutter_window.h b/gsf/windows/runner/flutter_window.h new file mode 100644 index 0000000..1881bcc --- /dev/null +++ b/gsf/windows/runner/flutter_window.h @@ -0,0 +1,69 @@ +<<<<<<< HEAD +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ +======= +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/main.cpp b/gsf/windows/runner/main.cpp new file mode 100644 index 0000000..a190f53 --- /dev/null +++ b/gsf/windows/runner/main.cpp @@ -0,0 +1,89 @@ +<<<<<<< HEAD +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"gsp_app", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} +======= +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"gsp_app", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/resource.h b/gsf/windows/runner/resource.h new file mode 100644 index 0000000..40e4791 --- /dev/null +++ b/gsf/windows/runner/resource.h @@ -0,0 +1,35 @@ +<<<<<<< HEAD +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif +======= +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/resources/app_icon.ico b/gsf/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000..c04e20c Binary files /dev/null and b/gsf/windows/runner/resources/app_icon.ico differ diff --git a/gsf/windows/runner/runner.exe.manifest b/gsf/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..02ce1c6 --- /dev/null +++ b/gsf/windows/runner/runner.exe.manifest @@ -0,0 +1,43 @@ +<<<<<<< HEAD + + + + + PerMonitorV2 + + + + + + + + + + + + + + + +======= + + + + + PerMonitorV2 + + + + + + + + + + + + + + + +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/utils.cpp b/gsf/windows/runner/utils.cpp new file mode 100644 index 0000000..564c08b --- /dev/null +++ b/gsf/windows/runner/utils.cpp @@ -0,0 +1,131 @@ +<<<<<<< HEAD +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} +======= +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/utils.h b/gsf/windows/runner/utils.h new file mode 100644 index 0000000..57f6c94 --- /dev/null +++ b/gsf/windows/runner/utils.h @@ -0,0 +1,41 @@ +<<<<<<< HEAD +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ +======= +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/win32_window.cpp b/gsf/windows/runner/win32_window.cpp new file mode 100644 index 0000000..b3fb240 --- /dev/null +++ b/gsf/windows/runner/win32_window.cpp @@ -0,0 +1,493 @@ +<<<<<<< HEAD +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} +======= +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/gsf/windows/runner/win32_window.h b/gsf/windows/runner/win32_window.h new file mode 100644 index 0000000..839fcff --- /dev/null +++ b/gsf/windows/runner/win32_window.h @@ -0,0 +1,199 @@ +<<<<<<< HEAD +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ +======= +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ +>>>>>>> bf782164e8554ef4207be582358b5a6a35902fc7 diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..c7a36db --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,40 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh + +ios/Classes/ICDeviceManager.a \ No newline at end of file diff --git a/ios/Assets/.gitkeep b/ios/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ios/Classes/FlutterSwiftPlugin.h b/ios/Classes/FlutterSwiftPlugin.h new file mode 100644 index 0000000..2302b44 --- /dev/null +++ b/ios/Classes/FlutterSwiftPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface FlutterSwiftPlugin : NSObject +@end diff --git a/ios/Classes/FlutterSwiftPlugin.m b/ios/Classes/FlutterSwiftPlugin.m new file mode 100644 index 0000000..baeeb3c --- /dev/null +++ b/ios/Classes/FlutterSwiftPlugin.m @@ -0,0 +1,15 @@ +#import "FlutterSwiftPlugin.h" +#if __has_include() +#import +#else +// Support project import fallback if the generated compatibility header +// is not copied when this plugin is created as a library. +// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 +#import "icdevicemanager_flutter-Swift.h" +#endif + +@implementation FlutterSwiftPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + [SwiftFlutterSwiftPlugin registerWithRegistrar:registrar]; +} +@end diff --git a/ios/Classes/Headers/ICAlgDef.h b/ios/Classes/Headers/ICAlgDef.h new file mode 100644 index 0000000..7e1bbb4 --- /dev/null +++ b/ios/Classes/Headers/ICAlgDef.h @@ -0,0 +1,68 @@ +// +// ICAlgDef.h +// ICDeviceManager +// +// Created by Symons on 2019/10/17. +// Copyright © 2019 Symons. All rights reserved. +// + +#ifndef ICAlgDef_h +#define ICAlgDef_h + +#define ENABLE_WLA01 1 + +#define ENABLE_WLA02 1 + +#define ENABLE_WLA03 1 + +#define ENABLE_WLA04 1 + +#define ENABLE_WLA05 1 + +#define ENABLE_WLA06 1 + +#define ENABLE_WLA07 1 + +#define ENABLE_WLA08 1 + +#define ENABLE_WLA09 1 + +#define ENABLE_WLA10 1 + +#define ENABLE_WLA11 1 + +#define ENABLE_WLA12 1 + +#define ENABLE_WLA13 1 + +#define ENABLE_WLA14 1 + +#define ENABLE_WLA15 1 + +#define ENABLE_WLA16 1 + +#define ENABLE_WLA17 1 + +#define ENABLE_WLA18 1 + +#define ENABLE_WLA19 1 + +#define ENABLE_WLA20 1 + +#define ENABLE_WLA22 1 + +#define ENABLE_WLA23 1 + +#define ENABLE_WLA24 1 + +#define ENABLE_WLA25 1 + +#define ENABLE_WLA26 1 + +#define ENABLE_WLA27 1 + +#define ENABLE_WLA28 1 + +#define ENABLE_WLA29 1 + +#endif /* ICAlgDef_h */ diff --git a/ios/Classes/Headers/ICBodyFatAlgorithmsManager.h b/ios/Classes/Headers/ICBodyFatAlgorithmsManager.h new file mode 100644 index 0000000..ec5cb53 --- /dev/null +++ b/ios/Classes/Headers/ICBodyFatAlgorithmsManager.h @@ -0,0 +1,29 @@ +// +// ICBodyFatAlgorithms.h +// ICDeviceManager +// +// Created by Symons on 2018/9/26. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import + + +@class ICUserInfo; +@class ICWeightData; + +/** + 体脂算法接口 + */ +@protocol ICBodyFatAlgorithmsManager + +/** + 重算体脂数据 + + @param weightData 体重数据(原来sdk回调出去的数据) + @param userInfo 用户信息 + @return 重算后的数据 + */ +- (ICWeightData *)reCalcBodyFatWithWeightData:(ICWeightData *)weightData userInfo:(ICUserInfo *)userInfo; + +@end diff --git a/ios/Classes/Headers/ICCallback_Inc.h b/ios/Classes/Headers/ICCallback_Inc.h new file mode 100644 index 0000000..363ab7d --- /dev/null +++ b/ios/Classes/Headers/ICCallback_Inc.h @@ -0,0 +1,12 @@ +// +// ICCallback_Inc.h +// ICDeviceManager +// + + +#ifndef ICCallback_Inc_h +#define ICCallback_Inc_h + +#import "ICScanDeviceDelegate.h" + +#endif /* ICCallback_Inc_h */ diff --git a/ios/Classes/Headers/ICConstant.h b/ios/Classes/Headers/ICConstant.h new file mode 100644 index 0000000..428c3ff --- /dev/null +++ b/ios/Classes/Headers/ICConstant.h @@ -0,0 +1,990 @@ +// +// ICConstant.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#ifndef ICConstant_h +#define ICConstant_h + +#import "ICAlgDef.h" + +@class ICDevice; + + +/** + 设备类型 + **/ +typedef NS_ENUM(NSUInteger, ICDeviceType) +{ + /** + * 未知 + **/ + ICDeviceTypeUnKnown = 0, + + /** + * 体重秤 + **/ + ICDeviceTypeWeightScale, + + /** + * 脂肪秤 + **/ + ICDeviceTypeFatScale, + + /** + * 脂肪秤(带温度显示) + **/ + ICDeviceTypeFatScaleWithTemperature, + + /** + * 厨房秤 + **/ + ICDeviceTypeKitchenScale, + + /** + * 围尺 + **/ + ICDeviceTypeRuler, + + /** + * 平衡秤 + **/ + ICDeviceTypeBalance, + + /** + * 跳绳 + **/ + ICDeviceTypeSkip, + + /** + * HR + **/ + ICDeviceTypeHR, +}; + +/** + 设备子类型 + **/ +typedef NS_ENUM(NSUInteger, ICDeviceSubType) +{ + /** + * 默认 + **/ + ICDeviceSubTypeDefault = 0, + + /** + * 8电极设备 + **/ + ICDeviceSubTypeEightElectrode, + + /** + * 身高设备 + **/ + ICDeviceSubTypeHeight, + /** + * 8电极设备2 + **/ + ICDeviceSubTypeEightElectrode2, + /** + * 双模设备 + **/ + ICDeviceSubTypeScaleDual, + /** + * 跳绳带灯效 + **/ + ICDeviceSubTypeLightEffect, + /** + * 彩屏秤 + **/ + ICDeviceSubTypeColor, + /** + * 跳绳带语音 + **/ + ICDeviceSubTypeSound, + + /** + * 跳绳带灯效和语音 + **/ + ICDeviceSubTypeLightAndSound, + + /** + * 基站 + */ + ICDeviceSubTypeBaseSt, + + /** + * iComon S2 + */ + ICDeviceSubTypeRopeS2, + +}; + +/** + 设备通讯方式 + + */ +typedef NS_ENUM(NSUInteger, ICDeviceCommunicationType) { + /** + 未知 + */ + ICDeviceCommunicationTypeUnknown, + + /** + 连接式 + */ + ICDeviceCommunicationTypeConnect, + + /** + 广播式 + */ + ICDeviceCommunicationTypeBroadcast, +}; + +/** + 蓝牙状态 + */ +typedef NS_ENUM(NSUInteger, ICBleState) +{ + /** + * 未知状态 + **/ + ICBleStateUnknown = 0, + + /** + * 手机不支持BLE + **/ + ICBleStateUnsupported, + + /** + * 应用未获取蓝牙授权 + **/ + ICBleStateUnauthorized, + + /** + * 蓝牙关闭 + **/ + ICBleStatePoweredOff, + + /** + * 蓝牙打开 + **/ + ICBleStatePoweredOn, +}; + + +/** + 设备连接状态 + + */ +typedef NS_ENUM(NSUInteger, ICDeviceConnectState) +{ + /** + * 已连接 + **/ + ICDeviceConnectStateConnected, + + /** + * 已断开 + **/ + ICDeviceConnectStateDisconnected, +}; + + + +/** + * 添加设备回调代码 + */ +typedef NS_ENUM(NSUInteger, ICAddDeviceCallBackCode) +{ + /** + * 添加成功 + */ + ICAddDeviceCallBackCodeSuccess, + + /** + * 添加失败,SDK未初始化 + */ + ICAddDeviceCallBackCodeFailedAndSDKNotInit, + + /** + * 添加失败,设备已存在 + */ + ICAddDeviceCallBackCodeFailedAndExist, + + /** + * 添加失败,设备参数有错 + */ + ICAddDeviceCallBackCodeFailedAndDeviceParamError, +}; + +/** + 添加设备回调 + */ +typedef void(^ICAddDeviceCallBack)(ICDevice *device, ICAddDeviceCallBackCode code); + + +/** + * 删除设备回调代码 + */ +typedef NS_ENUM(NSUInteger, ICRemoveDeviceCallBackCode) +{ + /** + * 删除成功 + */ + ICRemoveDeviceCallBackCodeSuccess, + + /** + * 删除失败,SDK未初始化 + */ + ICRemoveDeviceCallBackCodeFailedAndSDKNotInit, + + /** + * 删除失败,设备不存在 + */ + ICRemoveDeviceCallBackCodeFailedAndNotExist, + + /** + * 删除失败,设备参数有错 + */ + ICRemoveDeviceCallBackCodeFailedAndDeviceParamError, +}; + +/** + 删除设备回调 + */ +typedef void(^ICRemoveDeviceCallBack)(ICDevice *device, ICRemoveDeviceCallBackCode code); + + + +/** + 设置回调错误代码 + + */ +typedef NS_ENUM(NSUInteger, ICSettingCallBackCode) +{ + /** + * 设置成功 + **/ + ICSettingCallBackCodeSuccess = 0, + + /** + * 设置失败,SDK没有初始化 + **/ + ICSettingCallBackCodeSDKNotInit, + + /** + * 设置失败,SDK没有启动 + **/ + ICSettingCallBackCodeSDKNotStart, + + /** + * 设置失败,找不到设备或者设备未连接,请等待设备连接上后再设置 + **/ + ICSettingCallBackCodeDeviceNotFound, + + /** + * 设置失败,设备不支持该功能 + **/ + ICSettingCallBackCodeFunctionIsNotSupport, + + /** + * 设置失败,设备已断开 + **/ + ICSettingCallBackCodeDeviceDisConnected, + + /** + * 设置失败,无效参数 + **/ + ICSettingCallBackCodeInvalidParameter, + + /** + * 设置失败 + **/ + ICSettingCallBackCodeFailed, +}; + +/** + 体重秤单位 + */ +typedef NS_ENUM(NSUInteger, ICWeightUnit) +{ + + /** + * 公斤 + */ + ICWeightUnitKg = 0, + + /** + * 磅 + */ + ICWeightUnitLb, + + /** + * 英石 + */ + ICWeightUnitSt, + + /** + * 斤 + */ + ICWeightUnitJin +}; + + +/** + 围尺单位 + */ +typedef NS_ENUM(NSUInteger, ICRulerUnit) +{ + + /** + * 厘米cm + */ + ICRulerUnitCM = 1, + + /** + * 英寸inch + */ + ICRulerUnitInch, + /** + * 英尺'英寸 + */ + ICRulerUnitFtInch, + +}; + + +/** + 围尺测量模式 + */ +typedef NS_ENUM(NSUInteger, ICRulerMeasureMode) +{ + + /** + * 长度模式 + */ + ICRulerMeasureModeLength = 0, + + /** + * 围度模式 + */ + ICRulerMeasureModeGirth, + +}; + + + +/** + 厨房秤单位 + */ +typedef NS_ENUM(NSUInteger, ICKitchenScaleUnit) +{ + + /** + * 克 + */ + ICKitchenScaleUnitG, + + /** + * ml + */ + ICKitchenScaleUnitMl, + + /** + * 磅 + */ + ICKitchenScaleUnitLb, + + /** + * 盎司 + */ + ICKitchenScaleUnitOz, + /** + * 毫克 + */ + ICKitchenScaleUnitMg, + /** + * ml(牛奶) + */ + ICKitchenScaleUnitMlMilk, + /** + * 盎司(水) + */ + ICKitchenScaleUnitFlOzWater, + /** + * 盎司(牛奶) + */ + ICKitchenScaleUnitFlOzMilk +}; + + +/** + 围尺设置的部位类型 + */ +typedef NS_ENUM(NSUInteger, ICRulerBodyPartsType) +{ + /** + * 肩膀 + */ + ICRulerPartsTypeShoulder = 1, + + /** + * 手臂 + */ + ICRulerPartsTypeBicep, + + /** + * 胸 + */ + ICRulerPartsTypeChest, + + /** + * 腰 + */ + ICRulerPartsTypeWaist, + + /** + * 臀 + */ + ICRulerPartsTypeHip, + + /** + * 大腿 + */ + ICRulerPartsTypeThigh, + + /** + * 小腿 + */ + ICRulerPartsTypeCalf, + + +}; + +/** + 性别 + */ +typedef NS_ENUM(NSInteger,ICSexType) +{ + /** + * 未知/保密 + */ + ICSexTypeUnknown = 0, + + /** + * 男 + */ + ICSexTypeMale = 1, + + /** + * 女 + */ + ICSexTypeFemal +}; + +/** + 厨房秤营养成分类型 + */ +typedef NS_ENUM(NSUInteger, ICKitchenScaleNutritionFactType) { + /* + * 卡路里, 最大不超过4294967295 + */ + ICKitchenScaleNutritionFactTypeCalorie, + + /* + * 总卡路里, 最大不超过4294967295 + */ + ICKitchenScaleNutritionFactTypeTotalCalorie, + + /* + * 总脂肪 + */ + ICKitchenScaleNutritionFactTypeTotalFat, + + /* + * 总蛋白质 + */ + ICKitchenScaleNutritionFactTypeTotalProtein, + + /* + * 总碳水化合物 + */ + ICKitchenScaleNutritionFactTypeTotalCarbohydrates, + + /* + * 总脂肪纤维 + */ + ICKitchenScaleNutritionFactTypeTotalFiber, + + /* + * 总胆固醇 + */ + ICKitchenScaleNutritionFactTypeTotalCholesterd, + + /* + * 总钠含量 + */ + ICKitchenScaleNutritionFactTypeTotalSodium, + + /* + * 总糖含量 + */ + ICKitchenScaleNutritionFactTypeTotalSugar, + + /* + * 脂肪 + */ + ICKitchenScaleNutritionFactTypeFat, + + /* + * 蛋白质 + */ + ICKitchenScaleNutritionFactTypeProtein, + + /* + * 碳水化合物 + */ + ICKitchenScaleNutritionFactTypeCarbohydrates, + + /* + * 膳食纤维 + */ + ICKitchenScaleNutritionFactTypeFiber, + + /* + * 胆固醇 + */ + ICKitchenScaleNutritionFactTypeCholesterd, + + /* + * 钠含量 + */ + ICKitchenScaleNutritionFactTypeSodium, + + /* + * 糖含量 + */ + ICKitchenScaleNutritionFactTypeSugar, +}; + +/** + 算法版本 + */ +typedef enum : NSUInteger { +#if ENABLE_WLA01 + /* + * 含水肌肉率 + */ + ICBFATypeWLA01 = 0, +#endif +#if ENABLE_WLA02 + /* + * 不含水肌肉率 + */ + ICBFATypeWLA02 = 1, +#endif +#if ENABLE_WLA03 + /* + * 新算法1 + */ + ICBFATypeWLA03 = 2, +#endif +#if ENABLE_WLA04 + /* + * 新算法2 + */ + ICBFATypeWLA04 = 3, +#endif +#if ENABLE_WLA05 + /* + * 新算法3 + */ + ICBFATypeWLA05 = 4, +#endif +#if ENABLE_WLA06 + /* + * 新算法4 + */ + ICBFATypeWLA06 = 5, +#endif +#if ENABLE_WLA07 + /* + * 新算法WLA07 + */ + ICBFATypeWLA07 = 6, +#endif +#if ENABLE_WLA08 + /* + * 新算法WLA08 + */ + ICBFATypeWLA08 = 7, +#endif +#if ENABLE_WLA09 + /* + * 新算法WLA09 + */ + ICBFATypeWLA09 = 8, +#endif +#if ENABLE_WLA10 + /* + * 新算法WLA10 + */ + ICBFATypeWLA10 = 9, +#endif +#if ENABLE_WLA11 + /* + * 新算法WLA11 + */ + ICBFATypeWLA11 = 10, +#endif +#if ENABLE_WLA12 + /* + * 新算法WLA12 + */ + ICBFATypeWLA12 = 11, +#endif +#if ENABLE_WLA13 + /* + * 新算法WLA13 + */ + ICBFATypeWLA13 = 12, +#endif +#if ENABLE_WLA14 + /* + * 新算法WLA14 + */ + ICBFATypeWLA14 = 13, +#endif +#if ENABLE_WLA15 + /* + * 新算法WLA15 + */ + ICBFATypeWLA15 = 14, +#endif +#if ENABLE_WLA16 + /* + * 新算法WLA16 + */ + ICBFATypeWLA16 = 15, +#endif +#if ENABLE_WLA17 + /* + * 新算法WLA17 + */ + ICBFATypeWLA17 = 16, +#endif +#if ENABLE_WLA18 + /* + * 新算法WLA18 + */ + ICBFATypeWLA18 = 17, +#endif +#if ENABLE_WLA19 + /* + * 新算法WLA19 + */ + ICBFATypeWLA19 = 18, +#endif +#if ENABLE_WLA20 + /* + * 新算法WLA20 + */ + ICBFATypeWLA20 = 19, +#endif +#if ENABLE_WLA22 + /* + * 新算法WLA22 + */ + ICBFATypeWLA22 = 21, +#endif +#if ENABLE_WLA23 + /* + * 新算法WLA23 + */ + ICBFATypeWLA23 = 22, +#endif +#if ENABLE_WLA24 + /* + * 新算法WLA24 + */ + ICBFATypeWLA24 = 23, +#endif +#if ENABLE_WLA25 + /* + * 新算法WLA25 + */ + ICBFATypeWLA25 = 24, +#endif +#if ENABLE_WLA26 + /* + * 新算法WLA26 + */ + ICBFATypeWLA26 = 25, +#endif +#if ENABLE_WLA27 + /* + * 新算法WLA27 + */ + ICBFATypeWLA27 = 26, +#endif +#if ENABLE_WLA28 + /* + * 新算法WLA28 + */ + ICBFATypeWLA28 = 27, +#endif +#if ENABLE_WLA29 + /* + * 新算法WLA29 + */ + ICBFATypeWLA29 = 28, +#endif + ICBFATypeUnknown = 100, + ICBFATypeRev = 101 + +} ICBFAType; + +/** + 用户类型 + */ +typedef enum : NSUInteger { + /* + * 普通人 + */ + ICPeopleTypeNormal, + + /* + * 运动员 + */ + ICPeopleTypeSportman, +} ICPeopleType; + +/** + 数据类型 + */ +typedef enum : NSUInteger { + /* + * 测量体重 (ICWeightData) + */ + ICMeasureStepMeasureWeightData, + + /* + * 测量平衡 (ICWeightCenterData) + */ + ICMeasureStepMeasureCenterData, + + /* + * 开始测量阻抗 + */ + ICMeasureStepAdcStart, + + /* + * 测量阻抗结束 (ICWeightData) + */ + ICMeasureStepAdcResult, + + /* + * 开始测量心率 + */ + ICMeasureStepHrStart, + + /* + * 测量心率结束 (ICWeightData) + */ + ICMeasureStepHrResult, + + /* + * 测量结束 + */ + ICMeasureStepMeasureOver, + +} ICMeasureStep; + + + +/** + * 跳绳模式 + */ +typedef enum : NSUInteger { + /** + * 自由跳 + */ + ICSkipModeFreedom = 0, + + /** + * 计时跳 + */ + ICSkipModeTiming, + + /** + * 计次跳 + */ + ICSkipModeCount, + + /** + * 计时间歇跳 + */ + ICSkipModeInterruptTime, + + /** + * 计次间歇跳 + */ + ICSkipModeInterruptCount, + +} ICSkipMode; + +/** + * 升级状态 + */ +typedef NS_ENUM(NSUInteger, ICUpgradeStatus) { + /** + * 升级成功 + */ + ICUpgradeStatusSuccess, + /** + * 升级中 + */ + ICUpgradeStatusUpgrading, + /** + * 升级失败 + */ + ICUpgradeStatusFail, + /** + * 升级失败,文件无效 + */ + ICUpgradeStatusFailFileInvalid, + /** + * 升级失败,设备不支持升级 + */ + ICUpgradeStatusFailNotSupport, +}; + + +/** + * Wifi配网状态 + */ +typedef NS_ENUM(NSUInteger, ICConfigWifiState) { + ICConfigWifiStateSuccess, + ICConfigWifiStateWifiConnecting, + ICConfigWifiStateServerConnecting, + ICConfigWifiStateWifiConnectFail, + ICConfigWifiStateServerConnectFail, + ICConfigWifiStatePasswordFail, + ICConfigWifiStateFail, +}; + + +/* + * 跳绳灯效模式 + */ +typedef NS_ENUM(NSUInteger, ICSkipLightMode) { + /* + * 无 + */ + ICSkipLightModeNone, + /* + * 速度模式 + */ + ICSkipLightModeRPM, + /* + * 计时模式 + */ + ICSkipLightModeTimer, + /* + * 计次模式 + */ + ICSkipLightModeCount, + /* + * 百分比模式 + */ + ICSkipLightModePercent, + /* + * 绊绳次数模式 + */ + ICSkipLightModeTripRope, + /* + * 测量模式模式 + */ + ICSkipLightModeMeasuring, +}; + +/* + * 语音类型 + */ +typedef NS_ENUM(NSUInteger, ICSkipSoundType) { + /* + * 无 + */ + ICSkipSoundTypeNone, + /* + * 标准中文女声 + */ + ICSkipSoundTypeFemale, + /* + * 标准中文男声 + */ + ICSkipSoundTypeMale, +}; +/* + * 语音模式 + */ +typedef NS_ENUM(NSUInteger, ICSkipSoundMode) { + /* + * 无 + */ + ICSkipSoundModeNone, + /* + * 按间隔时长 + */ + ICSkipSoundModeTime, + /* + * 按间隔个数 + */ + ICSkipSoundModeCount, +}; + +/* + * 升级模式 + */ +typedef NS_ENUM(NSUInteger, ICOTAMode) { + /* + * 自动模式 + */ + ICOTAModeAuto, + /* + * 模式1 + */ + ICOTAMode1, + /* + * 模式2 + */ + ICOTAMode2, + /* + * 模式3 + */ + ICOTAMode3, +}; + +/* + * 跳绳状态 + */ + +typedef NS_ENUM(NSUInteger, ICSkipStatus) { + /* + * 跳绳中 + */ + ICSkipStatusJumping, + /* + * 跳绳结束 + */ + ICSkipStatusJumpOver, + /* + * 跳绳休息中 + */ + ICSkipStatusRest, +}; + +#endif /* ICConstant_h */ diff --git a/ios/Classes/Headers/ICCoordData.h b/ios/Classes/Headers/ICCoordData.h new file mode 100644 index 0000000..7f5ae51 --- /dev/null +++ b/ios/Classes/Headers/ICCoordData.h @@ -0,0 +1,31 @@ +// +// ICCoordData.h +// ICDeviceManager +// +// Created by Symons on 2018/8/10. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import + +/** + 坐标数据 + */ +@interface ICCoordData : NSObject + +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + x坐标 + */ +@property (nonatomic, assign) NSInteger x; + +/** + y坐标 + */ +@property (nonatomic, assign) NSInteger y; + +@end diff --git a/ios/Classes/Headers/ICDevice.h b/ios/Classes/Headers/ICDevice.h new file mode 100644 index 0000000..44a2814 --- /dev/null +++ b/ios/Classes/Headers/ICDevice.h @@ -0,0 +1,21 @@ +// +// ICDevice.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import + +/** + 沃莱设备类 + */ +@interface ICDevice : NSObject + +/** + 设备mac地址 + */ +@property (nonatomic, copy) NSString *macAddr; + +@end diff --git a/ios/Classes/Headers/ICDeviceInfo.h b/ios/Classes/Headers/ICDeviceInfo.h new file mode 100644 index 0000000..89216d0 --- /dev/null +++ b/ios/Classes/Headers/ICDeviceInfo.h @@ -0,0 +1,31 @@ +// +// ICDeviceInfo.h +// ICDeviceManager +// +// Created by Symons on 2020/4/29. +// Copyright © 2020 Symons. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ICDeviceInfo : NSObject + +@property(nonatomic, strong) NSString *mac; + +@property(nonatomic, strong) NSString *model; + +@property(nonatomic, strong) NSString *sn; + +@property(nonatomic, strong) NSString *firmwareVer; + +@property(nonatomic, strong) NSString *hardwareVer; + +@property(nonatomic, strong) NSString *softwareVer; + +@property(nonatomic, strong) NSString *manufactureName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICDeviceManager.h b/ios/Classes/Headers/ICDeviceManager.h new file mode 100644 index 0000000..354b5b6 --- /dev/null +++ b/ios/Classes/Headers/ICDeviceManager.h @@ -0,0 +1,129 @@ +// +// ICDeviceManager.h +// ICDeviceManager +// +// Created by Symons on 2018/7/27. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICDeviceManagerDelegate.h" +#import "ICDeviceManagerSettingManager.h" +#import "ICModels_Inc.h" +#import "ICCallback_Inc.h" +#import "ICBodyFatAlgorithmsManager.h" + + +@interface ICDeviceManager : NSObject + +/** + 数据以及状态回调 + */ +@property (nonatomic, weak) id delegate; + +/** + 蓝牙设备管理单例对象 + + @return 蓝牙设备管理单例对象 + */ ++ (instancetype)shared; + +/** + 初始化SDK(默认配置) + */ +- (void)initMgr; + +/** + 使用配置类来初始化SDK + + @param config 配置项 + */ +- (void)initMgrWithConfig:(ICDeviceManagerConfig *)config; + +/** +释放 +*/ +- (void)deInit; + +/** + 更新用户信息 + + @param userInfo 用户信息 + */ +- (void)updateUserInfo:(ICUserInfo *)userInfo; + +- (void)setUserList:(NSArray *)userlist; + +/** + 扫描设备 + + @param delegate 扫描回调 + */ +- (void)scanDevice:(id)delegate; + +/** + 停止扫描 + */ +- (void)stopScan; + +/** + 添加设备 + */ +- (void)addDevice:(ICDevice *)device callback:(ICAddDeviceCallBack)callback; + +/** + 添加设备列表(注:有多少个device就会通过block回调多少次) + */ +- (void)addDevices:(NSArray *)devices callback:(ICAddDeviceCallBack)callback; + +/** + 删除设备 + */ +- (void)removeDevice:(ICDevice *)device callback:(ICRemoveDeviceCallBack)callback; + +/** + 删除设备列表(注:有多少个device就会通过block回调多少次) + */ +- (void)removeDevices:(NSArray *)devices callback:(ICRemoveDeviceCallBack)callback; + +- (void)upgradeDevice:(ICDevice *)device filePath:(NSString *)filePath mode:(ICOTAMode)mode; + +- (void)stopUpgradeDevice:(ICDevice *)device; + +- (void)upgradeDevices:(NSArray *)devices filePath:(NSString *)filePath mode:(ICOTAMode)mode; + +/** + 获取设备设置接口 + + @return 设备设置接口实例 + */ +- (id)getSettingManager; + +/** + 获取体脂算法接口 + + @return 体脂算法接口实例 + */ +- (id)getBodyFatAlgorithmsManager; + +/** + 蓝牙是否已经开启 + @notice 请在初始化回调成功后再调用,否则将返回NO + */ +- (BOOL)isBLEEnable; + +/** + SDK版本 + + @return SDK版本 + */ ++ (NSString *)version; + +/** + sdk日志文件夹路径,仅保留最近7天的日志 + + @return 日志文件夹路径 + */ +- (NSString *)getLogPath; + +@end diff --git a/ios/Classes/Headers/ICDeviceManagerConfig.h b/ios/Classes/Headers/ICDeviceManagerConfig.h new file mode 100644 index 0000000..0ed7ede --- /dev/null +++ b/ios/Classes/Headers/ICDeviceManagerConfig.h @@ -0,0 +1,30 @@ +// +// ICDeviceManagerConfig.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import + +/** + SDK配置类,用于配置SDK + */ +@interface ICDeviceManagerConfig : NSObject + +/** + 蓝牙未打开时,打开app是否弹出的蓝牙未打开对话框(默认:YES) + */ +@property (nonatomic, assign) BOOL isShowPowerAlert; + + +/** + 是否自动填充连接秤的阻抗(默认:NO) + */ +@property (nonatomic, assign) BOOL is_fill_adc; + + + + +@end diff --git a/ios/Classes/Headers/ICDeviceManagerDelegate.h b/ios/Classes/Headers/ICDeviceManagerDelegate.h new file mode 100644 index 0000000..c611f78 --- /dev/null +++ b/ios/Classes/Headers/ICDeviceManagerDelegate.h @@ -0,0 +1,226 @@ +// +// ICDeviceManagerDelegate.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICModels_Inc.h" + +@protocol ICDeviceManagerDelegate + +@required +/** + SDKc初始化完成回调 + + @param bSuccess 初始化是否成功 + */ +- (void)onInitFinish:(BOOL)bSuccess; + +@optional + +/** + 蓝牙改变状态回调 + + @param state 蓝牙状态 + */ +- (void)onBleState:(ICBleState)state; + +/** + 设备连接状态回调 + + @param device 设备 + @param state 连接状态 + */ +- (void)onDeviceConnectionChanged:(ICDevice *)device state:(ICDeviceConnectState)state; + +/** + 节点设备连接状态回调 + + @param device 设备 + @param nodeId 设备 + @param state 连接状态 + */ +- (void)onNodeConnectionChanged:(ICDevice *)device nodeId:(NSUInteger)nodeId state:(ICDeviceConnectState)state; + + +/** + 体重秤数据回调 + + @param device 设备 + @param data 测量数据 + */ +- (void)onReceiveWeightData:(ICDevice *)device data:(ICWeightData *)data; + + +/** + 厨房秤数据回调 + + @param device 设备 + @param data 测量数据 + */ +- (void)onReceiveKitchenScaleData:(ICDevice *)device data:(ICKitchenScaleData *)data; + + +/** + 厨房秤单位改变 + + @param device 设备 + @param unit 改变后的单位 + */ +- (void)onReceiveKitchenScaleUnitChanged:(ICDevice *)device unit:(ICKitchenScaleUnit)unit; + + +/** + 平衡秤坐标数据回调 + + @param device 设备 + @param data 测量坐标数据 + */ +- (void)onReceiveCoordData:(ICDevice *)device data:(ICCoordData *)data; + +/** + 围尺数据回调 + + @param device 设备 + @param data 测量数据 + */ +- (void)onReceiveRulerData:(ICDevice *)device data:(ICRulerData *)data; + +/** + 围尺历史数据回调 + + @param device 设备 + @param data 测量数据 + */ +- (void)onReceiveRulerHistoryData:(ICDevice *)device data:(ICRulerData *)data; + +/** + 平衡数据回调 + + @param device 设备 + @param data 平衡数据 + */ +- (void)onReceiveWeightCenterData:(ICDevice *)device data:(ICWeightCenterData *)data; + +/** + 设备单位改变回调 + + @param device 设备 + @param unit 设备当前单位 + */ +- (void)onReceiveWeightUnitChanged:(ICDevice *)device unit:(ICWeightUnit)unit; + + +/** + 围尺单位改变回调 + + @param device 设备 + @param unit 设备当前单位 + */ +- (void)onReceiveRulerUnitChanged:(ICDevice *)device unit:(ICRulerUnit)unit; + +/** + 围尺测量模式改变回调 + + @param device 设备 + @param mode 设备当前测量模式 + */ +- (void)onReceiveRulerMeasureModeChanged:(ICDevice *)device mode:(ICRulerMeasureMode)mode; + + +/** + 4个传感器数据回调 + + @param device 设备 + @param data 传感器数据 + */ +- (void)onReceiveElectrodeData:(ICDevice *)device data:(ICElectrodeData *)data; + +/** + 分步骤体重、平衡、阻抗、心率数据回调 + + @param device 设备 + @param step 当前处于的步骤 + @param data 数据 + */ +- (void)onReceiveMeasureStepData:(ICDevice *)device step:(ICMeasureStep)step data:(NSObject *)data; + +/** + 体重历史数据回调 + + @param device 设备 + @param data 体重历史数据 + */ +- (void)onReceiveWeightHistoryData:(ICDevice *)device data:(ICWeightHistoryData *)data; + + +/** + 跳绳实时数据回调 + + @param device 设备 + @param data 体重历史数据 + */ +- (void)onReceiveSkipData:(ICDevice *)device data:(ICSkipData *)data; + + +/** + 跳绳历史数据回调 + + @param device 设备 + @param data 跳绳历史数据 + */ +- (void)onReceiveHistorySkipData:(ICDevice *)device data:(ICSkipData *)data; + +/** + 跳绳电量,后续使用onReceiveBattery + + @param device 设备 + @param battery 电量,范围:0~100 + */ +//- (void)onReceiveSkipBattery:(ICDevice *)device battery:(NSUInteger)battery; + +/** + 电量 + + @param device 设备 + @param battery 电量,范围:0~100 + @param ext 扩展字段,如是基站跳绳,则该字段的值表示节点ID,类型:NSNumber + */ +- (void)onReceiveBattery:(ICDevice *)device battery:(NSUInteger)battery ext:(NSObject *)ext; + +/** + 设备升级状态回调 + @param device 设备 + @param status 升级状态 + @param percent 升级进度,范围:0~100 + */ +- (void)onReceiveUpgradePercent:(ICDevice *)device status:(ICUpgradeStatus)status percent:(NSUInteger)percent; + +/** + 设备信息回调 + + @param device 设备 + @param deviceInfo 设备信息 + */ +- (void)onReceiveDeviceInfo:(ICDevice *)device deviceInfo:(ICDeviceInfo *)deviceInfo; + +/** + * 配网结果回调 + * @param device 设备 + * @param state 配网状态 + */ +- (void)onReceiveConfigWifiResult:(ICDevice *)device state:(ICConfigWifiState)state; + + +/** + 心率 + + @param device 设备 + @param hr 心率,范围:0~255 + */ +- (void)onReceiveHR:(ICDevice *)device hr:(int)hr; + +@end diff --git a/ios/Classes/Headers/ICDeviceManagerSettingManager.h b/ios/Classes/Headers/ICDeviceManagerSettingManager.h new file mode 100644 index 0000000..1ac5e12 --- /dev/null +++ b/ios/Classes/Headers/ICDeviceManagerSettingManager.h @@ -0,0 +1,248 @@ +// +// LSSettingManager.h +// ICDeviceManager +// +// Created by lifesense-mac on 17/3/20. +// Copyright © 2017年 Symons. All rights reserved. +// + +#import +#import "ICModels_Inc.h" + +@class ICDevice; + + +/** + 设置回调 + + @param code 设置回调代码 + */ +typedef void(^ICSettingCallback)(ICSettingCallBackCode code); + +/** + 设备设置 + */ +@protocol ICDeviceManagerSettingManager + +/** + 设置称单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ +- (void)setScaleUnit:(ICDevice *)device unit:(ICWeightUnit)unit callback:(ICSettingCallback)callback; + +/** + 设置围尺单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ +- (void)setRulerUnit:(ICDevice *)device unit:(ICRulerUnit)unit callback:(ICSettingCallback)callback; + +/** + 设置当前围尺身体部位 + + @param device 设备 + @param type 身体部位 + @param callback 回调 + */ +- (void)setRulerBodyPartsType:(ICDevice *)device type:(ICRulerBodyPartsType)type callback:(ICSettingCallback)callback; + +/** + 设置重量到厨房秤,单位:毫克 + + @param device 设备 + @param weight 重量,单位:毫克,最大不能超过65535毫克 + @param callback 回调 + */ +- (void)setWeight:(ICDevice *)device weight:(NSInteger)weight callback:(ICSettingCallback)callback; + +/** + 设置厨房秤去皮重量 + + @param device 设备 + @param callback 回调 + */ +- (void)deleteTareWeight:(ICDevice *)device callback:(ICSettingCallback)callback; +/** +设置厨房秤关机 + +@param device 设备 +@param callback 回调 +*/ +- (void)powerOffKitchenScale:(ICDevice *)device callback:(ICSettingCallback)callback; + +/** + 设置厨房秤计量单位 + + @param device 设备 + @param unit 单位,注:如果秤不支持该单位,将不会生效 + @param callback 回调 + */ +- (void)setKitchenScaleUnit:(ICDevice *)device unit:(ICKitchenScaleUnit)unit callback:(ICSettingCallback)callback; + +/** + 设置营养成分值到厨房秤 + + @param device 设备 + @param type 营养类型 + @param value 营养值 + @param callback 回调 + */ +- (void)setNutritionFacts:(ICDevice *)device type:(ICKitchenScaleNutritionFactType)type value:(NSInteger)value callback:(ICSettingCallback)callback; + +/** + 设置围尺测量模式 + + @param device 设备 + @param mode 测量模式 + @param callback 回调 + */ +- (void)setRulerMeasureMode:(ICDevice *)device mode:(ICRulerMeasureMode)mode callback:(ICSettingCallback)callback; + + +/** + * 开始跳绳 + * @param device 设备 + * @param mode 跳绳模式 + * @param param 模式参数 + * @param callback 回调 + */ +- (void)startSkip:(ICDevice *)device mode:(ICSkipMode)mode param:(NSUInteger)param callback:(ICSettingCallback)callback; + + +/** + * 开始跳绳 + * @param device 设备 + * @param param 模式参数 + * @param callback 回调 + */ +- (void)startSkipExt:(ICDevice *)device param:(ICSkipParam *)param callback:(ICSettingCallback)callback; + + +/** + * 暂停跳绳 + * @param device 设备 + * @param callback 回调 + */ +//- (void)pauseSkip:(ICDevice *)device callback:(ICSettingCallback)callback; + + + +/** + * 恢复跳绳 + * @param device 设备 + * @param callback 回调 + */ +//- (void)resumeSkip:(ICDevice *)device callback:(ICSettingCallback)callback; + + + +/** + * 停止跳绳 + * @param device 设备 + * @param callback 回调 + */ +- (void)stopSkip:(ICDevice *)device callback:(ICSettingCallback)callback; + +/** + 设置用户信息给设备,调用该接口后,updateUserInfo接口将不会再对该设备生效 + 注意:目前仅跳绳设备支持 + +@param device 设备 +@param userInfo 用户信息 +*/ +- (void)setUserInfo:(ICDevice *)device userInfo:(ICUserInfo *)userInfo; + + +/** + 双模设备配网 + +@param device 设备 +@param ssid WIFI SSID +@param password WIFI Password +*/ +- (void)configWifi:(ICDevice *)device ssid:(NSString *)ssid password:(NSString *)password callback:(ICSettingCallback)callback; + +/** + 双模设备更换设备域名 + +@param device 设备 +@param server App服务器域名,如:https://www.google.com +*/ +- (void)setServerUrl:(ICDevice *)device server:(NSString *)server callback:(ICSettingCallback)callback; + + + +/** + 设置厂商特定参数 + + @param device 设备 + @param type 根据客户意思不一样 + */ +- (void)setOtherParams:(ICDevice *)device type:(NSUInteger)type param:(NSObject *)param callback:(ICSettingCallback)callback; + + +/** + * 设置跳绳设备灯效 + * @param device 设备 + * @param lightEffects 跳绳灯效颜色 + * @param mode 等效的模式 + * @param callback 回调 + */ +- (void)setSkipLightSetting:(ICDevice *)device lightEffects:(NSArray *)lightEffects mode:(ICSkipLightMode)mode callback:(ICSettingCallback)callback; + + +/** + * 设置设备显示的项 + * @param device 设备 + * @param items UI项 + * @param callback 回调 + */ +- (void)setScaleUIItems:(ICDevice *)device items:(NSArray *)items callback:(ICSettingCallback)callback; + + + +/* + * 下发准备 + * @param device 基站设备 + * @param callback 回调 + */ +- (void)lockStSkip:(ICDevice *)device callback:(ICSettingCallback)callback; + +/* + * 查询在线状态 + * @param device 基站设备 + * @param callback 回调 + */ +- (void)queryStAllNode:(ICDevice *)device callback:(ICSettingCallback)callback; + +/* + * 改变广播名 + * @param device 基站设备 + * @param name 广播名 + * @param callback 回调 + */ +- (void)changeStName:(ICDevice *)device name:(NSString *)name callback:(ICSettingCallback)callback; + +/* + * 改变节点ID + * @param device 基站设备 + * @param dstId 节点设备更改后ID + * @param callback 回调 + */ +- (void)changeStNo:(ICDevice *)device dstId:(NSUInteger)dstId st_no:(NSUInteger)st_no callback:(ICSettingCallback)callback; + +/** + * 设置跳绳设备音效 + * @param device 设备 + * @param config 音效设置 + * @param callback 回调 + */ +- (void)setSkipSoundSetting:(ICDevice *)device config:(ICSkipSoundSettingData *)config callback:(ICSettingCallback)callback; + + +@end diff --git a/ios/Classes/Headers/ICElectrodeData.h b/ios/Classes/Headers/ICElectrodeData.h new file mode 100644 index 0000000..9350bb5 --- /dev/null +++ b/ios/Classes/Headers/ICElectrodeData.h @@ -0,0 +1,39 @@ +// +// ICElectrodeData.h +// ICDeviceManager +// +// Created by Symons on 2019/3/12. +// Copyright © 2019 Symons. All rights reserved. +// + +#import + + +/** + 电极数据 + */ +@interface ICElectrodeData : NSObject + +/** + 左上重量(单位:kg) + */ +@property (nonatomic, assign) NSUInteger weightLT_kg; + +/** + 左下重量(单位:kg) + */ +@property (nonatomic, assign) NSUInteger weightLB_kg; + +/** + 右上重量(单位:kg) + */ +@property (nonatomic, assign) NSUInteger weightRT_kg; + +/** + 右下重量(单位:kg) + */ +@property (nonatomic, assign) NSUInteger weightRB_kg; + + +@end + diff --git a/ios/Classes/Headers/ICKitchenDeviceInfoExt.h b/ios/Classes/Headers/ICKitchenDeviceInfoExt.h new file mode 100644 index 0000000..b5cc009 --- /dev/null +++ b/ios/Classes/Headers/ICKitchenDeviceInfoExt.h @@ -0,0 +1,17 @@ +// +// ICKitchenDeviceInfoExt.h +// ICDeviceManager +// +// Created by Symons on 2020/4/29. +// Copyright © 2020 Symons. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ICKitchenDeviceInfoExt : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICKitchenScaleData.h b/ios/Classes/Headers/ICKitchenScaleData.h new file mode 100644 index 0000000..108ebd1 --- /dev/null +++ b/ios/Classes/Headers/ICKitchenScaleData.h @@ -0,0 +1,145 @@ +// +// ICKitchenScaleData.h +// ICDeviceManager +// +// Created by Symons on 2018/8/20. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +/** + 厨房秤数据 + */ +@interface ICKitchenScaleData : NSObject + +/** + 数据是否稳定数, 不稳定的数据只做展示用,请勿保存 + */ +@property (nonatomic, assign) BOOL isStabilized; + +/** + 数据值,单位:mg + */ +@property (nonatomic, assign) NSUInteger value_mg; + +/** + 数据值,单位:G + */ +@property (nonatomic, assign) float value_g; + +/** + 数据值,单位:ml + */ +@property (nonatomic, assign) float value_ml; + +/** + 数据值,单位:ml milk + */ +@property (nonatomic, assign) float value_ml_milk; + +/** + 数据值,单位:oz + */ +@property (nonatomic, assign) float value_oz; + +/** + 数据值,单位:lb:oz中的lb + */ +@property (nonatomic, assign) NSUInteger value_lb; + +/** + 数据值,单位:lb:oz中的oz + */ +@property (nonatomic, assign) float value_lb_oz; + +/** + 数据值,单位:fl.oz + */ +@property (nonatomic, assign) float value_fl_oz; + +/** + 数据值,单位:fl.oz,英制 + */ +@property (nonatomic, assign) float value_fl_oz_uk; + +/** + 数据值,单位:fl.oz,美制 + */ +@property (nonatomic, assign) float value_fl_oz_milk; + +/** + 数据值,单位:fl.oz,英制 + */ +@property (nonatomic, assign) float value_fl_oz_milk_uk; +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + 本次数据单位 + */ +@property (nonatomic, assign) ICKitchenScaleUnit unit; + +/** + 小数点位数,如:value_g=70.12,则precision=2,value_g=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_g ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_ml ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_lboz ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_oz ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_ml_milk ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_floz_us ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_floz_uk ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_floz_milk_us ; +/** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ +@property (nonatomic, assign) NSUInteger precision_floz_milk_uk ; + +/** + 设备数据单位类型,0:公制,1:美制,2:英制 + */ +@property (nonatomic, assign) NSUInteger unitType; + + +/** + 数字是否负数 + */ +@property (nonatomic, assign) BOOL isNegative; + +/** + 是否去皮模式 + */ +@property (nonatomic, assign) BOOL isTare; + + + +@end diff --git a/ios/Classes/Headers/ICModels_Inc.h b/ios/Classes/Headers/ICModels_Inc.h new file mode 100644 index 0000000..0c1e7a2 --- /dev/null +++ b/ios/Classes/Headers/ICModels_Inc.h @@ -0,0 +1,35 @@ +// +// model_inc.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#ifndef model_inc_h +#define model_inc_h + +#import "ICDevice.h" +#import "ICScanDeviceInfo.h" +#import "ICUserInfo.h" +#import "ICSkipParam.h" + +#import "ICWeightData.h" +#import "ICWeightHistoryData.h" + +#import "ICRulerData.h" +#import "ICCoordData.h" +#import "ICKitchenScaleData.h" +#import "ICWeightCenterData.h" +#import "ICElectrodeData.h" +#import "ICSkipData.h" +#import "ICDeviceInfo.h" +#import "ICScaleDeviceInfo.h" +#import "ICKitchenDeviceInfoExt.h" + +#import "ICConstant.h" +#import "ICDeviceManagerConfig.h" +#import "ICSkipLightSettingData.h" +#import "ICSkipSoundSettingData.h" + +#endif /* model_inc_h */ diff --git a/ios/Classes/Headers/ICRulerData.h b/ios/Classes/Headers/ICRulerData.h new file mode 100644 index 0000000..4be4c6f --- /dev/null +++ b/ios/Classes/Headers/ICRulerData.h @@ -0,0 +1,80 @@ +// +// ICRulerData.h +// ICDeviceManager +// +// Created by Symons on 2018/8/9. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +/** + 围尺数据 + */ +@interface ICRulerData : NSObject + +/** + 数据是否稳定 + @notice 如果数据不稳定,则只有distance有效,不稳定的数据只做展示用,请勿保存 + */ +@property (nonatomic, assign) BOOL isStabilized; + +/** + 距离inch + */ +@property (nonatomic, assign) float distance_in; + +/** + 距离cm + */ +@property (nonatomic, assign) float distance_cm; + + +/** + 距离ft + */ +@property (nonatomic, assign) NSUInteger distance_ft; + +/** + 距离ft_in + */ +@property (nonatomic, assign) float distance_ft_in; + + +/** + 测量长度(0.1mm) + */ +@property (nonatomic, assign) NSUInteger distance; + +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + 身体部位类型 + */ +@property (nonatomic, assign) ICRulerBodyPartsType partsType; + +/** + inch距离小数点位数,如:distance_in=70.12,则precision_in=2,distance_in=71.5,则precision_in=1 + */ +@property (nonatomic, assign) NSUInteger precision_in; + +/** + cm距离小数点位数,如:distance_cm=70.12,则precision_cm=2,distance_cm=71.5,则precision_cm=1 + */ +@property (nonatomic, assign) NSUInteger precision_cm; + +/** + 本次测量的单位 + */ +@property (nonatomic, assign) ICRulerUnit unit; + +/** + 本次的测量模式 + */ +@property (nonatomic, assign) ICRulerMeasureMode mode; + +@end diff --git a/ios/Classes/Headers/ICScaleDeviceInfo.h b/ios/Classes/Headers/ICScaleDeviceInfo.h new file mode 100644 index 0000000..0ae9caf --- /dev/null +++ b/ios/Classes/Headers/ICScaleDeviceInfo.h @@ -0,0 +1,73 @@ +// +// ICScaleDeviceInfo.h +// ICDeviceManager +// +// Created by Symons on 2020/4/29. +// Copyright © 2020 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" +#import "ICDeviceInfo.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ICScaleDeviceInfo : ICDeviceInfo + +@property(nonatomic, assign) NSUInteger kg_scale_division; + +@property(nonatomic, assign) NSUInteger lb_scale_division; + +@property(nonatomic, assign) BOOL isSupportHr; + +@property(nonatomic, assign) BOOL isSupportGravity; + +@property(nonatomic, assign) BOOL isSupportBalance; + +@property(nonatomic, assign) BOOL isSupportOTA; + +@property(nonatomic, assign) BOOL isSupportOffline; + +@property(nonatomic, assign) NSUInteger bfDataCalcType; + +@property(nonatomic, assign) BOOL isSupportUserInfo; + +@property(nonatomic, assign) NSUInteger maxUserCount; + +@property(nonatomic, assign) NSUInteger batteryType; + +@property(nonatomic, assign) ICBFAType bfaType; + +@property(nonatomic, assign) ICBFAType bfaType2; + +@property(nonatomic, assign) BOOL isSupportUnitKg; + +@property(nonatomic, assign) BOOL isSupportUnitLb; + +@property(nonatomic, assign) BOOL isSupportUnitStLb; + +@property(nonatomic, assign) BOOL isSupportUnitJin; + +@property(nonatomic, assign) NSUInteger pole; + +@property(nonatomic, assign) NSUInteger isSupportChangePole; + +@property(nonatomic, assign) NSUInteger impendenceType; + +@property(nonatomic, assign) NSUInteger impendenceProperty; + +@property(nonatomic, assign) NSUInteger impendencePrecision; + +@property(nonatomic, assign) NSUInteger impendenceCount; + +@property(nonatomic, assign) BOOL enableMeasureImpendence; + +@property(nonatomic, assign) BOOL enableMeasureHr; + +@property(nonatomic, assign) BOOL enableMeasureBalance; + +@property(nonatomic, assign) BOOL enableMeasureGravity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICScanDeviceDelegate.h b/ios/Classes/Headers/ICScanDeviceDelegate.h new file mode 100644 index 0000000..8b5fcb7 --- /dev/null +++ b/ios/Classes/Headers/ICScanDeviceDelegate.h @@ -0,0 +1,22 @@ +// +// ICScanDeviceDelegate.h +// ICDeviceManager +// + +#import + +@class ICScanDeviceInfo; + +/** + 扫描结果回调代理 + */ +@protocol ICScanDeviceDelegate + +/** + 扫描结果回调 + + @param deviceInfo 扫描到的设备 + */ +- (void)onScanResult:(ICScanDeviceInfo *)deviceInfo; + +@end diff --git a/ios/Classes/Headers/ICScanDeviceInfo.h b/ios/Classes/Headers/ICScanDeviceInfo.h new file mode 100644 index 0000000..298787c --- /dev/null +++ b/ios/Classes/Headers/ICScanDeviceInfo.h @@ -0,0 +1,68 @@ +// +// ICScanDeviceInfo.h +// ICDeviceManager +// +// Created by Symons on 2018/7/28. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +/** + 扫描到的蓝牙设备信息 + */ +@interface ICScanDeviceInfo : NSObject + +/** + 广播名 + */ +@property (nonatomic, strong) NSString *name; + +/** + 设备类型 + */ +@property (nonatomic, assign) ICDeviceType type; + +/** + 设备子类型 + */ +@property (nonatomic, assign) ICDeviceSubType subType; + +/** + 设备通讯方式 + */ +@property (nonatomic, assign) ICDeviceCommunicationType communicationType; + +/** + mac地址 + */ +@property (nonatomic, strong) NSString *macAddr; + +/** + 服务ID列表 + */ +@property (nonatomic, strong) NSArray *services; + +/** + 信号强度(越小越大,0:系统配对设备,-128:信号值有误) + */ +@property (nonatomic, assign) NSInteger rssi; + +/** + 基站随机码 +*/ +@property (nonatomic, assign) NSUInteger st_no; + +/** + 节点ID +*/ +@property (nonatomic, assign) NSUInteger nodeId; + +/** + 设备标记,0表示没有 + */ +@property (nonatomic, assign) NSUInteger deviceFlag; + + +@end diff --git a/ios/Classes/Headers/ICSkipData.h b/ios/Classes/Headers/ICSkipData.h new file mode 100644 index 0000000..45df1dc --- /dev/null +++ b/ios/Classes/Headers/ICSkipData.h @@ -0,0 +1,204 @@ +// +// ICSkipData.h +// ICDeviceManager +// +// Created by Symons on 2019/10/19. +// Copyright © 2019 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +NS_ASSUME_NONNULL_BEGIN + + + +/** + * 间歇跳数据 + */ +@interface ICSkipInterruptData : NSObject + +/** + * 序号 + */ +@property (nonatomic, assign) NSUInteger index; + +/** + * 休息时间 + */ +@property (nonatomic, assign) NSUInteger rest_time; + + +/** + * 时长 + */ +@property (nonatomic, assign) NSUInteger time; + +/** + * 跳的个数 + */ +@property (nonatomic, assign) NSUInteger skip_count; + + +/** + * 热量消耗 + */ +@property (nonatomic, assign) double calories_burned; + +/** + * 平均速度 + */ +@property (nonatomic, assign) NSUInteger avg_freq; + +/** + * 绊绳次数 + */ +@property (nonatomic, assign) NSUInteger freq_count; + +@end + + + +/** + * 跳绳频次 + */ +@interface ICSkipFreqData : NSObject + +/** + * 持续时间 + */ +@property (nonatomic, assign) NSUInteger duration; + +/** + * 次数 + */ +@property (nonatomic, assign) NSUInteger skip_count; + +@end + + + +/** + * 跳绳数据 + */ +@interface ICSkipData : NSObject + + + /** + 是否稳定 + */ + @property (nonatomic, assign) BOOL isStabilized; + + /** + 节点ID + */ + @property (nonatomic, assign) NSUInteger nodeId; + /** + 节点电量 + */ + @property (nonatomic, assign) NSUInteger battery; + /** + 节点信息 + */ + @property (nonatomic, assign) NSUInteger nodeInfo; + + /** + 跳绳状态,非所有设备都有,目前仅S2有 + */ + @property (nonatomic, assign) ICSkipStatus status; + + /** + 节点Mac + */ +// @property (nonatomic, strong) NSString* nodeMac; + + + /** + * 组数,仅S2有 + */ + @property (nonatomic, assign) NSUInteger setting_group; + + /** + * 设置休息时间,仅S2有 + */ + @property (nonatomic, assign) NSUInteger setting_rest_time; + + /** + * 测量时间,单位:秒 + */ + @property (nonatomic, assign) NSUInteger time; + + /** + * 跳绳模式 + */ + @property (nonatomic, assign) ICSkipMode mode; + + /** + * 设置的参数 + */ + @property (nonatomic, assign) NSUInteger setting; + + /** + * 跳绳使用的时间 + */ + @property (nonatomic, assign) NSUInteger elapsed_time; + + /** + * 跳绳实际使用的时间,不是所有都支持 + */ + @property (nonatomic, assign) NSUInteger actual_time; + + + /** + * 跳的次数 + */ + @property (nonatomic, assign) NSUInteger skip_count; + + /** + * 平均频次 + */ + @property (nonatomic, assign) NSUInteger avg_freq; + + /** + * 当前速度,仅S2有 + */ +// @property (nonatomic, assign) NSUInteger cur_speed; + + /** + * 最快频次 + */ + @property (nonatomic, assign) NSUInteger fastest_freq; + + /** + * 热量消耗 + */ + @property (nonatomic, assign) double calories_burned; + + /** + * 燃脂效率 + */ + @property (nonatomic, assign) double fat_burn_efficiency; + + /** + * 绊绳总数 + */ + @property (nonatomic, assign) NSUInteger freq_count; + + /** + * 最多连跳 + */ + @property (nonatomic, assign) NSUInteger most_jump; + + /** + * 跳绳频次数据 + */ + @property (nonatomic, strong) NSArray *freqs; + + /** + * 间歇跳数据 + */ + @property (nonatomic, strong) NSArray *interrupts; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICSkipLightSettingData.h b/ios/Classes/Headers/ICSkipLightSettingData.h new file mode 100644 index 0000000..896712f --- /dev/null +++ b/ios/Classes/Headers/ICSkipLightSettingData.h @@ -0,0 +1,38 @@ +// +// ICSkipLightSettingData.h +// ICDeviceManager +// +// Created by Symons on 2021/8/6. +// Copyright © 2021 Symons. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ICSkipLightSettingData : NSObject + + +/** + 红色(0~255) + */ +@property (nonatomic, assign) NSUInteger r; + +/** + 绿色(0~255) + */ +@property (nonatomic, assign) NSUInteger g; + +/** + 蓝色(0~255) + */ +@property (nonatomic, assign) NSUInteger b; + +/** + 速度(0~255) + */ +@property (nonatomic, assign) NSUInteger modeValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICSkipParam.h b/ios/Classes/Headers/ICSkipParam.h new file mode 100644 index 0000000..53617a7 --- /dev/null +++ b/ios/Classes/Headers/ICSkipParam.h @@ -0,0 +1,40 @@ +// +// ICSkipParam.h +// ICDeviceManager +// +// Created by symons on 2022/9/21. +// Copyright © 2022 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ICSkipParam : NSObject + +/** + 模式 + */ +@property (nonatomic, assign) ICSkipMode mode; + +/** + 跳绳参数/ 间歇跳,单轮时长/单轮次数(S2) + + */ +@property (nonatomic, assign) NSUInteger param; + +/** + 间歇跳,单轮休息时长 + */ +@property (nonatomic, assign) NSUInteger rest_time; + +/** + 间歇跳,组数 + */ +@property (nonatomic, assign) NSUInteger group; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICSkipSoundSettingData.h b/ios/Classes/Headers/ICSkipSoundSettingData.h new file mode 100644 index 0000000..a5d4334 --- /dev/null +++ b/ios/Classes/Headers/ICSkipSoundSettingData.h @@ -0,0 +1,34 @@ +// +// ICSkipSoundSettingData.h +// ICDeviceManager +// +// Created by icomon on 2022/3/16. +// Copyright © 2022 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ICSkipSoundSettingData : NSObject + +/// 是否开启语音开关 +@property (nonatomic, assign) BOOL soundOn; +/// 语音类型 +@property (nonatomic, assign) ICSkipSoundType soundType; +/// 声音大小 +@property (nonatomic, assign) NSUInteger soundVolume; +/// 满分开关 +@property (nonatomic, assign) BOOL fullScoreOn; +/// 满分速率 +@property (nonatomic, assign) NSUInteger fullScoreBPM; +/// 语音间隔模式 +@property (nonatomic, assign) ICSkipSoundMode soundMode; +/// 模式参数 +@property (nonatomic, assign) NSUInteger modeParam; +/// 是否自动停止播放,YES:APP下发开始后,跳绳不会播放语音 ,NO:跳绳和APP都会播放语音 +@property (nonatomic, assign) BOOL isAutoStop; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICUserInfo.h b/ios/Classes/Headers/ICUserInfo.h new file mode 100644 index 0000000..992dfb3 --- /dev/null +++ b/ios/Classes/Headers/ICUserInfo.h @@ -0,0 +1,109 @@ +// +// ICUserInfo.h +// ICleDevice +// +// Created by lifesense-mac on 17/4/18. +// Copyright © 2017年 lifesense. All rights reserved. +// + +#import +#import "ICConstant.h" + +/** + 用户信息 + */ +@interface ICUserInfo : NSObject + +/** + 用户编号,默认:1 + */ +@property (nonatomic, assign) NSUInteger userIndex; + +/** + 用户ID,默认:0 + */ +@property (nonatomic, assign) NSUInteger userId; + +/** + 用户呢称,默认:"icomon" + */ +@property (nonatomic, strong) NSString *nickName; + +/** + 身高(cm),默认:172cm + */ +@property (nonatomic, assign) NSUInteger height; + +/** + 体重(kg),默认:60.0kg + */ +@property (nonatomic, assign) float weight; + +/** + 年龄,默认:24 + */ +@property (nonatomic, assign) NSUInteger age; + +/** + 性别,默认:ICSexTypeMale + */ +@property (nonatomic, assign) ICSexType sex; +/** + 目标体重(kg),默认:50.0kg + */ +@property (nonatomic, assign) float targetWeight; + +/** + 体重方向,默认:0 减重,1:增重 + */ +@property (nonatomic, assign) NSUInteger weightDirection; + +/** + 使用体脂算法版本,默认:ICBFATypeWLA01 + */ +@property (nonatomic, assign) ICBFAType bfaType; + +/** + 用户类型,默认:ICPeopleTypeNormal + */ +@property (nonatomic, assign) ICPeopleType peopleType; + +/** + 用户默认的体重单位,默认:ICWeightUnitKg + */ +@property (nonatomic, assign) ICWeightUnit weightUnit; + +/** + 用户默认的围尺单位,默认:ICRulerUnitCM + */ +@property (nonatomic, assign) ICRulerUnit rulerUnit; + +/** + 用户默认的围尺测量模式,默认:ICRulerMeasureModeLength + */ +@property (nonatomic, assign) ICRulerMeasureMode rulerMode; + +/** + 厨房秤默认单位,默认:ICKitchenScaleUnitG + */ +@property (nonatomic, assign) ICKitchenScaleUnit kitchenUnit; + +/** + * 是否启用测量阻抗,默认:YES,仅支持的设备有效 + */ +@property (nonatomic, assign) BOOL enableMeasureImpendence; +/** + * 是否启用测量HR,默认:YES,仅支持的设备有效 + */ +@property (nonatomic, assign) BOOL enableMeasureHr; +/** + * 是否启用测量平衡,默认:YES,仅支持的设备有效 + */ +@property (nonatomic, assign) BOOL enableMeasureBalance; +/** + * 是否启用测量重心,默认:YES,仅支持的设备有效 + */ +@property (nonatomic, assign) BOOL enableMeasureGravity; + + +@end diff --git a/ios/Classes/Headers/ICWeightCenterData.h b/ios/Classes/Headers/ICWeightCenterData.h new file mode 100644 index 0000000..cff91ee --- /dev/null +++ b/ios/Classes/Headers/ICWeightCenterData.h @@ -0,0 +1,116 @@ +// +// ICWeightCenterData.h +// ICDeviceManager +// +// Created by Symons on 2018/11/5. +// Copyright © 2018 Symons. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + 体重重心数据 + */ +@interface ICWeightCenterData : NSObject + +/** + 数据是否稳定, 不稳定的数据只做展示用,请勿保存 + */ +@property (nonatomic, assign) BOOL isStabilized; + +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + kg体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_kg=1 + */ +@property (nonatomic, assign) NSUInteger precision_kg; + +/** + lb体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_lb=1 + */ +@property (nonatomic, assign) NSUInteger precision_lb; + +/** + st:lb体重小数点位数 + */ +@property (nonatomic, assign) NSUInteger precision_st_lb; + +/** + kg分度值 + */ +@property (nonatomic, assign) NSUInteger kg_scale_division; + +/** + lb分度值 + */ +@property (nonatomic, assign) NSUInteger lb_scale_division; + +/** + 左边体重(g) + */ +@property (nonatomic, assign) NSUInteger left_weight_g; + +/** + 右边体重(g) + */ +@property (nonatomic, assign) NSUInteger right_weight_g; + + +/** + 左边体重占比(%) + */ +@property (nonatomic, assign) float leftPercent; + +/** + 右边体重占比(%) + */ +@property (nonatomic, assign) float rightPercent; + +/** + 左边体重(kg) + */ +@property (nonatomic, assign) float left_weight_kg; + +/** + 右边体重(kg) + */ +@property (nonatomic, assign) float right_weight_kg; + +/** + 左边体重(lb) + */ +@property (nonatomic, assign) float left_weight_lb; + +/** + 右边体重(lb) + */ +@property (nonatomic, assign) float right_weight_lb; + +/** + 左边体重(st:lb) + */ +@property (nonatomic, assign) NSUInteger left_weight_st; + +/** + 右边体重(st:lb) + */ +@property (nonatomic, assign) NSUInteger right_weight_st; + +/** + 左边体重(st:lb) + */ +@property (nonatomic, assign) float left_weight_st_lb; + +/** + 右边体重(st:lb) + */ +@property (nonatomic, assign) float right_weight_st_lb; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Headers/ICWeightData.h b/ios/Classes/Headers/ICWeightData.h new file mode 100644 index 0000000..373c199 --- /dev/null +++ b/ios/Classes/Headers/ICWeightData.h @@ -0,0 +1,407 @@ +// +// ICWeightData.h +// ICDeviceManager +// +// Created by Symons on 2018/8/7. +// Copyright © 2018年 Symons. All rights reserved. +// + +#import +#import "ICConstant.h" + +/** + 体重扩展数据,主要是8电极的部分数据 + */ +@interface ICWeightExtData : NSObject + +/** + 左手体脂率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float left_arm; + +/** + 右手体脂率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float right_arm; + +/** + 左脚体脂率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float left_leg; + +/** + 右脚体脂率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float right_leg; + +/** + 躯干体脂率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float all_body; + + +/** + 左手脂肪量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float left_arm_kg; + +/** + 右手脂肪量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float right_arm_kg; + +/** + 左脚脂肪量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float left_leg_kg; + +/** + 右脚脂肪量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float right_leg_kg; + +/** + 躯干脂肪量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float all_body_kg; + +/** + 左手肌肉率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float left_arm_muscle; + +/** + 右手肌肉率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float right_arm_muscle; + +/** + 左脚肌肉率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float left_leg_muscle; + +/** + 右脚肌肉率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float right_leg_muscle; + +/** + 躯干肌肉率(单位:%, 精度:0.1) + */ +@property (nonatomic, assign) float all_body_muscle; + + +/** + 左手肌肉量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float left_arm_muscle_kg; + +/** + 右手肌肉量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float right_arm_muscle_kg; + +/** + 左脚肌肉量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float left_leg_muscle_kg; + +/** + 右脚肌肉量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float right_leg_muscle_kg; + +/** + 躯干肌肉量(单位:kg, 精度:0.1) + */ +@property (nonatomic, assign) float all_body_muscle_kg; + +@end + +/** + 体重数据 + */ +@interface ICWeightData : NSObject +/** + 用户ID,默认:0 + */ +@property (nonatomic, assign) NSUInteger userId; +/** + 数据是否稳定 + @notice 如果数据不稳定,则只有weight_kg和weight_lb有效,不稳定的数据只做展示用,请勿保存 + */ +@property (nonatomic, assign) BOOL isStabilized; + +/** + 体重(g) + */ +@property (nonatomic, assign) NSUInteger weight_g; + +/** + 体重(kg) + */ +@property (nonatomic, assign) float weight_kg; + +/** + 体重(lb) + */ +@property (nonatomic, assign) float weight_lb; + +/** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ +@property (nonatomic, assign) NSUInteger weight_st; + +/** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ +@property (nonatomic, assign) float weight_st_lb; + +/** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ +@property (nonatomic, assign) NSUInteger precision_kg; + +/** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ +@property (nonatomic, assign) NSUInteger precision_lb; + +/** + st:lb体重小数点位数 + */ +@property (nonatomic, assign) NSUInteger precision_st_lb; + +/** + kg分度值 + */ +@property (nonatomic, assign) NSUInteger kg_scale_division; + +/** + lb分度值 + */ +@property (nonatomic, assign) NSUInteger lb_scale_division; + +/** + 温度,单位:摄氏度 + */ +@property (nonatomic, assign) float temperature; + +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + 支持心率测量 + */ +@property (nonatomic, assign) BOOL isSupportHR; + +/** + 心率值 + */ +@property (nonatomic, assign) NSUInteger hr; + +/** + 身体质量指数BMI(精度:0.1) + */ +@property (nonatomic, assign) float bmi; + +/** + 体脂率(百分比, 精度:0.1) + */ +@property (nonatomic, assign) float bodyFatPercent; + +/** + 皮下脂肪率(百分比, 精度:0.1) + */ +@property (nonatomic, assign) float subcutaneousFatPercent; + +/** + 内脏脂肪指数(精度:0.1) + */ +@property (nonatomic, assign) float visceralFat; + +/** + 肌肉率(百分比, 精度:0.1) + */ +@property (nonatomic, assign) float musclePercent; + +/** + 基础代谢率(单位:kcal) + */ +@property (nonatomic, assign) NSUInteger bmr; + +/** + 骨重(单位:kg,精度:0.1) + */ +@property (nonatomic, assign) float boneMass; + +/** + 水含量(百分比,精度:0.1) + */ +@property (nonatomic, assign) float moisturePercent; + +/** + 身体年龄 + */ +@property (nonatomic, assign) float physicalAge; + +/** + 蛋白率(百分比,精度:0.1) + */ +@property (nonatomic, assign) float proteinPercent; + +/** + 骨骼肌率(百分比,精度:0.1) + */ +@property (nonatomic, assign) float smPercent; + +/** + 身体评分 + */ +@property (nonatomic, assign) float bodyScore; + +/** + 身体类型 + */ +@property (nonatomic, assign) NSUInteger bodyType; + +/** + 目标体重 + */ +@property (nonatomic, assign) float targetWeight; + +/** + 体重控制 + */ +@property (nonatomic, assign) float weightControl; + +/** + 脂肪量控制 + */ +@property (nonatomic, assign) float bfmControl; + +/** + 去脂体重控制 + */ +@property (nonatomic, assign) float ffmControl; + +/** + 标准体重 + */ +@property (nonatomic, assign) float weightStandard; + +/** + 标准脂肪量 + */ +@property (nonatomic, assign) float bfmStandard; + +/** + 标准BMI + */ +@property (nonatomic, assign) float bmiStandard; + +/** + 标准骨骼肌量 + */ +@property (nonatomic, assign) float smmStandard; + +/** + 标准去脂体重 + */ +@property (nonatomic, assign) float ffmStandard; + + +@property (nonatomic, assign) int bmrStandard; // 标准BMR + +@property (nonatomic, assign) float bfpStandard; // 标准体脂率 + + + +@property (nonatomic, assign) float bmiMax; // bmi标准的最大值 +@property (nonatomic, assign) float bmiMin; // bmi标准的最小值 +@property (nonatomic, assign) float bfmMax; // 脂肪量标准的最大值 +@property (nonatomic, assign) float bfmMin; // 脂肪量标准的最小值 +@property (nonatomic, assign) float bfpMax; // 脂肪率标准的最大值 +@property (nonatomic, assign) float bfpMin; // 脂肪率标准的最小值 +@property (nonatomic, assign) float weightMax; // 体重标准的最大值 +@property (nonatomic, assign) float weightMin; // 体重标准的最小值 +@property (nonatomic, assign) float smmMax; // 骨骼肌量标准的最大值 +@property (nonatomic, assign) float smmMin; // 骨骼肌量标准的最小值 +@property (nonatomic, assign) float boneMax; // 骨量标准的最大值 +@property (nonatomic, assign) float boneMin; // 骨量标准的最小值 +@property (nonatomic, assign) float waterMassMax; // 含水量标准的最大值 +@property (nonatomic, assign) float waterMassMin; // 含水量标准的最小值 +@property (nonatomic, assign) float proteinMassMax; // 蛋白量标准的最大值 +@property (nonatomic, assign) float proteinMassMin; // 蛋白量标准的最小值 +@property (nonatomic, assign) float muscleMassMax; // 肌肉量标准的最大值 +@property (nonatomic, assign) float muscleMassMin; // 肌肉量标准的最小值 +@property (nonatomic, assign) NSUInteger bmrMax; // bmr标准的最大值 +@property (nonatomic, assign) NSUInteger bmrMin; // bmr标准的最小值 + +/** + 骨骼肌质量指数 + */ +@property (nonatomic, assign) float smi; + +/** + 肥胖程度 + */ +@property (nonatomic, assign) NSUInteger obesityDegree; + + + +/** + 电极数,4电极或者8电极 + */ +@property (nonatomic, assign) NSUInteger electrode; + +/** + 全身阻抗(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp; + +/** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp2; + +/** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp3; + +/** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp4; + +/** + 右腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp5; + +/** + 体重扩展数据(8电极的部分数据在这里面) + */ +@property (nonatomic, strong) ICWeightExtData *extData; + +/** + 数据计算方式(0:sdk,1:设备计算) + */ +@property (nonatomic, assign) NSUInteger data_calc_type; + +/** + 本次体脂数据计算的算法类型 + */ +@property (nonatomic, assign) ICBFAType bfa_type; + +@property (nonatomic, assign) NSUInteger state; + +@property (nonatomic, assign) NSUInteger impendenceType; + +@property (nonatomic, assign) NSUInteger impendenceProperty; +@property (nonatomic, strong) NSArray *impendences; + +@end diff --git a/ios/Classes/Headers/ICWeightHistoryData.h b/ios/Classes/Headers/ICWeightHistoryData.h new file mode 100644 index 0000000..72f8a48 --- /dev/null +++ b/ios/Classes/Headers/ICWeightHistoryData.h @@ -0,0 +1,137 @@ +// +// ICWeightHistoryData.h +// ICDeviceManager +// +// Created by Symons on 2019/4/22. +// Copyright © 2019 Symons. All rights reserved. +// + +#import +#import "ICWeightCenterData.h" +#import "ICWeightData.h" +#import "ICConstant.h" + +/** + 体重历史数据 + */ +@interface ICWeightHistoryData : NSObject +/** + 用户ID,默认:0 + */ +@property (nonatomic, assign) NSUInteger userId; + +/** + 体重(g) + */ +@property (nonatomic, assign) NSUInteger weight_g; + +/** + 体重(kg) + */ +@property (nonatomic, assign) float weight_kg; + +/** + 体重(lb) + */ +@property (nonatomic, assign) float weight_lb; + +/** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ +@property (nonatomic, assign) NSUInteger weight_st; + +/** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ +@property (nonatomic, assign) float weight_st_lb; + +/** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ +@property (nonatomic, assign) NSUInteger precision_kg; + +/** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ +@property (nonatomic, assign) NSUInteger precision_lb; + +/** + st:lb体重小数点位数 + */ +@property (nonatomic, assign) NSUInteger precision_st_lb; + +/** + kg分度值 + */ +@property (nonatomic, assign) NSUInteger kg_scale_division; + +/** + lb分度值 + */ +@property (nonatomic, assign) NSUInteger lb_scale_division; + +/** + 测量时间戳(秒) + */ +@property (nonatomic, assign) NSUInteger time; + +/** + 心率值 + */ +@property (nonatomic, assign) NSUInteger hr; + +/** + 电极数,4电极或者8电极 + */ +@property (nonatomic, assign) NSUInteger electrode; + +/** + 全身阻抗(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp; + +/** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp2; + +/** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp3; + +/** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp4; + +/** + 右腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ +@property (nonatomic, assign) float imp5; + +/** + 平衡数据 + */ +@property (nonatomic, strong) ICWeightCenterData *centerData; + +/** + 数据计算方式(0:sdk,1:设备计算) + */ +@property (nonatomic, assign) NSUInteger data_calc_type; + +/** + 本次体脂数据计算的算法类型 + */ +@property (nonatomic, assign) ICBFAType bfa_type; + + +@property (nonatomic, assign) NSUInteger impendenceType; + +@property (nonatomic, assign) NSUInteger impendenceProperty; + +@property (nonatomic, strong) NSArray *impendences; + +@end + + diff --git a/ios/Classes/ICDataConver.swift b/ios/Classes/ICDataConver.swift new file mode 100644 index 0000000..ee34fe9 --- /dev/null +++ b/ios/Classes/ICDataConver.swift @@ -0,0 +1,306 @@ +// +// ICuserConver.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class ICuserConver{ + + static func getICBfaType(type:BFAType) -> ICBFAType { + switch type{ + case .ICBFATypeWLA01: return ICBFAType.init(rawValue: 0) + case .ICBFATypeWLA02: return ICBFAType.init(rawValue: 1) + case .ICBFATypeWLA03: return ICBFAType.init(rawValue: 2) + case .ICBFATypeWLA04: return ICBFAType.init(rawValue: 3) + case .ICBFATypeWLA05: return ICBFAType.init(rawValue: 4) + case .ICBFATypeWLA06: return ICBFAType.init(rawValue: 5) + case .ICBFATypeWLA07: return ICBFAType.init(rawValue: 6) + case .ICBFATypeWLA08: return ICBFAType.init(rawValue: 7) + case .ICBFATypeWLA09: return ICBFAType.init(rawValue: 8) + case .ICBFATypeWLA10: return ICBFAType.init(rawValue: 9) + case .ICBFATypeWLA11: return ICBFAType.init(rawValue: 10) + case .ICBFATypeWLA12: return ICBFAType.init(rawValue: 11) + case .ICBFATypeWLA13: return ICBFAType.init(rawValue: 12) + case .ICBFATypeWLA14: return ICBFAType.init(rawValue: 13) + case .ICBFATypeWLA15: return ICBFAType.init(rawValue: 14) + case .ICBFATypeWLA16: return ICBFAType.init(rawValue: 15) + case .ICBFATypeWLA17: return ICBFAType.init(rawValue: 16) + case .ICBFATypeWLA18: return ICBFAType.init(rawValue: 17) + case .ICBFATypeWLA19: return ICBFAType.init(rawValue: 18) + case .ICBFATypeWLA20: return ICBFAType.init(rawValue: 19) + case .ICBFATypeWLA21: return ICBFAType.init(rawValue: 20) + case .ICBFATypeWLA22: return ICBFAType.init(rawValue: 21) + case .ICBFATypeWLA23: return ICBFAType.init(rawValue: 22) + case .ICBFATypeWLA24: return ICBFAType.init(rawValue: 23) + case .ICBFATypeWLA25: return ICBFAType.init(rawValue: 24) + case .ICBFATypeWLA26: return ICBFAType.init(rawValue: 25) + case .ICBFATypeWLA27: return ICBFAType.init(rawValue: 26) + case .ICBFATypeWLA28: return ICBFAType.init(rawValue: 27) + case .ICBFATypeWLA29: return ICBFAType.init(rawValue: 28) + case .ICBFATypeUnknown: return ICBFAType.init(rawValue: 100) + case .ICBFATypeRev: return ICBFAType.init(rawValue: 101) + + + } + + } + + + + static func getICPPType(type:PeopleType) -> ICPeopleType { + switch type{ + case.ICPeopleTypeNormal: return ICPeopleType.init(rawValue:0) + case.ICPeopleTypeSportman :return ICPeopleType.init(rawValue: 1) + + } + } + + static func getICSexType(type:SexType) -> ICSexType { + switch type{ + case.ICSexTypeFemal: return ICSexType.femal + case.ICSexTypeMale :return ICSexType.male + case.ICSexTypeUnknown :return ICSexType.unknown + + } + } + + static func getICWeightUnit(type:ScaleUnit) -> ICWeightUnit { + switch type{ + case.ICWeightUnitKg: return ICWeightUnit.kg + case.ICWeightUnitLb :return ICWeightUnit.lb + case.ICWeightUnitSt :return ICWeightUnit.st + case.ICWeightUnitJin :return ICWeightUnit.jin + + } + } + + + static func getICRulerUnit(type:RulerUnit) -> ICRulerUnit { + switch type{ + case.ICRulerUnitCM: return ICRulerUnit.CM + case.ICRulerUnitInch :return ICRulerUnit.inch + case.ICRulerUnitFtInch :return ICRulerUnit.ftInch + + } + } + + static func getICKitchenUnit(type:KitchenScaleUnit) -> ICKitchenScaleUnit { + switch type{ + case.ICKitchenScaleUnitG: return ICKitchenScaleUnit.G + case.ICKitchenScaleUnitMg :return ICKitchenScaleUnit.mg + case.ICKitchenScaleUnitMl :return ICKitchenScaleUnit.ml + case.ICKitchenScaleUnitMlMilk :return ICKitchenScaleUnit.mlMilk + case.ICKitchenScaleUnitOz :return ICKitchenScaleUnit.oz + case.ICKitchenScaleUnitFlOzMilk :return ICKitchenScaleUnit.flOzMilk + case.ICKitchenScaleUnitFlOzWater :return ICKitchenScaleUnit.flOzWater + case.ICKitchenScaleUnitLb :return ICKitchenScaleUnit.lb + + + } + } + + + static func getRulerMode(type:RulerMeasureMode) -> ICRulerMeasureMode { + switch type{ + case.ICRulerMeasureModeLength: return ICRulerMeasureMode.length + case.ICRulerMeasureModeGirth :return ICRulerMeasureMode.girth + + + } + } + + + + static func getRulerPart(type:RulerBodyPartsType) -> ICRulerBodyPartsType { + switch type{ + case.ICRulerPartsTypeBicep: return ICRulerBodyPartsType.partsTypeBicep + case.ICRulerPartsTypeChest :return ICRulerBodyPartsType.partsTypeChest + case.ICRulerPartsTypeShoulder :return ICRulerBodyPartsType.partsTypeShoulder + case.ICRulerPartsTypeHip :return ICRulerBodyPartsType.partsTypeHip + case.ICRulerPartsTypeWaist :return ICRulerBodyPartsType.partsTypeWaist + case.ICRulerPartsTypeThigh :return ICRulerBodyPartsType.partsTypeThigh + case.ICRulerPartsTypeCalf :return ICRulerBodyPartsType.partsTypeCalf + + + + } + } + + + + + static func getICUserInfo(data:UserInfo) -> ICUserInfo{ + + let user = ICUserInfo() + user.userId=data.userId + user.userIndex=data.userIndex + user.nickName=data.nickName + user.height=data.height + user.weight=data.weight + user.targetWeight=data.targetWeight + user.age=data.age + user.weightDirection=data.weightDirection + user.bfaType = ICuserConver.getICBfaType(type: data.bfaType) + user.peopleType = ICuserConver.getICPPType(type: data.peopleType) + user.sex = ICuserConver.getICSexType(type: data.sex) + + user.weightUnit = ICuserConver.getICWeightUnit(type: data.weightUnit) + user.rulerUnit = ICuserConver.getICRulerUnit(type: data.rulerUnit) + user.rulerMode = ICuserConver.getRulerMode(type: data.rulerMode) + user.kitchenUnit = ICuserConver.getICKitchenUnit(type: data.kitchenUnit) + user.enableMeasureImpendence = data.enableMeasureImpendence + user.enableMeasureHr = data.enableMeasureHr + user.enableMeasureBalance = data.enableMeasureBalance + user.enableMeasureGravity = data.enableMeasureGravity + + return user + } + + + + static func getCalcICWeight(data:WeightData) -> ICWeightData{ + let weight = ICWeightData() + weight.weight_kg=data.weight_kg + weight.bfa_type = getICBfaType(type: data.bfa_type) + weight.imp = data.imp + weight.impendences = [] + data.impendences?.forEach({ (element) in + weight.impendences.append(NSNumber(value: element)) + }) + + return weight + + } + + + static func getICSoundSettingData(data:SkipSoundSettingData) -> ICSkipSoundSettingData{ + let setting = ICSkipSoundSettingData() + setting.soundOn=data.soundOn + setting.soundVolume=data.soundVolume + setting.fullScoreOn=data.fullScoreOn + setting.fullScoreBPM=data.fullScoreBPM + setting.modeParam=data.modeParam + setting.isAutoStop=data.isAutoStop + setting.soundType = getSkipSoundType(type: data.soundType) + setting.soundMode = getSkipSoundMode(mode: data.soundMode) + + return setting + } + + + static func getICLightSettingData(data:SkipLightSettingData) -> ICSkipLightSettingData{ + let setting = ICSkipLightSettingData() + setting.r = data.r + setting.b = data.b + setting.g = data.g + setting.modeValue = data.rpm + + + return setting + } + + + static func getSDKOTAMode(mode:OTAMode) -> ICOTAMode{ + switch mode{ + case.ICOTAMode1:return ICOTAMode.mode1 + case.ICOTAMode2:return ICOTAMode.mode2 + case.ICOTAMode3:return ICOTAMode.mode3 + case.ICOTAModeAuto:return ICOTAMode.modeAuto + } + + } + + + static func getSkipMode(mode:SkipMode) -> ICSkipMode{ + switch mode{ + case.ICSkipModeFreedom:return ICSkipMode.init(rawValue: 0) + case.ICSkipModeTiming:return ICSkipMode.init(rawValue: 1) + case.ICSkipModeCount:return ICSkipMode.init(rawValue: 2) + case.ICSkipModeInterruptTime:return ICSkipMode.init(rawValue: 3) + case.ICSkipModeInterruptCount:return ICSkipMode.init(rawValue: 4) + default:return ICSkipMode.init(rawValue: 0) + } + + } + + + + static func getSkipSoundType(type:SkipSoundType) -> ICSkipSoundType{ + switch type{ + case.ICSkipSoundTypeNone:return ICSkipSoundType.none + case.ICSkipSoundTypeMale:return ICSkipSoundType.male + case.ICSkipSoundTypeFemale:return ICSkipSoundType.female + default:return ICSkipSoundType.female + + + } + + } + + + static func getSkipSoundMode(mode:SkipSoundMode) -> ICSkipSoundMode{ + switch mode{ + case.ICSkipSoundModeNone:return ICSkipSoundMode.none + case.ICSkipSoundModeTime:return ICSkipSoundMode.time + case.ICSkipSoundModeCount:return ICSkipSoundMode.count + default:return ICSkipSoundMode.count + + } + + } + static func getSkipLightMode(mode:SkipLightMode) -> ICSkipLightMode{ + switch mode{ + case.ICSkipLightModeNone:return ICSkipLightMode.none + case.ICSkipLightModeTimer:return ICSkipLightMode.timer + case.ICSkipLightModeCount:return ICSkipLightMode.count + case.ICSkipLightModePercent:return ICSkipLightMode.percent + case.ICSkipLightModeTripRope:return ICSkipLightMode.tripRope + case.ICSkipLightModeRPM:return ICSkipLightMode.RPM + case.ICSkipLightModeMeasuring:return ICSkipLightMode.measuring + default:return ICSkipLightMode.none + + } + + } + static func getICNutritionFactType(type:KitchenScaleNutritionFactType) -> ICKitchenScaleNutritionFactType{ + switch type{ + case .ICKitchenScaleNutritionFactTypeCalorie: + return ICKitchenScaleNutritionFactType.calorie + case .ICKitchenScaleNutritionFactTypeTotalCalorie: + return ICKitchenScaleNutritionFactType.totalCalorie + case .ICKitchenScaleNutritionFactTypeFat: + return ICKitchenScaleNutritionFactType.fat + + case .ICKitchenScaleNutritionFactTypeTotalFat: + return ICKitchenScaleNutritionFactType.totalFat + case .ICKitchenScaleNutritionFactTypeProtein: + return ICKitchenScaleNutritionFactType.protein + case .ICKitchenScaleNutritionFactTypeTotalProtein: + return ICKitchenScaleNutritionFactType.totalProtein + case .ICKitchenScaleNutritionFactTypeCarbohydrates: + return ICKitchenScaleNutritionFactType.carbohydrates + case .ICKitchenScaleNutritionFactTypeTotalCarbohydrates: + return ICKitchenScaleNutritionFactType.totalCarbohydrates + case .ICKitchenScaleNutritionFactTypeFiber: + return ICKitchenScaleNutritionFactType.fiber + + case .ICKitchenScaleNutritionFactTypeTotalFiber: + return ICKitchenScaleNutritionFactType.totalFiber + case .ICKitchenScaleNutritionFactTypeCholesterd: + return ICKitchenScaleNutritionFactType.cholesterd + case .ICKitchenScaleNutritionFactTypeTotalCholesterd: + return ICKitchenScaleNutritionFactType.totalCholesterd + case .ICKitchenScaleNutritionFactTypeSodium: + return ICKitchenScaleNutritionFactType.sodium + case .ICKitchenScaleNutritionFactTypeTotalSodium: + return ICKitchenScaleNutritionFactType.totalSodium + case .ICKitchenScaleNutritionFactTypeSugar: + return ICKitchenScaleNutritionFactType.sugar + case .ICKitchenScaleNutritionFactTypeTotalSugar: + return ICKitchenScaleNutritionFactType.totalSugar + } + } + + +} diff --git a/ios/Classes/ICJson.swift b/ios/Classes/ICJson.swift new file mode 100644 index 0000000..54a268d --- /dev/null +++ b/ios/Classes/ICJson.swift @@ -0,0 +1,152 @@ +// +// ICJson.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/9. +// +import Foundation + +class ICJson{ + + static func jsonToBean(from jsonString:String) throws -> T { + let jsonData = Data(jsonString.utf8) + return try JSONDecoder().decode(T.self, from: jsonData) + } + + + func jsonToArray(jsonString:String) -> [T]? { + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + return try JSONDecoder().decode([T].self, from: jsonData) + + } catch { + return nil + } + } + + + static func jsonToDeviceArray (jsonString:String) -> [ICDevice] { + var result = [ICDevice]() + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode([Device].self, from: jsonData) + + temp.forEach { (element) in + let icDevice=ICDevice() + icDevice.macAddr = element.macAddr + result.append(icDevice) + } + + return result + + } catch { + return result + } + } + + + + + + static func jsonToUserInfoArray (jsonString:String) -> [ICUserInfo] { + var result = [ICUserInfo]() + + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode([UserInfo].self, from: jsonData) + temp.forEach { (element) in + + result.append(ICuserConver.getICUserInfo(data: element)) + } + + return result + + } catch { + return result + } + } + + + + static func jsonToLightSettingArray (jsonString:String) -> [ICSkipLightSettingData] { + var result = [ICSkipLightSettingData]() + + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode([SkipLightSettingData].self, from: jsonData) + temp.forEach { (element) in + result.append(ICuserConver.getICLightSettingData(data: element)) + } + + return result + + } catch { + return result + } + } + + + + + static func jsonToICUser(jsonString:String) -> ICUserInfo { + var result = ICUserInfo() + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode(UserInfo.self, from: jsonData) + return ICuserConver.getICUserInfo(data: temp) + + } catch { + return result + } + } + + + static func jsonToICWeight(jsonString:String) -> ICWeightData { + var result = ICWeightData() + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode(WeightData.self, from: jsonData) + return ICuserConver.getCalcICWeight(data: temp) + + } catch { + return result + } + } + + + + static func jsonToICSoundSetting(jsonString:String) -> ICSkipSoundSettingData { + var result = ICSkipSoundSettingData() + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + let temp = try JSONDecoder().decode(SkipSoundSettingData.self, from: jsonData) + return ICuserConver.getICSoundSettingData(data: temp) + + } catch { + return result + } + } + + + static func beanToJson(bean:Codable) -> String?{ + let jsonEncoder = JSONEncoder(); + let jsonData = try! jsonEncoder.encode(bean); + let json = String(data: jsonData, encoding: String.Encoding.utf8); + return json; + } + + + + +} + + + + diff --git a/ios/Classes/ICMapKey.swift b/ios/Classes/ICMapKey.swift new file mode 100644 index 0000000..809acf8 --- /dev/null +++ b/ios/Classes/ICMapKey.swift @@ -0,0 +1,34 @@ +// +// ICMapKey.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/8. +// + + +struct ICMapKey{ + static let Method = "Method"; + static let Mac = "Mac"; + static let Password = "Password"; + static let SSID = "SSID"; + static let DstId = "DstId"; + static let StNo = "StNo"; + + + + static let JsonValue = "JsonValue"; + static let JsonValue2 = "JsonValue2"; + static let EnumName = "EnumName"; + static let BoolValue = "BoolValue"; + static let ObjectValue = "ObjectValue"; + static let IntValue = "IntValue"; + static let ResultValue = "ResultValue"; + static let StringValue = "StringValue"; + + + + + + + +} diff --git a/ios/Classes/ICSDKManager.swift b/ios/Classes/ICSDKManager.swift new file mode 100644 index 0000000..f538851 --- /dev/null +++ b/ios/Classes/ICSDKManager.swift @@ -0,0 +1,704 @@ +// +// ICSDKManager.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/8. +// + +class ICSDKManager :NSObject, + ICDeviceManagerDelegate, + ICScanDeviceDelegate +{ + + + + + private override init() { + + } + + static let sharedInstance: ICSDKManager = ICSDKManager() + + static var channel:FlutterMethodChannel? = nil; + + + func setDelegate(){ + ICDeviceManager.shared().delegate=self; + } + + + func getICDeviceByMac(strMac:String ) -> ICDevice { + let icDevice = ICDevice(); + icDevice.macAddr = strMac; + return icDevice; + } + + + + + func initSdk(config:ICDeviceManagerConfig){ + ICDeviceManager.shared().initMgr(with: config ); + + } + + + + + func addDevice( macAddr:String?, uiCallBack: ICAddDeviceCallBack? ) { + if (macAddr == nil){ + return; + } + let myDevice = ICDevice(); + myDevice.macAddr=macAddr! + + ICDeviceManager.shared().add(myDevice,callback: uiCallBack ); + + + } + + + + + func addDevices( devices:[ICDevice]?, uiCallBack:@escaping ICAddDeviceCallBack ) { + if (devices == nil){ + return; + } + ICDeviceManager.shared().add(devices,callback: uiCallBack ); + + } + + + func removeDevice( macAddr:String?, uiCallBack:@escaping ICRemoveDeviceCallBack ) { + if (macAddr == nil){ + return; + } + let myDevice = ICDevice(); + myDevice.macAddr=macAddr!; + + ICDeviceManager.shared().remove(myDevice,callback: uiCallBack ); + + } + + + + func removeDevices(devices:[ICDevice]?, uiCallBack:@escaping ICRemoveDeviceCallBack ) { + ICDeviceManager.shared().remove(devices,callback: uiCallBack ); + + } + + + + func upgradeDevice( macAddr: String?, path: String?, icotaMode: ICOTAMode) { + if (macAddr == nil){ + return; + } + if (path==nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().upgradeDevice(dev, filePath:path,mode: icotaMode); + + } + + + + + func upgradeDevices( devices:[ICDevice]?, path: String?, icotaMode: ICOTAMode) { + if (devices == nil){ + return; + } + if (path==nil){ + return; + } + ICDeviceManager.shared().upgradeDevices(devices, filePath:path,mode: icotaMode); + + } + + + + func stopUpgradeDevice( macAddr: String?) { + if (macAddr == nil){ + return; + } + let dev = ICDevice(); + dev.macAddr=macAddr!; + ICDeviceManager.shared().stopUpgradeDevice(dev); + + } + + + + func scanDevice() { + ICDeviceManager.shared().scanDevice(self); + } + + + + func stopScan() { + ICDeviceManager.shared().stopScan(); + } + + + + func configWifi( macAddr:String?, ssid:String, password:String,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().configWifi(dev, ssid: ssid, password: password, callback: callback); + + + + } + + + func setScaleUnit( macAddr:String?, unit:ICWeightUnit,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + print(unit.self) + + ICDeviceManager.shared().getSettingManager().setScaleUnit(dev, unit: unit, callback:callback); + + + } + + + func setRulerUnit( macAddr:String?, unit:ICRulerUnit,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setRulerUnit(dev, unit: unit, callback:callback); + + + } + + + func setRulerBodyPartsType( macAddr:String?, part:ICRulerBodyPartsType,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setRulerBodyPartsType(dev, type: part, callback:callback); + + + } + + + + + + func setRulerMeasureMode( macAddr:String?, mode:ICRulerMeasureMode,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setRulerMeasureMode(dev, mode: mode, callback:callback); + + + } + + + func setKitchenScaleUnit( macAddr:String?, unit:ICKitchenScaleUnit,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setKitchenScaleUnit(dev, unit: unit, callback:callback); + + + } + + func deleteTareWeight( macAddr:String?, callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().deleteTareWeight(dev, callback:callback); + + + } + + + func powerOffKitchenScale( macAddr:String?, callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().powerOffKitchenScale(dev, callback:callback); + + + } + + func setNutritionFacts( macAddr:String?, + type:ICKitchenScaleNutritionFactType, + value:Int, + callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setNutritionFacts(dev, type:type,value:value,callback:callback); + + + } + + + func setServerUrl( macAddr:String?, + server:String, + callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setServerUrl(dev,server:server,callback:callback); + + + } + + func setOtherParams( macAddr:String?,params:Any){ + + } + + + func queryStAllNode( macAddr:String?,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().queryStAllNode(dev,callback:callback); + } + + + func changeStName( macAddr:String?,name:String?,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + if (name == nil){ + return; + } + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().changeStName(dev,name:name,callback:callback); + } + + + + func changeStNo( macAddr:String?, dstId:UInt, st_no:UInt,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().changeStNo(dev,dstId:dstId, st_no:st_no,callback:callback); + } + + + func syncUserInfo(userInfo: ICUserInfo?) { + if (userInfo == nil){ + return; + } + ICDeviceManager.shared().update(userInfo!); + } + + func syncUserList(userList:[ICUserInfo]?) { + if (userList == nil){ + return; + } + ICDeviceManager.shared().setUserList(userList!); + } + + + + + func setWeight( macAddr:String?, weight:Int, callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setWeight(dev, weight:weight,callback:callback); + } + + + + func startSkip( macAddr:String?,mode:ICSkipMode, param:UInt, callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().startSkip(dev, mode:mode,param:param,callback:callback); + } + + + + func stopSkip( macAddr:String?,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().stopSkip(dev,callback:callback); + } + + func setSkipLightSetting( macAddr:String?,lightEffects:[ICSkipLightSettingData]?,mode:ICSkipLightMode,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + if (lightEffects == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setSkipLightSetting(dev,lightEffects:lightEffects,mode:mode,callback:callback); + } + + + + func setSkipSoundSetting( macAddr:String?,config:ICSkipSoundSettingData?,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + if (config == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().setSkipSoundSetting(dev,config:config,callback:callback); + } + + + + + func lockStSkip( macAddr:String?,callback:@escaping ICSettingCallback){ + if (macAddr == nil){ + return; + } + + let dev = ICDevice(); + dev.macAddr=macAddr!; + + ICDeviceManager.shared().getSettingManager().lockStSkip(dev,callback:callback); + } + + + func reCalcBodyFatWithWeightData( weightData:ICWeightData,userInfo :ICUserInfo )->WeightData { + let icWeight:ICWeightData = ICDeviceManager.shared().getBodyFatAlgorithmsManager().reCalcBodyFat(with: weightData, userInfo: userInfo) + return WeightData.init(data: icWeight) + } + + func getLogPath( )->String { + + return ICDeviceManager.shared().getLogPath() + } + + + + + + func sendMsgToFlutter( name:String, obj:Any) { + + DispatchQueue.main.async { + if (ICSDKManager.channel != nil) { + ICSDKManager.channel!.invokeMethod(name, arguments: obj) + } + } + + + } + + + + + func onScanResult(_ deviceInfo: ICScanDeviceInfo!) { + print("mac地址:"+deviceInfo.macAddr) + let info = ScanDeviceInfo.init(deviceInfo:deviceInfo); + let jsonEncoder = JSONEncoder(); + let jsonData = try! jsonEncoder.encode(info); + let json = String(data: jsonData, encoding: String.Encoding.utf8); + + + + var map:[String:Any] = [String:Any]() + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.DeviceScan, obj: map); + } + + + func onInitFinish(_ bSuccess: Bool) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.BoolValue]=bSuccess; + sendMsgToFlutter(name :ICWUploadEvent.InitSDK, obj: map); + + + } + + + func onBleState(_ state: ICBleState) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.EnumName] = BleState.init(type: state).rawValue + sendMsgToFlutter(name :ICWUploadEvent.BluetoothChange, obj: map); + + } + + func onDeviceConnectionChanged(_ device: ICDevice!, state: ICDeviceConnectState) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.EnumName] = DeviceConnectState.init(type: state).rawValue + sendMsgToFlutter(name :ICWUploadEvent.ConnectChange, obj: map); + } + + func onReceiveElectrodeData(_ device: ICDevice!, data: ICElectrodeData!) { + + } + + func onReceiveRulerMeasureModeChanged(_ device: ICDevice!, mode: ICRulerMeasureMode) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.EnumName] = RulerMeasureMode.init(type: mode).rawValue + sendMsgToFlutter(name :ICWUploadEvent.RulerModeChange, obj: map); + } + func onReceiveDeviceInfo(_ device: ICDevice!, deviceInfo: ICDeviceInfo!) { + var map:[String:Any] = [String:Any](); + let bean = DeviceInfo.init(data: deviceInfo) + let json = ICJson.beanToJson(bean: bean) + + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.DeviceInfo, obj: map); + + } + + func onNodeConnectionChanged(_ device: ICDevice!, nodeId: UInt, state: ICDeviceConnectState) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.IntValue]=nodeId + map[ICMapKey.EnumName] = DeviceConnectState.init(type: state).rawValue + sendMsgToFlutter(name :ICWUploadEvent.NodConnectChange, obj: map); + } + + + func onReceiveMeasureStepData(_ device: ICDevice!, step: ICMeasureStep, data: NSObject!) { + + var json :String? = "" + if(data.isKind(of:ICWeightCenterData.self)){ + let temp = data as! ICWeightCenterData + let weight:WeightCenterData = WeightCenterData.init(data: temp) + json = ICJson.beanToJson(bean: weight) + }else { + let temp = data as! ICWeightData + let weight:WeightData = WeightData.init(data: temp) + json = ICJson.beanToJson(bean: weight) + } + + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + map[ICMapKey.EnumName] = MeasureStep.init(type: step.rawValue).rawValue + sendMsgToFlutter(name :ICWUploadEvent.ScaleStepData, obj: map); + + } + func onReceiveWeightData(_ device: ICDevice!, data: ICWeightData!) { + let weight=WeightData.init(data: data) + let json = ICJson.beanToJson(bean: weight) + + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.ScaleData, obj: map); + } + + + func onReceiveKitchenScaleData(_ device: ICDevice!, data: ICKitchenScaleData!) { + let bean = KitchenData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.KitchenData, obj: map); + + } + + + func onReceiveKitchenScaleUnitChanged(_ device: ICDevice!, unit: ICKitchenScaleUnit) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.EnumName] = KitchenScaleUnit.init(type: unit).rawValue + sendMsgToFlutter(name :ICWUploadEvent.KitchenScaleUnitChanged, obj: map); + } + + func onReceiveCoordData(_ device: ICDevice!, data: ICCoordData!) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + + let bean = CoordData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + + map[ICMapKey.JsonValue] = json + sendMsgToFlutter(name :ICWUploadEvent.ScaleCoordData, obj: map); + } + + func onReceiveRulerData(_ device: ICDevice!, data: ICRulerData!) { + let bean = RulerData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.RulerData, obj: map); + } + + func onReceiveRulerHistoryData(_ device: ICDevice!, data: ICRulerData!) { + let bean = RulerData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.RulerHistoryData, obj: map); + } + + func onReceiveWeightCenterData(_ device: ICDevice!, data: ICWeightCenterData!) { + let bean = WeightCenterData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.ScaleCenterData, obj: map); + } + + func onReceiveWeightHistoryData(_ device: ICDevice!, data: ICWeightHistoryData!) { + let bean = WeightHistoryData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.ScaleHistoryData, obj: map); + } + + + + func onReceiveWeightUnitChanged(_ device: ICDevice!, unit: ICWeightUnit) { + var map:[String:Any] = [String:Any](); + map[ICMapKey.Mac]=device.macAddr + print("onReceiveWeightUnitChanged ") + print(unit.rawValue) + map[ICMapKey.EnumName] = ScaleUnit.init(type: unit).rawValue + sendMsgToFlutter(name :ICWUploadEvent.ScaleUnitChange, obj: map); + } + + + func onReceiveRulerUnitChanged(_ device: ICDevice!, unit: ICRulerUnit) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.EnumName] = RulerUnit(type: unit).rawValue + sendMsgToFlutter(name :ICWUploadEvent.RulerUnitChange, obj: map); + } + + + + func onReceiveSkipData(_ device: ICDevice!, data: ICSkipData!) { + let bean = SkipData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.SkipData, obj: map); + } + + func onReceiveHistorySkipData(_ device: ICDevice!, data: ICSkipData!) { + let bean = SkipData.init(data: data) + let json = ICJson.beanToJson(bean: bean) + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.JsonValue]=json; + sendMsgToFlutter(name :ICWUploadEvent.SkipHistoryData, obj: map); + } + + + func onReceiveBattery(_ device: ICDevice!, battery: UInt, ext: NSObject!) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.IntValue] = battery + sendMsgToFlutter(name :ICWUploadEvent.Battery, obj: map); + } + + func onReceiveUpgradePercent(_ device: ICDevice!, status: ICUpgradeStatus, percent: UInt) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.IntValue] = percent + map[ICMapKey.EnumName] = UpgradeStatus.init(type: status).rawValue + sendMsgToFlutter(name :ICWUploadEvent.Upgrade, obj: map); + } + + + + func onReceiveConfigWifiResult(_ device: ICDevice!, state: ICConfigWifiState) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.EnumName] = ConfigWifiState.init(type: state).rawValue + sendMsgToFlutter(name :ICWUploadEvent.ConfigWifi, obj: map); + + } + + func onReceiveHR(_ device: ICDevice!, hr: Int32) { + var map:[String:Any] = [String:Any]() + map[ICMapKey.Mac]=device.macAddr + map[ICMapKey.IntValue]=hr + sendMsgToFlutter(name :ICWUploadEvent.HrData, obj: map); + + } + + + +} diff --git a/ios/Classes/ICWPublishEvent.swift b/ios/Classes/ICWPublishEvent.swift new file mode 100644 index 0000000..4a4cff5 --- /dev/null +++ b/ios/Classes/ICWPublishEvent.swift @@ -0,0 +1,64 @@ +// +// ICWPublishEvent.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/8. +// + +struct ICWPublishEvent{ + static let InitSDK = "InitSDK"; + static let AddDevice = "AddDevice"; + static let AddDevices = "AddDevices"; + static let DeleteDevice = "RemoveDevice"; + static let DeleteDevices = "RemoveDevices"; + + static let OTADevice = "OTADevice"; + static let OTADevices = "OTADevices"; + static let StopOTADevice = "StopOTADevice"; + static let StopOTADevices = "StopOTADevices"; + + static let StopScan = "StopScan"; + static let StartScan = "StartScan"; + static let SetUserInfo = "SetUserInfo"; + static let SetUserList = "SetUserList"; + + + + static let ScaleUnitSetting = "setScaleUnit"; + static let ScaleConfigWifi = "configWifi"; + + static let RulerUnitSetting = "RulerUnitSetting"; + static let RulerModeSetting = "RulerModeSetting"; + static let RulerBodyPartSetting = "RulerBodyPartSetting"; + + + static let KitchenUnitSetting = "KitchenUnitSetting"; + static let KitchenPowerOff = "KitchenPowerOff"; + static let KitchenCMD = "KitchenCMD"; + static let KitchenTareWeight = "KitchenTareWeight"; + static let KitchenFactory = "KitchenFactory"; + static let KitchenSetNutritionFacts = "KitchenSetNutritionFacts"; + + static let SkipStop = "SkipStop"; + static let SkipStart = "SkipStart"; + static let SetSkipMode = "SetSkipMode"; + static let SkipLightSetting = "SkipLightSetting"; + static let SkipSoundSetting = "SkipSoundSetting"; + static let SkipLockSt = "SkipLockSt"; + static let SkipSetWeight = "SkipSetWeight"; + + + + + static let SetServerUrl = "setServerUrl"; + static let SetOtherParams = "setOtherParams"; + static let SetScaleUIItems = "setScaleUIItems"; + + static let QueryStAllNode = "queryStAllNode"; + static let ChangeStName = "changeStName"; + static let ChangeStNo = "changeStNo"; + static let CalcBodyFat = "CalcBodyFat"; + static let GetLogPath = "LogPath"; + + +} diff --git a/ios/Classes/ICWUploadEvent.swift b/ios/Classes/ICWUploadEvent.swift new file mode 100644 index 0000000..61eed00 --- /dev/null +++ b/ios/Classes/ICWUploadEvent.swift @@ -0,0 +1,60 @@ +// +// ICWUploadEvent.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/9. +// + + + + +struct ICWUploadEvent{ + static let InitSDK = "InitSDK"; + + static let Connected = "Connected"; + static let DisConnected = "Connected"; + + static let Upgrade = "onReceiveUpgradePercent"; + static let Battery = "onReceiveBattery"; + static let ConfigWifi = "onReceiveConfigWifiResult"; + static let DeviceScan = "onScanResult"; + + static let SettingResult = "onSettingCallBack"; + static let AddDeviceResult = "onAddDeviceCallBack"; + static let RemoveDeviceResult = "onRemoveDeviceCallBack"; + + static let BluetoothChange = "onBleState"; + + static let ScaleData = "onReceiveWeightData"; + static let ScaleCoordData = "onReceiveCoordData"; + static let ScaleStepData = "onReceiveMeasureStepData"; + static let ScaleCenterData = "onReceiveWeightCenterData"; + static let ScaleUnitChange = "onReceiveWeightUnitChanged"; + static let ScaleHistoryData = "onReceiveWeightHistoryData"; + + + + + static let RulerData = "onReceiveRulerData"; + static let RulerHistoryData = "onReceiveRulerHistoryData"; + static let RulerUnitChange = "onReceiveRulerUnitChanged"; + static let RulerModeChange = "onReceiveRulerMeasureModeChanged"; + + + static let KitchenData = "onReceiveKitchenScaleData"; + + static let SkipData = "onReceiveSkipData"; + static let DeviceInfo = "onReceiveDeviceInfo"; + static let SkipBattery = "onReceiveSkipBattery"; + static let SkipHistoryData = "onReceiveHistorySkipData"; + + static let ConnectChange = "onDeviceConnectionChanged"; + static let NodConnectChange = "onNodConnectChange"; + + static let KitchenScaleUnitChanged = "onReceiveKitchenScaleUnitChanged"; + + + static let HrData = "HrData"; + + +} diff --git a/ios/Classes/SwiftFlutterSwiftPlugin.swift b/ios/Classes/SwiftFlutterSwiftPlugin.swift new file mode 100644 index 0000000..77e9834 --- /dev/null +++ b/ios/Classes/SwiftFlutterSwiftPlugin.swift @@ -0,0 +1,484 @@ +import Flutter +import UIKit + +public class SwiftFlutterSwiftPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "ic_bluetooth_sdk", binaryMessenger: registrar.messenger()) + let instance = SwiftFlutterSwiftPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + ICSDKManager.channel=channel; + ICSDKManager.sharedInstance.setDelegate() + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + var arguments = call.arguments; + var params:[String:Any] = [String:Any]() + var resultMap:[String:String] = [String:String]() + if arguments is Dictionary { + var map:[String:Any] = arguments as! [String : Any] + map.forEach { (key: String, value: Any) in + params[key]=value; + + } + + } + + var jsonObj = params[ICMapKey.JsonValue]; + var macObj = params[ICMapKey.Mac]; + var enumObj = params[ICMapKey.EnumName]; + var intObj = params[ICMapKey.IntValue]; + var stringObj = params[ICMapKey.StringValue]; + + + + + var mac = ""; + var cmdValue = ""; + var device = ICDevice(); + var devList = [ICDevice]() + var filePath = ""; + var weight = 0; + + + if (jsonObj != nil){ + cmdValue = (jsonObj as? String)!; + } + if (macObj != nil) { + mac = (macObj as? String)!; + + } + if (intObj != nil){ + weight = intObj as! Int; + } + + switch call.method{ + case ICWPublishEvent.InitSDK: + ICSDKManager.sharedInstance.initSdk(config: ICDeviceManagerConfig()) + break + case ICWPublishEvent.StartScan: + ICSDKManager.sharedInstance.scanDevice() + break + + case ICWPublishEvent.StopScan: + ICSDKManager.sharedInstance.stopScan() + break + case ICWPublishEvent.AddDevice: + ICSDKManager.sharedInstance.addDevice(macAddr: mac) { device, code in + resultMap[ICMapKey.EnumName] = AddDeviceCallBackCode.init(type:code).rawValue + result(resultMap) + + } + + break + + case ICWPublishEvent.AddDevices: + + devList = ICJson.jsonToDeviceArray(jsonString: cmdValue) + + ICSDKManager.sharedInstance.addDevices(devices: devList) { device, code in + resultMap[ICMapKey.EnumName] = AddDeviceCallBackCode.init(type:code).rawValue + result(resultMap) + + } + break + + case ICWPublishEvent.DeleteDevice: + + ICSDKManager.sharedInstance.removeDevice(macAddr: mac) { device, code in + resultMap[ICMapKey.EnumName] = RemoveDeviceCallBackCode.init(type:code).rawValue + result(resultMap) + + } + + + break + + + case ICWPublishEvent.DeleteDevices: + devList = ICJson.jsonToDeviceArray(jsonString: cmdValue) + + ICSDKManager.sharedInstance.removeDevices(devices: devList) { device, code in + resultMap[ICMapKey.EnumName] = RemoveDeviceCallBackCode.init(type:code).rawValue + result(resultMap) + + } + break + case ICWPublishEvent.OTADevice: + + + if (stringObj != nil) { + filePath = stringObj as! String + + } + + + + let mode = OTAMode.init(rawValue: enumObj as! String) + + var sdkOTAMode:ICOTAMode + if(mode == nil){ + sdkOTAMode = ICOTAMode.modeAuto + }else{ + sdkOTAMode = ICuserConver.getSDKOTAMode(mode:mode!) + } + + ICSDKManager.sharedInstance.upgradeDevice(macAddr: mac, path: filePath, icotaMode: sdkOTAMode) + + + break + + case ICWPublishEvent.OTADevices: + + + devList = ICJson.jsonToDeviceArray(jsonString: cmdValue) + let mode = OTAMode.init(rawValue: enumObj as! String) + var sdkOTAMode:ICOTAMode + if(mode == nil){ + sdkOTAMode = ICOTAMode.modeAuto + }else{ + sdkOTAMode = ICuserConver.getSDKOTAMode(mode:mode!) + } + + ICSDKManager.sharedInstance.upgradeDevices(devices: devList, path: filePath, icotaMode: sdkOTAMode) + + break + + case ICWPublishEvent.StopOTADevice: + ICSDKManager.sharedInstance.stopUpgradeDevice(macAddr: mac) + break + + + case ICWPublishEvent.StopOTADevices: + devList = ICJson.jsonToDeviceArray(jsonString: cmdValue) + break + case ICWPublishEvent.ScaleConfigWifi: + + let ssidObj = params[ICMapKey.SSID] as! String + let passwordObj = params[ICMapKey.Password] as! String + + ICSDKManager.sharedInstance.configWifi(macAddr:mac, ssid: ssidObj, password: passwordObj) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + + break + + + + case ICWPublishEvent.ScaleUnitSetting: + let unitString = enumObj as! String + let unit = ScaleUnit.init(rawValue: unitString) + var weightUnit:ICWeightUnit + if(unit == nil){ + weightUnit = ICWeightUnit.kg + + }else { + weightUnit = ICuserConver.getICWeightUnit(type: unit!) + } + + + ICSDKManager.sharedInstance.setScaleUnit(macAddr:mac, unit: weightUnit ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + + break + + case ICWPublishEvent.RulerUnitSetting: + + let unit = RulerUnit.init(rawValue: enumObj as! String) + var rulerUnit:ICRulerUnit + if(unit == nil){ + rulerUnit = ICRulerUnit.CM + + }else { + rulerUnit = ICuserConver.getICRulerUnit(type: unit!) + } + + ICSDKManager.sharedInstance.setRulerUnit(macAddr:mac, unit: rulerUnit ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + + break + + case ICWPublishEvent.RulerModeSetting: + + + + let mode = RulerMeasureMode.init(rawValue: enumObj as! String) + + var rulerMode:ICRulerMeasureMode + + if(mode == nil){ + rulerMode = ICRulerMeasureMode.length + + }else { + rulerMode = ICuserConver.getRulerMode(type: mode!) + } + + ICSDKManager.sharedInstance.setRulerMeasureMode(macAddr:mac, mode: rulerMode ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + break + case ICWPublishEvent.RulerBodyPartSetting: + + let part = RulerBodyPartsType.init(rawValue: enumObj as! String) + + var rulerPart:ICRulerBodyPartsType + + if(part == nil){ + rulerPart = ICRulerBodyPartsType.partsTypeBicep + + }else { + rulerPart = ICuserConver.getRulerPart(type: part!) + } + + ICSDKManager.sharedInstance.setRulerBodyPartsType(macAddr:mac, part: rulerPart ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + break + + case ICWPublishEvent.KitchenUnitSetting: + + let unit = KitchenScaleUnit.init(rawValue: enumObj as! String) + var kitchenUnit:ICKitchenScaleUnit + if(unit == nil){ + kitchenUnit = ICKitchenScaleUnit.G + + }else { + kitchenUnit = ICuserConver.getICKitchenUnit(type: unit!) + } + + ICSDKManager.sharedInstance.setKitchenScaleUnit(macAddr:mac, unit: kitchenUnit ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + break + case ICWPublishEvent.KitchenPowerOff: + + ICSDKManager.sharedInstance.powerOffKitchenScale(macAddr:mac) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + case ICWPublishEvent.KitchenCMD: + break + + case ICWPublishEvent.KitchenTareWeight: + ICSDKManager.sharedInstance.deleteTareWeight(macAddr:mac) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + case ICWPublishEvent.KitchenFactory: + break + + case ICWPublishEvent.SetSkipMode: + + + + + + let skipMode = SkipMode.init(rawValue: enumObj as! String) + + var icSkipMope:ICSkipMode + + if(skipMode == nil){ + icSkipMope = ICSkipMode.init(rawValue: 0) + + }else { + icSkipMope = ICuserConver.getSkipMode(mode:skipMode!) + } + + var params:UInt = 0 + if(intObj != nil){ + params = intObj as! UInt + + } + + ICSDKManager.sharedInstance.startSkip(macAddr:mac, mode:icSkipMope,param: params ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + + break + + case ICWPublishEvent.SkipStart: + + + let skipMode = SkipMode.init(rawValue: enumObj as! String) + + var icSkipMope:ICSkipMode + + if(skipMode == nil){ + icSkipMope = ICSkipMode.init(rawValue: 0) + + }else { + icSkipMope = ICuserConver.getSkipMode(mode:skipMode!) + } + + var params:UInt = 0 + if(intObj != nil){ + params = intObj as! UInt + + } + + ICSDKManager.sharedInstance.startSkip(macAddr:mac, mode:icSkipMope,param: params ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + + case ICWPublishEvent.SkipStop: + + ICSDKManager.sharedInstance.stopSkip(macAddr:mac ) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + + case ICWPublishEvent.SkipLightSetting: + let lightSetting = ICJson.jsonToLightSettingArray(jsonString: cmdValue) + let lightMode = SkipLightMode.init(type: enumObj as! ICSkipLightMode) + let iclightMode = ICuserConver.getSkipLightMode(mode: lightMode) + + ICSDKManager.sharedInstance.setSkipLightSetting(macAddr:mac ,lightEffects: lightSetting,mode:iclightMode) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + case ICWPublishEvent.SkipSoundSetting: + + let soundSetting = ICJson.jsonToICSoundSetting(jsonString: cmdValue) + + ICSDKManager.sharedInstance.setSkipSoundSetting(macAddr:mac ,config:soundSetting) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + case ICWPublishEvent.SkipSetWeight: + ICSDKManager.sharedInstance.setWeight(macAddr:mac ,weight:weight) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + case ICWPublishEvent.KitchenSetNutritionFacts: + + let type = KitchenScaleNutritionFactType.init(rawValue: enumObj as! String) + let icKitchenSetNutritionFacts = ICuserConver.getICNutritionFactType(type: type!) + + ICSDKManager.sharedInstance.setNutritionFacts(macAddr:mac ,type: icKitchenSetNutritionFacts,value:weight) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + case ICWPublishEvent.SetServerUrl: + + let url = stringObj as! String + ICSDKManager.sharedInstance.setServerUrl(macAddr:mac ,server:url) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + case ICWPublishEvent.SetOtherParams: + break; + case ICWPublishEvent.SetScaleUIItems: + break; + case ICWPublishEvent.SkipLockSt: + ICSDKManager.sharedInstance.lockStSkip(macAddr:mac) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + + break + + case ICWPublishEvent.QueryStAllNode: + + ICSDKManager.sharedInstance.queryStAllNode(macAddr:mac) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + case ICWPublishEvent.ChangeStName: + let stName = stringObj as! String + + + ICSDKManager.sharedInstance.changeStName(macAddr:mac, name: stName) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + case ICWPublishEvent.ChangeStNo: + let stId = params[ICMapKey.DstId] as! UInt + let stNo = params[ICMapKey.StNo] as! UInt + + ICSDKManager.sharedInstance.changeStNo(macAddr:mac,dstId:stId,st_no:stNo) { code in + resultMap[ICMapKey.EnumName] = SettingCallBackCode.init(type:code).rawValue + result(resultMap) + } + break + + + case ICWPublishEvent.SetUserInfo: + + let user = ICJson.jsonToICUser(jsonString: cmdValue) + ICSDKManager.sharedInstance.syncUserInfo(userInfo: user) + break + + + case ICWPublishEvent.SetUserList: + let userList = ICJson.jsonToUserInfoArray(jsonString: cmdValue) + ICSDKManager.sharedInstance.syncUserList(userList: userList) + break + + case ICWPublishEvent.CalcBodyFat: + + let weightData = ICJson.jsonToICWeight(jsonString:cmdValue); + var userObj = params[ICMapKey.JsonValue2]; + if (userObj != nil) { + var userJon = userObj as! String + let user = ICJson.jsonToICUser(jsonString: userJon) + let resultWeight = ICSDKManager.sharedInstance.reCalcBodyFatWithWeightData(weightData: weightData, userInfo:user ) + resultMap[ICMapKey.JsonValue] = ICJson.beanToJson(bean: resultWeight) + result(resultMap) + + } + + + break + case ICWPublishEvent.GetLogPath: + let logPath = ICSDKManager.sharedInstance.getLogPath() + resultMap[ICMapKey.StringValue] = logPath + result(resultMap) + + break + default: + break + + } + + + } + + + + + +} diff --git a/ios/Classes/model/CoordData.swift b/ios/Classes/model/CoordData.swift new file mode 100644 index 0000000..c0a5809 --- /dev/null +++ b/ios/Classes/model/CoordData.swift @@ -0,0 +1,18 @@ +// +// CoordData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/13. +// + +class CoordData:Codable{ + + init(data:ICCoordData){ + time=data.time; + x=data.x; + y=data.y; + } + var time:UInt = 0; + var x:Int = 0; + var y:Int = 0; +} diff --git a/ios/Classes/model/Device.swift b/ios/Classes/model/Device.swift new file mode 100644 index 0000000..d23dded --- /dev/null +++ b/ios/Classes/model/Device.swift @@ -0,0 +1,26 @@ +// +// Device.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class Device:Codable{ + init(data:String){ + macAddr=data + } + var macAddr:String? + + + + func jsonToArray(jsonString:String) -> [T]? { + let jsonData = Data(jsonString.utf8) + let decoder = JSONDecoder() + do { + return try JSONDecoder().decode([T].self, from: jsonData) + + } catch { + return nil + } + } +} diff --git a/ios/Classes/model/DeviceInfo.swift b/ios/Classes/model/DeviceInfo.swift new file mode 100644 index 0000000..8c7b3ab --- /dev/null +++ b/ios/Classes/model/DeviceInfo.swift @@ -0,0 +1,96 @@ +// +// DeviceInfo.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class DeviceInfo:Codable{ + + init(data:ICDeviceInfo){ + mac = data.mac; + model = data.model; + sn = data.sn; + firmwareVer = data.firmwareVer; + softwareVer = data.softwareVer; + hardwareVer = data.hardwareVer; + manufactureName = data.manufactureName; +// kg_scale_division=data.kg_scale_division +// lb_scale_division=data.lb_scale_division +// isSupportHr=data.isSupportHr +// isSupportGravity=data.isSupportGravity +// isSupportBalance=data.isSupportBalance +// isSupportOTA=data.isSupportOTA +// isSupportOffline=data.isSupportOffline +// bfDataCalcType=data.bfDataCalcType +// isSupportUserInfo=data.isSupportUserInfo +// maxUserCount=data.maxUserCount +// batteryType=data.batteryType +// bfaType = BFAType.init(type: data.bfaType.rawValue) +// bfaType2 = BFAType.init(type: data.bfaType2.rawValue) +// isSupportUnitKg=data.isSupportUnitKg +// isSupportUnitLb=data.isSupportUnitLb +// isSupportUnitStLb=data.isSupportUnitStLb +// isSupportUnitJin=data.isSupportUnitJin +// isSupportChangePole = false +// pole=data.pole +// impendenceType=data.impendenceType +// impendenceCount=data.impendenceCount +// impendencePrecision=data.impendencePrecision +// impendencePropert=0 +// enableMeasureImpendence=data.enableMeasureImpendence +// enableMeasureHr=data.enableMeasureHr +// enableMeasureBalance=data.enableMeasureBalance +// enableMeasureGravity=data.enableMeasureGravity + + + } + + + var mac = ""; + + var model = ""; + + var sn = ""; + + var firmwareVer = ""; + + var softwareVer = ""; + + var hardwareVer = ""; + + var manufactureName = ""; + + var extInfo:String?; + +// +// +// var kg_scale_division:UInt; +// var lb_scale_division:UInt; +// var isSupportHr = false; +// var isSupportGravity = false; +// var isSupportBalance = false; +// var isSupportOTA = false; +// var isSupportOffline = false; +// var bfDataCalcType:UInt; +// var isSupportUserInfo = false; +// var maxUserCount:UInt; +// var batteryType:UInt; +// var bfaType:BFAType? ; +// var bfaType2:BFAType? ; +// var isSupportUnitKg = false; +// var isSupportUnitLb = false; +// var isSupportUnitStLb = false; +// var isSupportUnitJin = false; +// var isSupportChangePole = false; +// var pole:UInt; +// var impendenceType:UInt; +// var impendenceCount:UInt; +// var impendencePrecision:UInt; +// var impendencePropert:UInt; +// var enableMeasureImpendence = false; +// var enableMeasureHr = false; +// var enableMeasureBalance = false; +// var enableMeasureGravity = false; +// +} diff --git a/ios/Classes/model/DeviceInfoExt.swift b/ios/Classes/model/DeviceInfoExt.swift new file mode 100644 index 0000000..9a939fd --- /dev/null +++ b/ios/Classes/model/DeviceInfoExt.swift @@ -0,0 +1,17 @@ +// +// DeviceInfoExt.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class DeviceInfoExt :Codable{ + + + init(data:String?){ + ext = data + } + var ext:String?; +} + + diff --git a/ios/Classes/model/ICConstant.swift b/ios/Classes/model/ICConstant.swift new file mode 100644 index 0000000..7ad934c --- /dev/null +++ b/ios/Classes/model/ICConstant.swift @@ -0,0 +1,991 @@ +// +// ICConstant.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/9. +// + + +enum BleState:String,Codable{ + + init(type:ICBleState){ + switch type{ + case .unsupported: self = .ICBleStateUnsupported + case .unauthorized: self = .ICBleStateUnauthorized + case .poweredOff:self = .ICBleStatePoweredOff + case .poweredOn:self = .ICBleStatePoweredOn + default:self = .ICBleStateUnknown; + + } + + }; + + + /** + * 未知状态 + **/ + case ICBleStateUnknown = "ICBleStateUnknown", + + /** + * 手机不支持BLE + **/ + ICBleStateUnsupported = "ICBleStateUnsupported", + + /** + * 应用未获取蓝牙授权 + **/ + ICBleStateUnauthorized = "ICBleStateUnauthorized", + + /** + * 蓝牙关闭 + **/ + ICBleStatePoweredOff = "ICBleStatePoweredOff", + + /** + * 蓝牙打开 + **/ + ICBleStatePoweredOn = "ICBleStatePoweredOn" + +} +enum DeviceType:String,Codable{ + + init(type:ICDeviceType){ + switch type{ + case .weightScale: self = .ICDeviceTypeWeightScale + + case .fatScale:self = .ICDeviceTypeFatScale + + case .fatScaleWithTemperature:self = .ICDeviceTypeFatScaleWithTemperature + case .ruler:self = .ICDeviceTypeRuler + case .HR:self = .ICDeviceTypeHR + case .balance:self = .ICDeviceTypeBalance + case .kitchenScale:self = .ICDeviceTypeKitchenScale + case .skip:self = .ICDeviceTypeSkip + + default:self = .ICDeviceTypeUnKnown; + + } + + }; + + + + + /// 未知 + ///*/ + case ICDeviceTypeUnKnown="ICDeviceTypeUnKnown", + + /// 体重秤 + ///*/ + ICDeviceTypeWeightScale="ICDeviceTypeWeightScale", + + /// 脂肪秤 + ///*/ + ICDeviceTypeFatScale="ICDeviceTypeFatScale", + + /// 脂肪秤(带温度显示) + ///*/ + ICDeviceTypeFatScaleWithTemperature="ICDeviceTypeFatScaleWithTemperature", + + /// 厨房秤 + ///*/ + ICDeviceTypeKitchenScale="ICDeviceTypeKitchenScale", + + /// 围尺 + ///*/ + ICDeviceTypeRuler="ICDeviceTypeRuler", + + /// 平衡秤 + ///*/ + ICDeviceTypeBalance="ICDeviceTypeBalance", + + /// 跳绳 + ///*/ + ICDeviceTypeSkip="ICDeviceTypeSkip", + + /// HR + ///*/ + ICDeviceTypeHR="ICDeviceTypeHR" +} + + + +enum DeviceSubType :String,Codable{ + + init(type:ICDeviceSubType){ + switch type{ + case .eightElectrode: self = .ICDeviceSubTypeEightElectrode + + case .eightElectrode2:self = .ICDeviceSubTypeEightElectrode2 + + case .height:self = .ICDeviceSubTypeHeight + case .scaleDual:self = .ICDeviceSubTypeScaleDual + case .lightEffect:self = .ICDeviceSubTypeLightEffect + case .sound:self = .ICDeviceSubTypeSound + case .lightAndSound:self = .ICDeviceSubTypeLightAndSound + case .color:self = .ICDeviceSubTypeColor + case .baseSt:self = .ICDeviceSubTypeBaseSt + case .ropeS2:self = .ICDeviceSubTypeRopeS2 + + default:self = .ICDeviceSubTypeDefault; + + } + + }; + + + + /** + * 默认 + **/ + case ICDeviceSubTypeDefault = "ICDeviceSubTypeDefault", + + /** + * 8电极设备 + **/ + ICDeviceSubTypeEightElectrode="ICDeviceSubTypeEightElectrode", + + /** + * 身高设备 + **/ + ICDeviceSubTypeHeight="ICDeviceSubTypeHeight", + /** + * 8电极设备2 + **/ + ICDeviceSubTypeEightElectrode2="ICDeviceSubTypeEightElectrode2", + /** + * 双模设备 + **/ + ICDeviceSubTypeScaleDual="ICDeviceSubTypeScaleDual", + /** + * 跳绳带灯效 + **/ + ICDeviceSubTypeLightEffect="ICDeviceSubTypeLightEffect", + /** + * 彩屏秤 + **/ + ICDeviceSubTypeColor="ICDeviceSubTypeColor", + /** + * 跳绳带语音 + **/ + ICDeviceSubTypeSound="ICDeviceSubTypeSound", + + /** + * 跳绳带灯效和语音 + **/ + ICDeviceSubTypeLightAndSound="ICDeviceSubTypeLightAndSound", + + /** + * 基站 + */ + ICDeviceSubTypeBaseSt="ICDeviceSubTypeBaseSt", + + /** + * iComon S2 + */ + ICDeviceSubTypeRopeS2="ICDeviceSubTypeRopeS2" + +} + + +enum DeviceCommunicationType:String ,Codable{ + + + init(type:ICDeviceCommunicationType){ + switch type{ + case .broadcast: self = .ICDeviceCommunicationTypeBroadcast + + case .connect:self = .ICDeviceCommunicationTypeConnect + + default:self = .ICDeviceCommunicationTypeUnknown; + + } + + }; + + /** + 未知 + */ + case ICDeviceCommunicationTypeUnknown="ICDeviceCommunicationTypeUnknown", + + /** + 连接式 + */ + ICDeviceCommunicationTypeConnect="ICDeviceCommunicationTypeConnect", + + /** + 广播式 + */ + ICDeviceCommunicationTypeBroadcast = "ICDeviceCommunicationTypeBroadcast" + +} + + + + +enum DeviceConnectState:String,Codable{ + + init(type:ICDeviceConnectState){ + switch type{ + case .connected:self = .ICDeviceConnectStateConnected + + default:self = .ICDeviceConnectStateDisconnected; + + } + + }; + + /** + * 已连接 + **/ + case ICDeviceConnectStateConnected, + + /** + * 已断开 + **/ + ICDeviceConnectStateDisconnected + +} + +enum AddDeviceCallBackCode :String,Codable{ + + init(type:ICAddDeviceCallBackCode){ + switch type{ + case .success:self = .ICAddDeviceCallBackCodeSuccess + case .failedAndSDKNotInit:self = .ICAddDeviceCallBackCodeFailedAndSDKNotInit + case .failedAndExist:self = .ICAddDeviceCallBackCodeFailedAndExist + default:self = .ICAddDeviceCallBackCodeFailedAndDeviceParamErro; + + } + + }; + + /** + * 添加成功 + */ + case ICAddDeviceCallBackCodeSuccess, + + /** + * 添加失败,SDK未初始化 + */ + ICAddDeviceCallBackCodeFailedAndSDKNotInit, + + /** + * 添加失败,设备已存在 + */ + ICAddDeviceCallBackCodeFailedAndExist, + + /** + * 添加失败,设备参数有错 + */ + ICAddDeviceCallBackCodeFailedAndDeviceParamErro + +} + + +enum RemoveDeviceCallBackCode:String,Codable{ + + + + init(type:ICRemoveDeviceCallBackCode){ + switch type{ + case .success:self = .ICRemoveDeviceCallBackCodeSuccess + case .failedAndSDKNotInit:self = .ICRemoveDeviceCallBackCodeFailedAndNotExist + case .failedAndNotExist:self = .ICRemoveDeviceCallBackCodeFailedAndNotExist + default:self = .ICRemoveDeviceCallBackCodeFailedAndDeviceParamError; + + } + + }; + /** + * 删除成功 + */ + case ICRemoveDeviceCallBackCodeSuccess="ICRemoveDeviceCallBackCodeSuccess", + + /** + * 删除失败,SDK未初始化 + */ + ICRemoveDeviceCallBackCodeFailedAndSDKNotInit="ICRemoveDeviceCallBackCodeFailedAndSDKNotInit", + + /** + * 删除失败,设备不存在 + */ + ICRemoveDeviceCallBackCodeFailedAndNotExist="ICRemoveDeviceCallBackCodeFailedAndNotExist", + + /** + * 删除失败,设备参数有错 + */ + ICRemoveDeviceCallBackCodeFailedAndDeviceParamError="ICRemoveDeviceCallBackCodeFailedAndDeviceParamError" + +} + +enum MeasureStep:String,Codable{ + + init(type:UInt){ + + switch type{ + case 0:self = .ICMeasureStepMeasureWeightData + case 1:self = .ICMeasureStepMeasureCenterData + case 2:self = .ICMeasureStepAdcStart + case 3:self = .ICMeasureStepAdcResult + case 4:self = .ICMeasureStepHrStart + case 5:self = .ICMeasureStepHrResult + case 6:self = .ICMeasureStepMeasureOver + default:self = .ICMeasureStepMeasureWeightData; + + } + + }; + + case ICMeasureStepMeasureWeightData="ICMeasureStepMeasureWeightData", + ICMeasureStepMeasureCenterData="ICMeasureStepMeasureCenterData", + ICMeasureStepAdcStart="ICMeasureStepAdcStart", + ICMeasureStepAdcResult="ICMeasureStepAdcResult", + ICMeasureStepHrStart="ICMeasureStepHrStart", + ICMeasureStepHrResult="ICMeasureStepHrResult", + ICMeasureStepMeasureOver="ICMeasureStepMeasureOver" +} + + +enum ScaleUnit:String,Codable{ + + init(type:ICWeightUnit){ + switch type{ + case .kg:self = .ICWeightUnitKg + case .lb:self = .ICWeightUnitLb + case .st:self = .ICWeightUnitSt + case .jin:self = .ICWeightUnitJin + default:self = .ICWeightUnitKg + } + }; + + + case ICWeightUnitKg="ICWeightUnitKg", + ICWeightUnitLb="ICWeightUnitLb", + ICWeightUnitSt="ICWeightUnitSt", + ICWeightUnitJin="ICWeightUnitJin" + +} + + + + +enum RulerUnit:String,Codable{ + + init(type:ICRulerUnit){ + switch type{ + case .CM:self = .ICRulerUnitCM + case .inch:self = .ICRulerUnitInch + case .ftInch:self = .ICRulerUnitFtInch + default:self = .ICRulerUnitCM + } + }; + + + case ICRulerUnitCM="ICRulerUnitCM", + ICRulerUnitInch="ICRulerUnitInch", + ICRulerUnitFtInch="ICRulerUnitFtInch" + + +} + + + + +enum KitchenScaleUnit:String,Codable{ + + init(type:ICKitchenScaleUnit){ + + switch type{ + case .oz:self = .ICKitchenScaleUnitOz + case .mg:self = .ICKitchenScaleUnitMg + case .G:self = .ICKitchenScaleUnitG + case .ml:self = .ICKitchenScaleUnitMl + case .lb:self = .ICKitchenScaleUnitLb + case .mlMilk:self = .ICKitchenScaleUnitMlMilk + case .flOzWater:self = .ICKitchenScaleUnitFlOzWater + case .flOzMilk:self = .ICKitchenScaleUnitFlOzMilk + + default:self = .ICKitchenScaleUnitG; + + } + + }; + + + /** + * 克 + */ + case ICKitchenScaleUnitG = "ICKitchenScaleUnitG", + + /** + * ml + */ + ICKitchenScaleUnitMl = "ICKitchenScaleUnitMl", + + /** + * 磅 + */ + ICKitchenScaleUnitLb = "ICKitchenScaleUnitLb", + + /** + * 盎司 + */ + ICKitchenScaleUnitOz = "ICKitchenScaleUnitOz", + /** + * 毫克 + */ + ICKitchenScaleUnitMg = "ICKitchenScaleUnitMg", + /** + * ml(牛奶) + */ + ICKitchenScaleUnitMlMilk = "ICKitchenScaleUnitMlMilk", + /** + * 盎司(水) + */ + ICKitchenScaleUnitFlOzWater = "ICKitchenScaleUnitFlOzWater", + /** + * 盎司(牛奶) + */ + ICKitchenScaleUnitFlOzMilk = "ICKitchenScaleUnitFlOzMilk" +} + + + +enum BFAType:String,Codable{ + + init(type:UInt){ + switch type{ + + case 0:self = .ICBFATypeWLA01 + case 1:self = .ICBFATypeWLA02 + case 2:self = .ICBFATypeWLA03 + case 3:self = .ICBFATypeWLA04 + case 4:self = .ICBFATypeWLA05 + case 5:self = .ICBFATypeWLA06 + case 6:self = .ICBFATypeWLA07 + case 7:self = .ICBFATypeWLA08 + case 8:self = .ICBFATypeWLA09 + case 9:self = .ICBFATypeWLA10 + case 10:self = .ICBFATypeWLA11 + case 11:self = .ICBFATypeWLA12 + case 12:self = .ICBFATypeWLA13 + case 13:self = .ICBFATypeWLA14 + case 14:self = .ICBFATypeWLA15 + case 15:self = .ICBFATypeWLA16 + case 16:self = .ICBFATypeWLA17 + case 17:self = .ICBFATypeWLA18 + case 18:self = .ICBFATypeWLA19 + case 19:self = .ICBFATypeWLA20 + case 20:self = .ICBFATypeWLA21 + case 21:self = .ICBFATypeWLA22 + case 22:self = .ICBFATypeWLA23 + case 23:self = .ICBFATypeWLA24 + case 24:self = .ICBFATypeWLA25 + case 25:self = .ICBFATypeWLA26 + case 26:self = .ICBFATypeWLA27 + case 27:self = .ICBFATypeWLA28 + case 28:self = .ICBFATypeWLA29 + case 100:self = .ICBFATypeUnknown + case 101:self = .ICBFATypeRev + + default: + self = .ICBFATypeWLA01 + } + }; + + + + case ICBFATypeWLA01 = "ICBFATypeWLA01", + + ICBFATypeWLA02 = "ICBFATypeWLA02", + + ICBFATypeWLA03 = "ICBFATypeWLA03", + + ICBFATypeWLA04 = "ICBFATypeWLA04", + + ICBFATypeWLA05 = "ICBFATypeWLA05", + + ICBFATypeWLA06 = "ICBFATypeWLA06", + + ICBFATypeWLA07 = "ICBFATypeWLA07", + + ICBFATypeWLA08 = "ICBFATypeWLA08", + + ICBFATypeWLA09 = "ICBFATypeWLA09", + + ICBFATypeWLA10 = "ICBFATypeWLA10", + + ICBFATypeWLA11 = "ICBFATypeWLA11", + + ICBFATypeWLA12 = "ICBFATypeWLA12", + + ICBFATypeWLA13 = "ICBFATypeWLA13", + + ICBFATypeWLA14 = "ICBFATypeWLA14", + + ICBFATypeWLA15 = "ICBFATypeWLA15", + + ICBFATypeWLA16 = "ICBFATypeWLA16", + + ICBFATypeWLA17 = "ICBFATypeWLA17", + + ICBFATypeWLA18 = "ICBFATypeWLA18", + + ICBFATypeWLA19 = "ICBFATypeWLA19", + + ICBFATypeWLA20 = "ICBFATypeWLA20", + + ICBFATypeWLA21 = "ICBFATypeWLA21", + + ICBFATypeWLA22 = "ICBFATypeWLA22", + + ICBFATypeWLA23 = "ICBFATypeWLA23", + + ICBFATypeWLA24 = "ICBFATypeWLA24", + + ICBFATypeWLA25 = "ICBFATypeWLA25", + + ICBFATypeWLA26 = "ICBFATypeWLA26", + + ICBFATypeWLA27 = "ICBFATypeWLA27", + + ICBFATypeWLA28 = "ICBFATypeWLA28", + + ICBFATypeWLA29 = "ICBFATypeWLA29", + + ICBFATypeUnknown = "ICBFATypeUnknown", + + ICBFATypeRev = "ICBFATypeRev" + +} + +enum RulerMeasureMode:String,Codable{ + init(type:ICRulerMeasureMode){ + + switch type{ + case .girth:self = .ICRulerMeasureModeGirth + default:self = .ICRulerMeasureModeLength + } + + }; + + case ICRulerMeasureModeLength = "ICRulerMeasureModeLength", + ICRulerMeasureModeGirth = "ICRulerMeasureModeGirth" + +} + + +enum RulerBodyPartsType:String,Codable{ + init(type:ICRulerBodyPartsType){ + switch type{ + case .partsTypeShoulder:self = .ICRulerPartsTypeShoulder + case .partsTypeBicep:self = .ICRulerPartsTypeBicep + case .partsTypeChest:self = .ICRulerPartsTypeChest + case .partsTypeWaist:self = .ICRulerPartsTypeWaist + case .partsTypeHip:self = .ICRulerPartsTypeHip + case .partsTypeThigh:self = .ICRulerPartsTypeThigh + case .partsTypeCalf:self = .ICRulerPartsTypeCalf + default:self = .ICRulerPartsTypeShoulder + } + + }; + + case ICRulerPartsTypeShoulder = "ICRulerPartsTypeShoulder", + ICRulerPartsTypeBicep = "ICRulerPartsTypeBicep", + ICRulerPartsTypeChest = "ICRulerPartsTypeChest", + ICRulerPartsTypeWaist = "ICRulerPartsTypeWaist", + ICRulerPartsTypeHip = "ICRulerPartsTypeHip", + ICRulerPartsTypeThigh = "ICRulerPartsTypeThigh", + ICRulerPartsTypeCalf = "ICRulerPartsTypeCalf" + +} + +enum SkipMode:String,Codable{ + + init(type:UInt){ + switch type{ + case 0:self = .ICSkipModeFreedom + case 1:self = .ICSkipModeTiming + case 2:self = .ICSkipModeCount + case 3:self = .ICSkipModeInterruptTime + case 4:self = .ICSkipModeInterruptCount + default:self = .ICSkipModeFreedom + } + + }; + + case ICSkipModeFreedom="ICSkipModeFreedom", + ICSkipModeTiming="ICSkipModeTiming", + ICSkipModeCount="ICSkipModeCount", + ICSkipModeInterruptTime="ICSkipModeInterruptTime", + ICSkipModeInterruptCount="ICSkipModeInterruptCount" +} + +enum UpgradeStatus:String,Codable{ + + + + init(type:ICUpgradeStatus){ + switch type{ + case .success:self = .ICUpgradeStatusSuccess + case .upgrading:self = .ICUpgradeStatusUpgrading + case .fail:self = .ICUpgradeStatusFail + case .failFileInvalid:self = .ICUpgradeStatusFailFileInvalid + case .failNotSupport:self = .ICUpgradeStatusFailNotSupport + default:self = .ICUpgradeStatusFail + } + + }; + /** + * 升级成功 + */ + case ICUpgradeStatusSuccess = "ICUpgradeStatusSuccess", + /** + * 升级中 + */ + ICUpgradeStatusUpgrading = "ICUpgradeStatusUpgrading", + /** + * 升级失败 + */ + ICUpgradeStatusFail = "ICUpgradeStatusFail", + /** + * 升级失败,文件无效 + */ + ICUpgradeStatusFailFileInvalid = "ICUpgradeStatusFailFileInvalid", + /** + * 升级失败,设备不支持升级 + */ + ICUpgradeStatusFailNotSupport = "ICUpgradeStatusFailNotSupport" +} + + + +enum ConfigWifiState:String,Codable{ + init(type:ICConfigWifiState){ + switch type{ + case .success:self = .ICConfigWifiStateSuccess + case .wifiConnecting:self = .ICConfigWifiStateWifiConnecting + case .fail:self = .ICConfigWifiStateWifiConnectFail + case .wifiConnectFail:self = .ICConfigWifiStateWifiConnectFail + case .serverConnectFail:self = .ICConfigWifiStateServerConnectFail + case .passwordFail:self = .ICConfigWifiStatePasswordFail + default:self = .ICConfigWifiStateFail + } + + }; + + + case ICConfigWifiStateSuccess = "ICConfigWifiStateSuccess", + ICConfigWifiStateWifiConnecting = "ICConfigWifiStateWifiConnecting", + ICConfigWifiStateServerConnecting = "ICConfigWifiStateServerConnecting", + ICConfigWifiStateWifiConnectFail = "ICConfigWifiStateWifiConnectFail", + ICConfigWifiStateServerConnectFail = "ICConfigWifiStateServerConnectFail", + ICConfigWifiStatePasswordFail = "ICConfigWifiStatePasswordFail", + ICConfigWifiStateFail = "ICConfigWifiStateFail" + +} + + + +enum SexType:String,Codable { + init(type:ICSexType){ + switch type{ + case .unknown:self = .ICSexTypeUnknown + case .male:self = .ICSexTypeMale + case .femal:self = .ICSexTypeFemal + default:self = .ICSexTypeMale + + + } + }; + + + + case ICSexTypeUnknown = "ICSexTypeUnknown", + ICSexTypeMale = "ICSexTypeMale", + ICSexTypeFemal = "ICSexTypeFemal" + +} + +enum PeopleType:String,Codable { + init(type:UInt){ + switch type{ + case 1:self = .ICPeopleTypeSportman + default:self = .ICPeopleTypeNormal + + + } + }; + + + + case ICPeopleTypeNormal = "ICPeopleTypeNormal", + ICPeopleTypeSportman = "ICPeopleTypeSportman" + + +} + + + +enum OTAMode:String,Codable{ + + init(type:ICOTAMode){ + switch type{ + case .modeAuto:self = .ICOTAModeAuto + case .mode3:self = .ICOTAMode3 + case .mode2:self = .ICOTAMode2 + case .mode1:self = .ICOTAMode1 + @unknown default:self = .ICOTAModeAuto + + } + }; + + + case ICOTAModeAuto = "ICOTAModeAuto", + + ICOTAMode1 = "ICOTAMode1", + + ICOTAMode2 = "ICOTAMode2", + + ICOTAMode3 = "ICOTAMode3" +} + + +enum SettingCallBackCode:String,Codable{ + + init(type:ICSettingCallBackCode){ + switch type{ + case .success:self = .ICSettingCallBackCodeSuccess + case .sdkNotInit:self = .ICSettingCallBackCodeSDKNotInit + case .sdkNotStart:self = .ICSettingCallBackCodeSDKNotStart + case .deviceNotFound:self = .ICSettingCallBackCodeDeviceNotFound + case .functionIsNotSupport:self = .ICSettingCallBackCodeFunctionIsNotSupport + case .deviceDisConnected:self = .ICSettingCallBackCodeDeviceDisConnected + case .invalidParameter:self = .ICSettingCallBackCodeInvalidParameter + case .failed:self = .ICSettingCallBackCodeFailed + @unknown default:self = .ICSettingCallBackCodeInvalidParameter + + } + }; + + + case ICSettingCallBackCodeSuccess = "ICSettingCallBackCodeSuccess", + + + ICSettingCallBackCodeSDKNotInit = "ICSettingCallBackCodeSDKNotInit", + + + ICSettingCallBackCodeSDKNotStart = "ICSettingCallBackCodeSDKNotStart", + + + ICSettingCallBackCodeDeviceNotFound = "ICSettingCallBackCodeDeviceNotFound", + + ICSettingCallBackCodeFunctionIsNotSupport = "ICSettingCallBackCodeFunctionIsNotSupport", + + + ICSettingCallBackCodeDeviceDisConnected = "ICSettingCallBackCodeDeviceDisConnected", + + + ICSettingCallBackCodeInvalidParameter = "ICSettingCallBackCodeInvalidParameter", + + + ICSettingCallBackCodeFailed = "ICSettingCallBackCodeFailed" + +} + +enum SkipSoundType:String,Codable{ + + init(type:ICSkipSoundType){ + switch type{ + case .none:self = .ICSkipSoundTypeNone + case .female:self = .ICSkipSoundTypeFemale + case .male:self = .ICSkipSoundTypeMale + default:self = .ICSkipSoundTypeFemale + + } + }; + + + case ICSkipSoundTypeNone = "ICSkipSoundTypeNone", + + + ICSkipSoundTypeFemale = "ICSkipSoundTypeFemale", + + ICSkipSoundTypeMale = "ICSkipSoundTypeMale" +} + + + +enum SkipSoundMode:String,Codable { + + init(type:ICSkipSoundMode){ + switch type{ + case .none:self = .ICSkipSoundModeNone + case .time:self = .ICSkipSoundModeTime + case .count:self = .ICSkipSoundModeCount + default:self = .ICSkipSoundModeCount + + } + }; + + case ICSkipSoundModeNone = "ICSkipSoundModeNone", + + ICSkipSoundModeTime = "ICSkipSoundModeTime", + + ICSkipSoundModeCount = "ICSkipSoundModeCount" +} + +enum SkipLightMode:String,Codable{ + init(type:ICSkipLightMode){ + switch type{ + case .none:self = .ICSkipLightModeNone + case .RPM:self = .ICSkipLightModeRPM + case .timer:self = .ICSkipLightModeTimer + case .count:self = .ICSkipLightModeCount + case .percent:self = .ICSkipLightModePercent + case .tripRope:self = .ICSkipLightModeTripRope + case .measuring:self = .ICSkipLightModeMeasuring + default:self = .ICSkipLightModeNone + + } + }; + + /* + * 无 + */ + case ICSkipLightModeNone = "ICSkipLightModeNone", + /* + * 速度模式 + */ + ICSkipLightModeRPM = "ICSkipLightModeRPM", + /* + * 计时模式 + */ + ICSkipLightModeTimer = "ICSkipLightModeTimer", + /* + * 计次模式 + */ + ICSkipLightModeCount = "ICSkipLightModeCount", + /* + * 百分比模式 + */ + ICSkipLightModePercent = "ICSkipLightModePercent", + /* + * 绊绳次数模式 + */ + ICSkipLightModeTripRope = "ICSkipLightModeTripRope", + /* + * 测量模式模式 + */ + ICSkipLightModeMeasuring = "ICSkipLightModeMeasuring" +} + +enum KitchenScaleNutritionFactType:String,Codable{ + + + init(type:ICKitchenScaleNutritionFactType){ + switch type{ + case .calorie:self = .ICKitchenScaleNutritionFactTypeCalorie + case .totalCalorie:self = .ICKitchenScaleNutritionFactTypeTotalCalorie + case .fat :self = .ICKitchenScaleNutritionFactTypeFat + case .totalFat:self = .ICKitchenScaleNutritionFactTypeTotalFat + case .protein:self = .ICKitchenScaleNutritionFactTypeProtein + case .totalProtein:self = .ICKitchenScaleNutritionFactTypeTotalProtein + case .carbohydrates:self = .ICKitchenScaleNutritionFactTypeCarbohydrates + case .totalCarbohydrates:self = .ICKitchenScaleNutritionFactTypeTotalCarbohydrates + case .fiber:self = .ICKitchenScaleNutritionFactTypeFiber + case .totalFiber:self = .ICKitchenScaleNutritionFactTypeTotalFiber + case .cholesterd:self = .ICKitchenScaleNutritionFactTypeCholesterd + case .totalCholesterd:self = .ICKitchenScaleNutritionFactTypeTotalCholesterd + case .sodium:self = .ICKitchenScaleNutritionFactTypeSodium + case .totalSodium:self = .ICKitchenScaleNutritionFactTypeTotalSodium + case .sugar:self = .ICKitchenScaleNutritionFactTypeSugar + case .totalSugar:self = .ICKitchenScaleNutritionFactTypeTotalSugar + + default:self = .ICKitchenScaleNutritionFactTypeCalorie + + } + }; + + + /* + * 卡路里, 最大不超过4294967295 + */ + case ICKitchenScaleNutritionFactTypeCalorie = "ICKitchenScaleNutritionFactTypeCalorie", + + /* + * 总卡路里, 最大不超过4294967295 + */ + ICKitchenScaleNutritionFactTypeTotalCalorie = "ICKitchenScaleNutritionFactTypeTotalCalorie", + + /* + * 总脂肪 + */ + ICKitchenScaleNutritionFactTypeTotalFat = "ICKitchenScaleNutritionFactTypeTotalFat", + + /* + * 总蛋白质 + */ + ICKitchenScaleNutritionFactTypeTotalProtein = "ICKitchenScaleNutritionFactTypeTotalProtein", + + /* + * 总碳水化合物 + */ + ICKitchenScaleNutritionFactTypeTotalCarbohydrates = "ICKitchenScaleNutritionFactTypeTotalCarbohydrates", + + /* + * 总脂肪纤维 + */ + ICKitchenScaleNutritionFactTypeTotalFiber = "ICKitchenScaleNutritionFactTypeTotalFiber", + + /* + * 总胆固醇 + */ + ICKitchenScaleNutritionFactTypeTotalCholesterd = "ICKitchenScaleNutritionFactTypeTotalCholesterd", + + /* + * 总钠含量 + */ + ICKitchenScaleNutritionFactTypeTotalSodium = "ICKitchenScaleNutritionFactTypeTotalSodium", + + /* + * 总糖含量 + */ + ICKitchenScaleNutritionFactTypeTotalSugar = "ICKitchenScaleNutritionFactTypeTotalSugar", + + /* + * 脂肪 + */ + ICKitchenScaleNutritionFactTypeFat = "ICKitchenScaleNutritionFactTypeFat", + + /* + * 蛋白质 + */ + ICKitchenScaleNutritionFactTypeProtein = "ICKitchenScaleNutritionFactTypeProtein", + + /* + * 碳水化合物 + */ + ICKitchenScaleNutritionFactTypeCarbohydrates = "ICKitchenScaleNutritionFactTypeCarbohydrates", + + /* + * 膳食纤维 + */ + ICKitchenScaleNutritionFactTypeFiber = "ICKitchenScaleNutritionFactTypeFiber", + + /* + * 胆固醇 + */ + ICKitchenScaleNutritionFactTypeCholesterd = "ICKitchenScaleNutritionFactTypeCholesterd", + + /* + * 钠含量 + */ + ICKitchenScaleNutritionFactTypeSodium = "ICKitchenScaleNutritionFactTypeSodium", + + /* + * 糖含量 + */ + ICKitchenScaleNutritionFactTypeSugar = "ICKitchenScaleNutritionFactTypeSugar" +} diff --git a/ios/Classes/model/KitchenData.swift b/ios/Classes/model/KitchenData.swift new file mode 100644 index 0000000..c080200 --- /dev/null +++ b/ios/Classes/model/KitchenData.swift @@ -0,0 +1,166 @@ +// +// KitchenData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class KitchenData:Codable{ + + + init(data:ICKitchenScaleData){ + isStabilized=data.isStabilized + value_mg=data.value_mg + value_g=data.value_g + value_ml=data.value_ml + value_ml_milk=data.value_ml_milk + value_oz=data.value_oz + value_lb=data.value_lb + value_lb_oz=data.value_lb_oz + value_fl_oz=data.value_fl_oz + value_fl_oz_uk=data.value_fl_oz_uk + value_fl_oz_milk=data.value_fl_oz_milk + value_fl_oz_milk_uk=data.value_fl_oz_milk_uk + time=data.time + precision=data.precision + precision_g=data.precision_g + precision_ml=data.precision_ml + precision_lboz=data.precision_lboz + precision_oz=data.precision_oz + precision_ml_milk=data.precision_ml_milk + precision_floz_us=data.precision_floz_us + precision_floz_uk=data.precision_floz_uk + precision_floz_milk_us=data.precision_floz_milk_us + precision_floz_milk_uk=data.precision_floz_milk_uk + unitType=data.unitType + isNegative=data.isNegative + isTare = data.isTare + unit = KitchenScaleUnit.init(type: data.unit) + }; + + + /** + 是否稳定数据, 不稳定的数据只做展示用,请勿保存 + */ + var isStabilized=false; + + /** + 数据值,单位:mg + */ + var value_mg :UInt; + + /** + 数据值,单位:g + */ + var value_g:Float; + + /** + 数据值,单位:ml + */ + var value_ml:Float; + /** + 数据值,单位:ml milk + */ + var value_ml_milk:Float; + + /** + 数据值,单位:oz + */ + var value_oz:Float; + + /** + 数据值,单位:lb:oz中的lb + */ + var value_lb:UInt; + + /** + 数据值,单位:lb:oz中的oz + */ + var value_lb_oz:Float; + + /** + 数据值,单位:fl.oz,美制 + */ + var value_fl_oz:Float; + + /** + 数据值,单位:fl.oz,英制 + */ + var value_fl_oz_uk:Float; + + /** + 数据值,单位:fl.oz,美制 + */ + var value_fl_oz_milk:Float; + + /** + 数据值,单位:fl.oz,英制 + */ + var value_fl_oz_milk_uk:Float; + + /** + 测量时间戳(秒) + */ + var time:UInt; + + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision:UInt = 1; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_g:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_ml:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_lboz:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_oz:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_ml_milk:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_floz_us:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_floz_uk:UInt; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_floz_milk_us:UInt; + + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + var precision_floz_milk_uk:UInt; + /** + 设备数据单位类型,0:公制,1:美制,2:英制 + */ + var unitType:UInt; + + /** + 数字是否负数 + */ + var isNegative = false; + + /** + 是否去皮模式 + */ + var isTare = false; + + /** + ///本次数据单位 + */ + var unit:KitchenScaleUnit +} diff --git a/ios/Classes/model/RulerData.swift b/ios/Classes/model/RulerData.swift new file mode 100644 index 0000000..cdac753 --- /dev/null +++ b/ios/Classes/model/RulerData.swift @@ -0,0 +1,88 @@ +// +// RulerData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class RulerData :Codable{ + + + init(data:ICRulerData){ + isStabilized=data.isStabilized + distance=data.distance + distance_in=data.distance_in + distance_ft=data.distance_ft + distance_ft_in=data.distance_ft_in + distance_cm=data.distance_cm + precision_in=data.precision_in + precision_cm=data.precision_cm + unit = RulerUnit.init(type: data.unit) + mode = RulerMeasureMode.init(type: data.mode) + time=data.time + partsType = RulerBodyPartsType.init(type: data.partsType) + }; + + + /** + 是否稳定数据 + @notice 如果数据不稳定,则只有distance有效,不稳定的数据只做展示用,请勿保存 + */ + var isStabilized=false; + + /** + 测量长度(0.1mm) + */ + var distance:UInt; + + /** + 距离inch + */ + var distance_in:Float; + + /** + 距离ft + */ + var distance_ft:UInt; + /** + 距离ft'in + */ + var distance_ft_in:Float; + + /** + 距离cm + */ + var distance_cm:Float; + + /** + inch距离小数点位数,如:distance_in=70.12,则precision_in=2,distance_in=71.5,则precision_in=1 + */ + var precision_in:UInt = 1; + + /** + cm距离小数点位数,如:distance_cm=70.12,则precision_cm=2,distance_cm=71.5,则precision_cm=1 + */ + var precision_cm:UInt = 1; + + /** + * + 本次测量的单位 + */ + var unit = RulerUnit.ICRulerUnitCM; + + /** + 本次测量的单位 + */ + var mode = RulerMeasureMode.ICRulerMeasureModeLength; + + + /** + 时间戳 + */ + var time:UInt; + + /** + 身体部位类型 + */ + var partsType = RulerBodyPartsType.ICRulerPartsTypeCalf; +} diff --git a/ios/Classes/model/ScanDeviceInfo.swift b/ios/Classes/model/ScanDeviceInfo.swift new file mode 100644 index 0000000..d40406c --- /dev/null +++ b/ios/Classes/model/ScanDeviceInfo.swift @@ -0,0 +1,77 @@ +// +// ScanDeviceInfo.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/9. +// + + +class ScanDeviceInfo:Codable{ + + + init(deviceInfo:ICScanDeviceInfo){ + name = deviceInfo.name + type = DeviceType.init(type:deviceInfo.type) + subType = DeviceSubType.init(type:deviceInfo.subType) + communicationType = DeviceCommunicationType.init(type:deviceInfo.communicationType) + macAddr = deviceInfo.macAddr + services = deviceInfo.services + rssi = deviceInfo.rssi + nodeId = deviceInfo.nodeId + st_no = deviceInfo.st_no + deviceFlag = deviceInfo.deviceFlag + + } + /** + * 广播名 + */ + var name: String? + + /** + * 设备类型 + */ + var type: DeviceType? + + /** + * 设备子类型 + */ + var subType: DeviceSubType? + + /** + * 设备通讯方式 + */ + var communicationType: DeviceCommunicationType? + + /** + * mac地址 + */ + var macAddr: String? + + /** + * 服务ID列表 + */ + var services: Array? + + /** + * 信号强度(越小越大,0:系统配对设备,-128:信号值有误) + */ + var rssi: Int? + + /** + * 基站随机码 + */ + var st_no: UInt? + + /** + * 节点ID + */ + var nodeId: UInt? + + /** + * 设备标记,0表示没有 + */ + var deviceFlag: UInt? + + +} + diff --git a/ios/Classes/model/SkipData.swift b/ios/Classes/model/SkipData.swift new file mode 100644 index 0000000..964ddb8 --- /dev/null +++ b/ios/Classes/model/SkipData.swift @@ -0,0 +1,126 @@ +// +// SkipData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class SkipData :Codable{ + + init(data:ICSkipData){ + isStabilized=data.isStabilized + nodeId=data.nodeId + battery=data.battery + nodeInfo=data.nodeInfo + time=data.time + mode = SkipMode.init(type: data.mode.rawValue) + setting=data.setting + elapsed_time=data.elapsed_time + actual_time=data.actual_time + skip_count=data.skip_count + avg_freq=data.avg_freq + fastest_freq=data.fastest_freq + freq_count=data.freq_count + most_jump=data.most_jump + calories_burned=data.calories_burned + fat_burn_efficiency=data.fat_burn_efficiency + var list = [SkipFreqData]() + data.freqs.forEach { (element) in + let freq = SkipFreqData.init(data:element) + list.append(freq) + } + freqs = ICJson.beanToJson(bean: list) + + }; + + + + + /** + 是否稳定 + */ + var isStabilized=false; + + /** + 节点ID + */ + var nodeId:UInt; + /** + 节点电量 + */ + var battery:UInt; + /** + 节点信息 + */ + var nodeInfo:UInt; + + /** + * 测量时间,单位:秒 + */ + var time:UInt; + + /** + * 跳绳模式 + */ + var mode = SkipMode.ICSkipModeFreedom; + + /** + * 设置的参数 + */ + var setting:UInt; + + /** + * 跳绳使用的时间 + */ + var elapsed_time:UInt; + + /** + * 跳绳实际使用的时间,不是所有都支持 + */ + var actual_time:UInt; + + /** + * 跳的次数 + */ + var skip_count:UInt; + + /** + * 平均频次 + */ + var avg_freq:UInt; + + /** + * 最快频次 + */ + var fastest_freq:UInt; + + + /** + * 绊绳总数 + */ + var freq_count :UInt; + + /** + * 最多连跳 + */ + var most_jump:UInt; + + + + /** + * 热量消耗 + */ + var calories_burned:Double; + + /** + * 燃脂效率 + */ + var fat_burn_efficiency:Double; + + + /** + * 跳绳频次数据 + */ + + var freqs : String?; +} diff --git a/ios/Classes/model/SkipFreqData.swift b/ios/Classes/model/SkipFreqData.swift new file mode 100644 index 0000000..463aa56 --- /dev/null +++ b/ios/Classes/model/SkipFreqData.swift @@ -0,0 +1,25 @@ +// +// SkipFreqData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class SkipFreqData:Codable{ + + + init(data:ICSkipFreqData){ + duration=data.duration + skip_count=data.skip_count + }; + + /** + * 持续时间 + */ + var duration :UInt; + + /** + * 次数 + */ + var skip_count :UInt; +} diff --git a/ios/Classes/model/SkipLightSettingData.swift b/ios/Classes/model/SkipLightSettingData.swift new file mode 100644 index 0000000..9d4af53 --- /dev/null +++ b/ios/Classes/model/SkipLightSettingData.swift @@ -0,0 +1,13 @@ +// +// SkipLightSettingData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class SkipLightSettingData:Codable{ + var r:UInt = 0; + var g:UInt = 0; + var b:UInt = 0; + var rpm:UInt = 0; +} diff --git a/ios/Classes/model/SkipSoundSettingData.swift b/ios/Classes/model/SkipSoundSettingData.swift new file mode 100644 index 0000000..03f8a93 --- /dev/null +++ b/ios/Classes/model/SkipSoundSettingData.swift @@ -0,0 +1,64 @@ +// +// SkipSoundSettingData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class SkipSoundSettingData:Codable{ + + + init(data:ICSkipSoundSettingData){ + soundOn=data.soundOn + soundType = SkipSoundType.init(type: data.soundType) + soundVolume=data.soundVolume + fullScoreOn=data.fullScoreOn + fullScoreBPM=data.fullScoreBPM + modeParam=data.modeParam + isAutoStop=data.isAutoStop + soundMode=SkipSoundMode.init(type: data.soundMode) + } + + + /* + 是否开启语音开关 + */ + var soundOn = false; + + /* + 语音类型 + */ + var soundType = SkipSoundType.ICSkipSoundTypeFemale; + + /* + 声音大小 + */ + var soundVolume:UInt = 0; + + /* + 满分开关 + */ + var fullScoreOn = false; + + /* + 满分速率 + */ + var fullScoreBPM :UInt = 0; + + /* + 语音间隔模式 + */ + var soundMode = SkipSoundMode.ICSkipSoundModeCount; + + /* + 模式参数 + */ + var modeParam:UInt = 0; + + /* + 是否自动停止播放,true:APP下发开始后,跳绳不会播放语音 ,false:跳绳和APP都会播放语音 + */ + var isAutoStop = false; + + +} diff --git a/ios/Classes/model/UserInfo.swift b/ios/Classes/model/UserInfo.swift new file mode 100644 index 0000000..e2481fd --- /dev/null +++ b/ios/Classes/model/UserInfo.swift @@ -0,0 +1,107 @@ +// +// UserInfo.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// +class UserInfo:Codable{ + + /** + 用户编号,默认:1 + */ + var userIndex :UInt = 1; + + /** + 用户ID,默认:0 + */ + var userId :UInt = 0; + + /** + 用户呢称,默认:"icomon" + */ + var nickName="icomon"; + + /** + 身高(cm),默认:172cm + */ + var height:UInt = 172; + + /** + 当前体重(kg),默认:60.0kg + */ + var weight:Float = 60; + /** + 目标体重(kg),默认:50.0kg + */ + var targetWeight:Float = 50; + + /** + 年龄,默认:24 + */ + var age:UInt = 24; + + /** + 体重方向,默认:0 减重,1:增重 + */ + var weightDirection:UInt = 0; + + /** + 使用体脂算法版本,默认:ICBFATypeWLA01 + */ + var bfaType = BFAType.ICBFATypeWLA01 + + /** + 用户类型,默认:ICPeopleTypeNormal + */ + var peopleType = PeopleType.ICPeopleTypeNormal; + + + /** + 性别,默认:ICSexTypeMale + */ + var sex = SexType.ICSexTypeMale; + + /** + 用户默认的体重单位,默认:ICWeightUnitKg + */ + var weightUnit = ScaleUnit.ICWeightUnitKg; + + /** + 用户默认的围尺单位,默认:ICRulerUnitCM + */ + var rulerUnit=RulerUnit.ICRulerUnitCM; + + /** + 用户默认的围尺测量模式,默认:ICRulerMeasureModeLength + */ + var rulerMode = RulerMeasureMode.ICRulerMeasureModeLength; + + + /** + 厨房秤默认单位,默认:ICKitchenScaleUnitG + */ + var kitchenUnit = KitchenScaleUnit.ICKitchenScaleUnitG; + + /** + * 是否启用测量阻抗,默认:true,仅支持的设备有效 + */ + var enableMeasureImpendence = true; + /** + * 是否启用测量HR,默认:true,仅支持的设备有效 + */ + var enableMeasureHr = true; + /** + * 是否启用测量平衡,默认:true,仅支持的设备有效 + */ + var enableMeasureBalance = true; + /** + * 是否启用测量重心,默认:true,仅支持的设备有效 + */ + var enableMeasureGravity = true; + + /** + * 最后一次的阻抗 + */ + var lastImp:UInt = 0; + +} diff --git a/ios/Classes/model/WeightCenterData.swift b/ios/Classes/model/WeightCenterData.swift new file mode 100644 index 0000000..e263ddf --- /dev/null +++ b/ios/Classes/model/WeightCenterData.swift @@ -0,0 +1,128 @@ +// +// WeightCenterData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class WeightCenterData:Codable{ + + + init(data:ICWeightCenterData){ + isStabilized=data.isStabilized + time=data.time + precision_kg=data.precision_kg + precision_lb=data.precision_lb + precision_st_lb=data.precision_st_lb + kg_scale_division=data.kg_scale_division + lb_scale_division=data.lb_scale_division + leftPercent=data.leftPercent + rightPercent=data.rightPercent + left_weight_g=data.left_weight_g + right_weight_g=data.right_weight_g + left_weight_kg=data.left_weight_kg + right_weight_kg=data.right_weight_kg + left_weight_lb=data.left_weight_lb + right_weight_lb=data.right_weight_lb + left_weight_st=data.left_weight_st + right_weight_st=data.right_weight_st + left_weight_st_lb=data.left_weight_st_lb + right_weight_st_lb=data.right_weight_st_lb + + }; + + /** + 数据是否稳定, 不稳定的数据只做展示用,请勿保存 + */ + var isStabilized=false; + + /** + 测量时间戳(秒) + */ + var time:UInt; + + /** + kg体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_kg=1 + */ + var precision_kg:UInt = 1; + + /** + lb体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_lb=1 + */ + var precision_lb:UInt = 1; + + /** + st:lb体重小数点位数 + */ + var precision_st_lb:UInt = 1; + + /** + kg分度值 + */ + var kg_scale_division:UInt; + + /** + lb分度值 + */ + var lb_scale_division:UInt; + + /** + 左边体重占比(%) + */ + var leftPercent:Float; + + /** + 右边体重占比(%) + */ + var rightPercent:Float; + + /** + 左边体重(g) + */ + var left_weight_g:UInt; + + /** + 右边体重(g) + */ + var right_weight_g:UInt; + /** + 左边体重(kg) + */ + var left_weight_kg:Float; + + /** + 右边体重(kg) + */ + var right_weight_kg:Float; + + /** + 左边体重(lb) + */ + var left_weight_lb:Float; + + /** + 右边体重(lb) + */ + var right_weight_lb:Float; + + /** + 左边体重(st:lb) + */ + var left_weight_st:UInt; + + /** + 右边体重(st:lb) + */ + var right_weight_st:UInt; + + /** + 左边体重(st:lb) + */ + var left_weight_st_lb:Float; + + /** + 右边体重(st:lb) + */ + var right_weight_st_lb:Float; + +} diff --git a/ios/Classes/model/WeightData.swift b/ios/Classes/model/WeightData.swift new file mode 100644 index 0000000..f69907d --- /dev/null +++ b/ios/Classes/model/WeightData.swift @@ -0,0 +1,372 @@ +// +// WeightData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/9. +// + +class WeightData :Codable{ + + init(data:ICWeightData){ + userId=data.userId + isStabilized=data.isStabilized + weight_g=data.weight_g + weight_kg=data.weight_kg + weight_lb=data.weight_lb + weight_st=data.weight_st + weight_st_lb=data.weight_st_lb + precision_kg=data.precision_kg + precision_lb=data.precision_lb + precision_st_lb=data.precision_st_lb + kg_scale_division=data.kg_scale_division + lb_scale_division=data.lb_scale_division + temperature=data.temperature + isSupportHR=data.isSupportHR + hr=data.hr + time=data.time + bmi=data.bmi + bodyFatPercent=data.bodyFatPercent + subcutaneousFatPercent=data.subcutaneousFatPercent + visceralFat=data.visceralFat + musclePercent=data.musclePercent + bmr=data.bmr + boneMass=data.boneMass + moisturePercent=data.moisturePercent + physicalAge=data.physicalAge + proteinPercent=data.proteinPercent + smPercent=data.smPercent + electrode=data.electrode + bodyScore=data.bodyScore + bodyType=data.bodyType + targetWeight=data.targetWeight + bfmControl=data.bfmControl + ffmControl=data.ffmControl + weightControl=data.weightControl + weightStandard=data.weightStandard + bfmStandard=data.bfmStandard + bmiStandard=data.bmiStandard + smmStandard=data.smmStandard + ffmStandard=data.ffmStandard + bfpStandard=data.bfpStandard + + bmrStandard=data.bmrStandard + bmiMax=data.bmiMax + bmiMin=data.bmiMin + bfmMax=data.bfmMax + bfmMin=data.bfmMin + bfpMax=data.bfpMax + bfpMin=data.bfpMin + weightMax=data.weightMax + weightMin=data.weightMin + smmMax=data.smmMax + smmMin=data.smmMin + boneMax=data.boneMax + boneMin=data.boneMin + bmrMax=data.bmrMax + bmrMin=data.bmrMin + waterMassMax=data.waterMassMax + waterMassMin=data.waterMassMin + proteinMassMax=data.proteinMassMax + proteinMassMin=data.proteinMassMin + muscleMassMax=data.muscleMassMax + smi=data.smi + obesityDegree=data.obesityDegree + state=data.state + imp=data.imp + imp2=data.imp2 + imp3=data.imp3 + imp4=data.imp4 + imp5=data.imp5 + extData = WeightExtData.init(data: data.extData) + data_calc_type=data.data_calc_type + bfa_type = BFAType.init(type: data.bfa_type.rawValue) + impendenceType=data.impendenceType + impendenceProperty=data.impendenceProperty + impendences = [] + data.impendences?.forEach({ (element) in + impendences?.append(Float(truncating: element)) + }) + + }; + + /** + 用户ID,默认:0 + */ + var userId:UInt = 0; + + /** + 是否稳定数据,如果数据不稳定,则只有weight有效,不稳定的数据只做展示用,请勿保存 + */ + var isStabilized = false; + + /** + 体重(g) + */ + var weight_g:UInt = 0; + + /** + 体重(kg) + */ + var weight_kg :Float = 0.0 ; + + /** + 体重(磅) + */ + var weight_lb :Float = 0.0; + + /** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ + var weight_st:UInt ; + + /** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ + var weight_st_lb :Float = 0.0; + + /** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ + var precision_kg:UInt = 1; + + /** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ + var precision_lb :UInt = 1; + + /** + st:lb体重小数点位数 + */ + var precision_st_lb:UInt = 1; + + /** + kg分度值 + */ + var kg_scale_division:UInt = 0; + + /** + lb分度值 + */ + var lb_scale_division:UInt = 0; + + /** + 温度 + */ + var temperature:Float = 0.0; + + /** + 支持心率测量 + */ + var isSupportHR = false; + + /** + 心率值 + */ + var hr :UInt = 0; + + /** + 时间戳 + */ + var time:UInt = 0; + + /** + 身体质量指数BMI(精度:0.1) + */ + var bmi:Float = 0.0; + + /** + 体脂率(百分比, 精度:0.1) + */ + var bodyFatPercent :Float = 0.0; + + /** + 皮下脂肪率(百分比, 精度:0.1) + */ + var subcutaneousFatPercent : Float = 0.0; + + /** + 内脏脂肪指数(精度:0.1) + */ + var visceralFat : Float = 0.0; + + /** + 肌肉率(百分比, 精度:0.1) + */ + var musclePercent : Float = 0.0; + + /** + 基础代谢率(单位:kcal) + */ + var bmr:UInt = 0; + + /** + 骨重量(单位:kg,精度:0.1) + */ + var boneMass : Float = 0.0; + + /** + 水含量(百分比,精度:0.1) + */ + var moisturePercent : Float = 0.0; + + /** + 身体年龄 + */ + var physicalAge : Float = 0.0; + + /** + 蛋白率(百分比,精度:0.1) + */ + var proteinPercent : Float = 0.0; + + /** + 骨骼肌率(百分比,精度:0.1) + */ + var smPercent : Float = 0.0; + + /** + 电极数,4电极或者8电极 + */ + var electrode:UInt = 4; + + /** + 身体评分 + */ + var bodyScore : Float = 0.0; + + /** + 身体类型 + */ + var bodyType:UInt = 0; + + /** + 目标体重 + */ + var targetWeight : Float = 0.0; + + /** + 脂肪量控制 + */ + var bfmControl : Float = 0.0; + + /** + 去脂体重控制 + */ + var ffmControl : Float = 0.0; + + /** + 体重控制 + */ + var weightControl : Float = 0.0; + + /** + 标准体重 + */ + var weightStandard : Float = 0.0; + + /** + 标准脂肪量 + */ + var bfmStandard : Float = 0.0; + + /** + 标准BMI + */ + var bmiStandard : Float = 0.0; + + /** + 标准骨骼肌量 + */ + var smmStandard : Float = 0.0; + + /** + 标准去脂体重 + */ + var ffmStandard : Float = 0.0; + + var bfpStandard : Float = 0.0; // 标准脂肪率 + var bmrStandard:Int32 = 0; // 标准BMR + + var bmiMax : Float = 0.0; + var bmiMin : Float = 0.0; + var bfmMax : Float = 0.0; + var bfmMin : Float = 0.0; + var bfpMax : Float = 0.0; + var bfpMin : Float = 0.0; + var weightMax : Float = 0.0; + var weightMin : Float = 0.0; + var smmMax : Float = 0.0; + var smmMin : Float = 0.0; + var boneMax : Float = 0.0; + var boneMin : Float = 0.0; + var bmrMax:UInt = 0; + var bmrMin:UInt = 0; + var waterMassMax : Float = 0.0; + var waterMassMin : Float = 0.0; + var proteinMassMax : Float = 0.0; + var proteinMassMin : Float = 0.0; + var muscleMassMax : Float = 0.0; + var muscleMassMin : Float = 0.0; + + /** + 骨骼肌质量指数 + */ + var smi : Float = 0.0; + + /** + 肥胖程度 + */ + var obesityDegree :UInt = 0; + + var state :UInt = 0; + + /** + 全身阻抗(8电极)或全身阻抗(4电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp : Float = 0.0; + + /** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp2 : Float = 0.0; + + /** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp3 : Float = 0.0; + + /** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp4 : Float = 0.0; + + /** + 右腳阻抗(8电极)(单位:欧姆ohm),如:阻抗等于0,则代表测量不到阻抗 + */ + var imp5 : Float = 0.0; + + /** + 体重扩展数据(8电极的部分数据在这里面) + */ + var extData: WeightExtData? ; + + /** + 数据计算方式(0:sdk,1:设备计算,2:app计算) + */ + var data_calc_type :UInt = 0; + + /** + 本次体脂数据计算的算法类型 + */ + var bfa_type :BFAType = BFAType.ICBFATypeWLA02; + + var impendenceType :UInt = 0; + + var impendenceProperty:UInt = 0; + + + var impendences:[Float]?; + + +} + diff --git a/ios/Classes/model/WeightExtData.swift b/ios/Classes/model/WeightExtData.swift new file mode 100644 index 0000000..f14df61 --- /dev/null +++ b/ios/Classes/model/WeightExtData.swift @@ -0,0 +1,135 @@ +// +// WeightExtData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class WeightExtData:Codable{ + + init(data:ICWeightExtData){ + left_arm=data.left_arm + right_arm=data.right_arm + left_leg=data.left_leg + right_leg=data.right_leg + all_body=data.all_body + left_arm_kg=data.left_arm_kg + right_arm_kg=data.right_arm_kg + left_leg_kg=data.left_leg_kg + right_leg_kg=data.right_leg_kg + all_body_kg=data.all_body_kg + left_arm_muscle=data.left_arm_muscle + right_arm_muscle=data.right_arm_muscle + left_leg_muscle=data.left_leg_muscle + right_leg_muscle=data.right_leg_muscle + all_body_muscle=data.all_body_muscle + left_arm_muscle_kg=data.left_arm_muscle_kg + right_arm_muscle_kg=data.right_arm_muscle_kg + left_leg_muscle_kg=data.left_leg_muscle_kg + right_leg_muscle_kg=data.right_leg_muscle_kg + all_body_muscle_kg=data.all_body_muscle_kg + }; + + + + /** + 左手体脂率(单位:%, 精度:0.1) + */ + var left_arm :Float; + + /** + 右手体脂率(单位:%, 精度:0.1) + */ + var right_arm :Float; + + /** + 左脚体脂率(单位:%, 精度:0.1) + */ + var left_leg :Float; + + /** + 右脚体脂率(单位:%, 精度:0.1) + */ + var right_leg :Float; + + /** + 躯干体脂率(单位:%, 精度:0.1) + */ + var all_body :Float; + + /** + 左手脂肪量(单位:kg, 精度:0.1) + */ + var left_arm_kg :Float; + + /** + 右手脂肪量率(单位:kg, 精度:0.1) + */ + var right_arm_kg :Float; + + /** + 左脚脂肪量(单位:kg, 精度:0.1) + */ + var left_leg_kg :Float; + + /** + 右脚脂肪量(单位:kg, 精度:0.1) + */ + var right_leg_kg :Float; + + /** + 躯干脂肪量(单位:kg, 精度:0.1) + */ + var all_body_kg :Float; + + /** + 左手肌肉率(单位:%, 精度:0.1) + */ + var left_arm_muscle :Float; + + /** + 右手肌肉率(单位:%, 精度:0.1) + */ + var right_arm_muscle :Float; + + /** + 左脚肌肉率(单位:%, 精度:0.1) + */ + var left_leg_muscle :Float; + + /** + 右脚肌肉率(单位:%, 精度:0.1) + */ + var right_leg_muscle :Float; + + /** + 躯干肌肉率(单位:%, 精度:0.1) + */ + var all_body_muscle :Float; + + /** + 左手肌肉量(单位:kg, 精度:0.1) + */ + var left_arm_muscle_kg :Float; + + /** + 右手肌肉量(单位:kg, 精度:0.1) + */ + var right_arm_muscle_kg :Float; + + /** + 左脚肌肉量(单位:kg, 精度:0.1) + */ + var left_leg_muscle_kg :Float; + + /** + 右脚肌肉量(单位:kg, 精度:0.1) + */ + var right_leg_muscle_kg :Float; + + /** + 躯干肌肉量(单位:kg, 精度:0.1) + */ + var all_body_muscle_kg :Float; + +} diff --git a/ios/Classes/model/WeightHistoryData.swift b/ios/Classes/model/WeightHistoryData.swift new file mode 100644 index 0000000..3467dc0 --- /dev/null +++ b/ios/Classes/model/WeightHistoryData.swift @@ -0,0 +1,160 @@ +// +// WeightHistoryData.swift +// flutter_swift +// +// Created by 凉茶 on 2022/10/10. +// + +class WeightHistoryData :Codable{ + + init(data:ICWeightHistoryData){ + userId=data.userId + weight_g=data.weight_g + weight_kg=data.weight_kg + weight_lb=data.weight_lb + weight_st=data.weight_st + weight_st_lb=data.weight_st_lb + precision_kg=data.precision_kg + precision_lb=data.precision_lb + precision_st_lb=data.precision_st_lb + kg_scale_division=data.kg_scale_division + lb_scale_division=data.lb_scale_division + hr=data.hr + time=data.time + electrode=data.electrode + imp=data.imp + imp2=data.imp2 + imp3=data.imp3 + imp4=data.imp4 + imp5=data.imp5 + data_calc_type=data.data_calc_type + bfa_type = BFAType.init(type: data.bfa_type.rawValue) + impendenceType=data.impendenceType + impendenceProperty=data.impendenceProperty + impendences = [] + data.impendences.forEach { (element) in + impendences?.append(Float(truncating: element)) + } + + + }; + + /** + 用户ID,默认:0 + */ + var userId:UInt; + + /** + 体重(g) + */ + var weight_g :UInt; + + /** + 体重(kg) + */ + var weight_kg :Float; + + /** + 体重(lb) + */ + var weight_lb:Float; + + /** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ + var weight_st :UInt; + + /** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ + var weight_st_lb :Float; + + /** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ + var precision_kg:UInt = 1; + + /** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ + var precision_lb:UInt = 1; + + /** + st:lb体重小数点位数 + */ + var precision_st_lb:UInt = 1; + + /** + kg分度值 + */ + var kg_scale_division :UInt; + + /** + lb分度值 + */ + var lb_scale_division :UInt; + + /** + 测量时间戳(秒) + */ + var time :UInt; + + /** + 心率值 + */ + var hr :UInt; + + /** + 电极数,4电极或者8电极 + */ + var electrode:UInt = 4; + + /** + 全身阻抗(单位:欧姆ohm), `electrode=4`时,只使用这个阻抗,如阻抗等于0,则代表测量不到阻抗 + */ + var imp :Float; + + /** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp2 :Float; + + /** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp3 :Float; + + /** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp4 :Float; + + /** + 右腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + var imp5 :Float; + + /** + 平衡数据 + */ + + var centerData:WeightCenterData?; + + /** + 数据计算方式(0:sdk,1:设备计算) + */ + var data_calc_type :UInt; + + /** + 本次体脂数据计算的算法类型 + */ + var bfa_type = BFAType.ICBFATypeUnknown; + + var impendenceType :UInt; + + var impendenceProperty :UInt; + + var impendences:[Float]?; + + +} diff --git a/ios/icdevicemanager_flutter.podspec b/ios/icdevicemanager_flutter.podspec new file mode 100644 index 0000000..902a2ef --- /dev/null +++ b/ios/icdevicemanager_flutter.podspec @@ -0,0 +1,25 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint flutter_swift.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'icdevicemanager_flutter' + s.version = '1.0.0' + s.summary = 'A new Flutter project.' + s.description = <<-DESC +A new Flutter project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '9.0' + + + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' +end diff --git a/lib/callback/ICAddDeviceCallBack.dart b/lib/callback/ICAddDeviceCallBack.dart new file mode 100644 index 0000000..84b1e1c --- /dev/null +++ b/lib/callback/ICAddDeviceCallBack.dart @@ -0,0 +1,11 @@ + + + + +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +class ICAddDeviceCallBack { + final void Function(ICDevice icDevice, ICAddDeviceCallBackCode code) callBack; + ICAddDeviceCallBack({required this.callBack}); +} \ No newline at end of file diff --git a/lib/callback/ICCommonCallback.dart b/lib/callback/ICCommonCallback.dart new file mode 100644 index 0000000..f7c2dc2 --- /dev/null +++ b/lib/callback/ICCommonCallback.dart @@ -0,0 +1,7 @@ + + + +class ICCommonCallback { + final void Function(dynamic value) callBack; + ICCommonCallback({required this.callBack}); + } diff --git a/lib/callback/ICDeviceManagerCallback.dart b/lib/callback/ICDeviceManagerCallback.dart new file mode 100644 index 0000000..66cccd2 --- /dev/null +++ b/lib/callback/ICDeviceManagerCallback.dart @@ -0,0 +1,216 @@ + + +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + + +abstract class ICDeviceManagerDelegate{ + + + + + /* + * SDK初始化完成回调 + * @param bSuccess 初始化是否成功 + */ + void onInitFinish(bool bSuccess); + + + /* + 蓝牙改变状态回调 + + @param state 蓝牙状态 + */ + void onBleState(ICBleState state); + + /* + 设备连接状态回调 + + @param device 设备 + @param state 连接状态 + */ + void onDeviceConnectionChanged(ICDevice device,ICDeviceConnectState state); + + /* + 节点设备连接状态回调 + + @param device 设备 + @param nodeId 设备 + @param state 连接状态 + */ + void onNodeConnectionChanged(ICDevice device, int nodeId,ICDeviceConnectState state); + + /* + 体重秤数据回调 + + @param device 设备 + @param data 测量数据 + */ + void onReceiveWeightData(ICDevice device, ICWeightData data); + + /* + 厨房秤数据回调 + + @param device 设备 + @param data 测量数据 + */ + void onReceiveKitchenScaleData(ICDevice device, ICKitchenScaleData data); + + /* + 厨房秤单位改变 + + @param device 设备 + @param unit 改变后的单位 + */ + void onReceiveKitchenScaleUnitChanged(ICDevice device,ICKitchenScaleUnit unit); + + /* + 平衡秤坐标数据回调 + + @param device 设备 + @param data 测量坐标数据 + */ + void onReceiveCoordData(ICDevice device, ICCoordData data); + + /* + 围尺数据回调 + + @param device 设备 + @param data 测量数据 + */ + void onReceiveRulerData(ICDevice device, ICRulerData data); + + /* + 围尺历史数据回调 + + @param device 设备 + @param data 测量数据 + */ + void onReceiveRulerHistoryData(ICDevice device, ICRulerData data); + + /* + 重心秤重心数据回调 + + @param device 设备 + @param data 重心数数据 + */ + void onReceiveWeightCenterData(ICDevice device, ICWeightCenterData data); + + /* + 设备单位改变回调 + + @param device 设备 + @param unit 设备当前单位 + */ + void onReceiveWeightUnitChanged(ICDevice device,ICWeightUnit unit); + + /* + 围尺单位改变回调 + + @param device 设备 + @param unit 设备当前单位 + */ + void onReceiveRulerUnitChanged(ICDevice device,ICRulerUnit unit); + + /* + 围尺测量模式改变回调 + + @param device 设备 + @param mode 设备当前测量模式 + */ + void onReceiveRulerMeasureModeChanged(ICDevice device,ICRulerMeasureMode mode); + + /* + 分步骤体重、平衡、阻抗、心率数据回调 + + @param device 设备 + @param step 当前处于的步骤 + @param data 数据 + */ + void onReceiveMeasureStepData(ICDevice device,ICMeasureStep step, Object data); + + /* + 体重历史数据回调 + + @param device 设备 + @param data 体重历史数据 + */ + void onReceiveWeightHistoryData(ICDevice device, ICWeightHistoryData data); + + /* + 跳绳实时数据回调 + + @param device 设备 + @param data 体重历史数据 + */ + void onReceiveSkipData(ICDevice device, ICSkipData data); + /* + 跳绳历史数据回调 + + @param device 设备 + @param data 体重历史数据 + */ + void onReceiveHistorySkipData(ICDevice device, ICSkipData data); + + + /* + 电量 + + @param device 设备 + @param battery 电量,范围:0~100 + @param ext 扩展字段,如是基站跳绳,则该字段的值表示节点ID,类型:Integer + */ + void onReceiveBattery(ICDevice device, int battery, Object ext); + + /* + 设备升级状态回调 + @param device 设备 + @param status 升级状态 + @param percent 升级进度,范围:0~100 + */ + void onReceiveUpgradePercent(ICDevice device,ICUpgradeStatus status, int percent); + + /* + 设备信息回调 + + @param device 设备 + @param deviceInfo 设备信息 + */ + void onReceiveDeviceInfo(ICDevice device, ICDeviceInfo deviceInfo); + + /* + 调试数据回调 + + @param device 设备 + @param type 类型 + @param obj 数据 + */ + void onReceiveDebugData(ICDevice device, int type, Object obj); + + + /* + * 配网结果回调 + * @param device 设备 + * @param state 配网状态 + */ + void onReceiveConfigWifiResult(ICDevice device,ICConfigWifiState state); + + + + /* + 心率 + + @param device 设备 + @param hr 心率,范围:0~255 + */ + void onReceiveHR(ICDevice device, int hr); + +} \ No newline at end of file diff --git a/lib/callback/ICFatAlgorithmsSettingCallback.dart b/lib/callback/ICFatAlgorithmsSettingCallback.dart new file mode 100644 index 0000000..61ec185 --- /dev/null +++ b/lib/callback/ICFatAlgorithmsSettingCallback.dart @@ -0,0 +1,6 @@ +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; + +class ICFatAlgorithmsSettingCallback{ + final void Function(ICWeightData data) callBack; + ICFatAlgorithmsSettingCallback({required this.callBack}); +} \ No newline at end of file diff --git a/lib/callback/ICRemoveDeviceCallBack.dart b/lib/callback/ICRemoveDeviceCallBack.dart new file mode 100644 index 0000000..5eee863 --- /dev/null +++ b/lib/callback/ICRemoveDeviceCallBack.dart @@ -0,0 +1,9 @@ + + +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +class ICRemoveDeviceCallBack { + final void Function(ICDevice icDevice, ICRemoveDeviceCallBackCode code) callBack; + ICRemoveDeviceCallBack({required this.callBack}); +} \ No newline at end of file diff --git a/lib/callback/ICScanDeviceDelegate.dart b/lib/callback/ICScanDeviceDelegate.dart new file mode 100644 index 0000000..20f76c5 --- /dev/null +++ b/lib/callback/ICScanDeviceDelegate.dart @@ -0,0 +1,11 @@ + + +import 'package:icdevicemanager_flutter/model/device/ICScanDeviceInfo.dart'; + +abstract class ICScanDeviceDelegate{ + /* + * 扫描结果回调 + * @param deviceInfo 扫描到的设备信息 + */ + void onScanResult(ICScanDeviceInfo deviceInfo); +} \ No newline at end of file diff --git a/lib/callback/ICSettingCallback.dart b/lib/callback/ICSettingCallback.dart new file mode 100644 index 0000000..7c6c203 --- /dev/null +++ b/lib/callback/ICSettingCallback.dart @@ -0,0 +1,7 @@ + +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +class ICSettingCallback { + final void Function(ICSettingCallBackCode code) callBack; + ICSettingCallback({required this.callBack}); + } diff --git a/lib/ic_bluetooth_sdk.dart b/lib/ic_bluetooth_sdk.dart new file mode 100644 index 0000000..98326f8 --- /dev/null +++ b/lib/ic_bluetooth_sdk.dart @@ -0,0 +1,468 @@ +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICCommonCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICFatAlgorithmsSettingCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICScanDeviceDelegate.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_platform_interface.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipLightSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipSoundSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:icdevicemanager_flutter/model/other/ICDeviceManagerConfig.dart'; + +class IcBluetoothSdk { + static IcBluetoothSdk? _instance; + + IcBluetoothSdk._() { + IcBluetoothSdkPlatform.instance.onMethodCall(); + } + + static IcBluetoothSdk get instance => _instance ??= IcBluetoothSdk._(); + + /* + * 设置数据回调代理 + */ + void setDeviceManagerDelegate(ICDeviceManagerDelegate? delegate) { + IcBluetoothSdkPlatform.instance.setDeviceManagerDelegate(delegate); + } + + /* + * 设置扫描回调代理 + */ + void setDeviceScanDelegate(ICScanDeviceDelegate delegate) { + IcBluetoothSdkPlatform.instance.setDeviceScanDelegate(delegate); + } + + /* + * SDK初始化 + * @param config 配置 + */ + void initSDK(ICDeviceManagerConfig config) { + IcBluetoothSdkPlatform.instance.initSDK(config); + } + + /* + * 添加单个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void addDevice(ICDevice device, ICAddDeviceCallBack? callBack) async { + IcBluetoothSdkPlatform.instance.addDevice(device, callBack); + } + + /* + * 添加设备列表 + * + * + * @param devices 设备 + * @param callBack 回调 + * + * + */ + void addDevices(List devices, ICAddDeviceCallBack? callback) async { + IcBluetoothSdkPlatform.instance.addDevices(devices, callback); + } + + /* + * 删除单个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void removeDevice(ICDevice device, ICRemoveDeviceCallBack? callBack) async { + IcBluetoothSdkPlatform.instance.removeDevice(device, callBack); + } + + /* + * 删除多个设备 + * + * + * @param devices 设备 + * @param callBack 回调 + * + * + */ + void removeDevices( + List devices, ICRemoveDeviceCallBack? callBack) async { + IcBluetoothSdkPlatform.instance.removeDevices(devices, callBack); + } + + /* + * 升级单个设备 + * + * + * @param device device + * @param callBack 回调 + * + * + */ + void upgradeDevice(ICDevice device, String filePath, ICOTAMode mode) { + IcBluetoothSdkPlatform.instance.upgradeDevice(device, filePath, mode); + } + + /* + * 升级多个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void upgradeDevices(List devices, String filePath, ICOTAMode mode) { + IcBluetoothSdkPlatform.instance.upgradeDevices(devices, filePath, mode); + } + + /* + * 停止升级设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void stopUpgradeDevice(ICDevice device) { + IcBluetoothSdkPlatform.instance.stopUpgradeDevice(device); + } + + /* + * 停止升级多个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void stopUpgradeDevices(List devices) { + IcBluetoothSdkPlatform.instance.stopUpgradeDevices(devices); + } + + /* + * 扫描设备 + * + */ + void scanDevice(ICScanDeviceDelegate delegate) { + IcBluetoothSdkPlatform.instance.setDeviceScanDelegate(delegate); + IcBluetoothSdkPlatform.instance.scanDevice(); + } + + /* + * 停止扫描设备 + * + */ + void stopScan() { + IcBluetoothSdkPlatform.instance.setDeviceScanDelegate(null); + IcBluetoothSdkPlatform.instance.stopScan(); + } + + /* + * 同步当前用户信息 + * + * @param userInfo 用户 + * + */ + void updateUserInfo(ICUserInfo userInfo) { + IcBluetoothSdkPlatform.instance.updateUserInfo(userInfo); + } + + /* + * 下发用户列表 + * + * @param list 用户列表 + * + */ + void setUserList(List list) { + IcBluetoothSdkPlatform.instance.setUserList(list); + } + + /* + 设置称单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ + void setScaleUnit( + ICDevice device, ICWeightUnit unit, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setScaleUnit(device, unit, callback); + } + + /* + 设置围尺单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ + void setRulerUnit( + ICDevice device, ICRulerUnit unit, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setRulerUnit(device, unit, callback); + } + + /* + 设置围尺测量模式 + + @param device 设备 + @param mode 测量模式 + @param callback 回调 + */ + void setRulerMeasureMode(ICDevice device, ICRulerMeasureMode mode, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setRulerMeasureMode(device, mode, callback); + } + + /* + 设置当前围尺身体部位 + + @param device 设备 + @param type 身体部位 + @param callback 回调 + */ + void setRulerBodyPartsType(ICDevice device, ICRulerBodyPartsType type, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .setRulerBodyPartsType(device, type, callback); + } + + /* + 设置重量到厨房秤,单位:毫克 + + @param device 设备 + @param weight 重量,单位:毫克,最大不能超过65535毫克 + @param callback 回调 + */ + void setWeight( + ICDevice device, int weight, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setWeight(device, weight, callback); + } + + /* + 设置厨房秤去皮重量 + + @param device 设备 + @param callback 回调 + */ + void deleteTareWeight(ICDevice device, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.deleteTareWeight(device, callback); + } + + /* + 厨房秤关机 + + @param device 设备 + @param callback 回调 + */ + void powerOffKitchenScale( + ICDevice device, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.powerOffKitchenScale(device, callback); + } + + /* + 设置厨房秤计量单位 + + @param device 设备 + @param unit 单位,注:如果秤不支持该单位,将不会生效 + @param callback 回调 + */ + void setKitchenScaleUnit(ICDevice device, ICKitchenScaleUnit unit, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setKitchenScaleUnit(device, unit, callback); + } + + /* + 设置营养成分值到厨房秤 + + @param device 设备 + @param type 营养类型 + @param value 营养值 + @param callback 回调 + */ + void setNutritionFacts(ICDevice device, ICKitchenScaleNutritionFactType type, + int value, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .setNutritionFacts(device, type, value, callback); + } + + /* + * 开始跳绳 + * @param device 设备 + * @param mode 跳绳模式 + * @param param 模式参数 + * @param callback 回调 + */ + void startSkipMode(ICDevice device, ICSkipMode mode, int param, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .startSkipMode(device, mode, param, callback); + } + + /* + * 停止跳绳 + * @param device 设备 + * @param callback 回调 + */ + void stopSkip(ICDevice device, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.stopSkip(device, callback); + } + + /* + 设置用户信息给设备,调用该接口后,updateUserInfo接口将不会再对该设备生效 + 注意:目前仅跳绳设备支持 + + @param device 设备 + @param userInfo 用户信息 + */ + void setUserInfo(ICDevice device, ICUserInfo userInfo) async { + IcBluetoothSdkPlatform.instance.setUserInfo(device, userInfo); + } + + /* + * 设置跳绳设备灯效 + * @param device 设备 + * @param lightEffects 跳绳灯效颜色 + * @param mode 等效的模式 + * @param callback 回调 + */ + void setSkipLightSetting( + ICDevice device, + List lightEffects, + ICSkipLightMode mode, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .setSkipLightSetting(device, lightEffects, mode, callback); + } + + /* + * 设置跳绳设备音效 + * @param device 设备 + * @param config 音效设置 + * @param callback 回调 + */ + void setSkipSoundSetting(ICDevice device, ICSkipSoundSettingData config, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .setSkipSoundSetting(device, config, callback); + } + + /* + 双模设备配网 + + @param device 设备 + @param ssid WIFI SSID + @param password WIFI Password + */ + void configWifi(ICDevice device, String? ssid, String? password, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .configWifi(device, ssid, password, callback); + } + + /* + 双模设备设置域名 + + @param device 设备 + @param server App服务器域名,如:https://www.google.com + */ + void setServerUrl( + ICDevice device, String server, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setServerUrl(device, server, callback); + } + + /* + 设置厂商特定参数 + + @param device 设备 + @param type 根据客户意思不一样 + */ + void setOtherParams(ICDevice device, int type, Object param, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance + .setOtherParams(device, type, param, callback); + } + + /* + * 设置设备显示的项 + * @param device 设备 + * @param items UI项 + * @param callback 回调 + */ + void setScaleUIItems( + ICDevice device, List items, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setScaleUIItems(device, items, callback); + } + + /* + * 下发准备 + * @param device 基站设备 + * @param callback 回调 + */ + void lockStSkip(ICDevice device, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.lockStSkip(device, callback); + } + + /* + * 查询在线状态 + * @param device 基站设备 + * @param callback 回调 + */ + void queryStAllNode(ICDevice device, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.queryStAllNode(device, callback); + } + + /* + * 改变广播名 + * @param device 基站设备 + * @param name 广播名 + * @param callback 回调 + */ + void changeStName( + ICDevice device, String name, ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.changeStName(device, name, callback); + } + + /* + * 改变节点ID + * @param device 基站设备 + * @param dstId 节点设备更改后ID, 0~0xFF + * @param st_no 基站号码,0~0xFFFFFF + * @param callback 回调 + */ + void changeStNo(ICDevice device, int dstId, int st_no, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.changeStNo(device, dstId, st_no, callback); + } + + /* + * 设置调试命令 + * @param device 设备 + * @param cmd 命令 + * @param callback 回调 + */ + void setDebugCommand(ICDevice device, Map cmd, + ICSettingCallback? callback) async { + IcBluetoothSdkPlatform.instance.setDebugCommand(device, cmd, callback); + } + + void reCalcBodyFatWithWeightData(ICWeightData weightData, ICUserInfo userInfo, + ICFatAlgorithmsSettingCallback callback) { + IcBluetoothSdkPlatform.instance + .reCalcBodyFatWithWeightData(weightData, userInfo, callback); + } + + void getLogPath(ICCommonCallback callback) { + IcBluetoothSdkPlatform.instance.getLogPath(callback); + } +} diff --git a/lib/ic_bluetooth_sdk_method_channel.dart b/lib/ic_bluetooth_sdk_method_channel.dart new file mode 100644 index 0000000..a062e2d --- /dev/null +++ b/lib/ic_bluetooth_sdk_method_channel.dart @@ -0,0 +1,913 @@ +import 'dart:collection'; +import 'dart:convert'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICFatAlgorithmsSettingCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICScanDeviceDelegate.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_platform_interface.dart'; +import 'package:icdevicemanager_flutter/model/data/ICCoordData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICKitchenScaleData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICRulerData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipLightSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipSoundSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightHistoryData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICScanDeviceInfo.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:icdevicemanager_flutter/model/other/ICDeviceManagerConfig.dart'; +import 'package:icdevicemanager_flutter/model/other/ICMapKey.dart'; +import 'package:icdevicemanager_flutter/model/other/ICWPublishEvent.dart'; +import 'package:icdevicemanager_flutter/model/other/ICWUploadEvent.dart'; +import 'package:icdevicemanager_flutter/utils/ICConverUtil.dart'; + +import 'callback/ICCommonCallback.dart'; + + + +class MethodChannelIcBluetoothSdk extends IcBluetoothSdkPlatform { + @visibleForTesting + final channel = const MethodChannel('ic_bluetooth_sdk'); + + ICScanDeviceDelegate? scanDeviceDelegate; + + ICDeviceManagerDelegate? deviceManagerDelegate; + + @override + void setDeviceManagerDelegate(ICDeviceManagerDelegate? delegate) { + deviceManagerDelegate = delegate; + } + + @override + void setDeviceScanDelegate(ICScanDeviceDelegate? delegate) { + scanDeviceDelegate = delegate; + } + + @override + void onMethodCall() { + channel.setMethodCallHandler((call) => onReceiveMsg(call)); + } + + @override + void initSDK(ICDeviceManagerConfig config) async { + channel.invokeMethod(ICWPublishEvent.initSDK.value); + log("initSdk---"); + var result = await channel.invokeMethod(ICWPublishEvent.initSDK.value, ""); + + } + + + @override + void addDevice(ICDevice device, ICAddDeviceCallBack? callBack) async { + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + if (device.macAddr == null) return; + var result = + await channel.invokeMethod(ICWPublishEvent.addDevice.value, hashMap); + var resultCode = result[ICMapKey.EnumName]; + if (callBack != null) { + callBack.callBack(device, ICConverUtil.AddDeviceCallBackCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$result method"); + } + + @override + void addDevices(List devices, ICAddDeviceCallBack? callback) async { + for (var device in devices) { + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + if (device.macAddr == null) return; + var result = + await channel.invokeMethod(ICWPublishEvent.addDevice.value, hashMap); + var resultCode = result[ICMapKey.EnumName]; + if (callback != null) { + callback.callBack(device, ICConverUtil.AddDeviceCallBackCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$result method"); + } + + + + + + } + + @override + void changeStName( + ICDevice device, String name, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = + await channel.invokeMethod(ICWPublishEvent.changeStName.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void changeStNo(ICDevice device, int dstId, int st_no, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.DstId] = dstId; + hashMap[ICMapKey.StNo] = st_no; + + var result = + await channel.invokeMethod(ICWPublishEvent.changeStName.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void configWifi(ICDevice device, String? ssid, String? password, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + if (ssid == null) return; + if (password == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.SSID] = ssid; + hashMap[ICMapKey.Password] = password; + + var result = + await channel.invokeMethod(ICWPublishEvent.configWifi.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name method"); + } + + @override + void deleteTareWeight(ICDevice device, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + + var result = await channel.invokeMethod( + ICWPublishEvent.deleteTareWeight.value, hashMap); + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name key:"); + } + + @override + void lockStSkip(ICDevice device, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = + await channel.invokeMethod(ICWPublishEvent.lockStSkip.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void powerOffKitchenScale( + ICDevice device, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = await channel.invokeMethod( + ICWPublishEvent.powerOffKitchenScale.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void queryStAllNode(ICDevice device, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = await channel.invokeMethod( + ICWPublishEvent.queryStAllNode.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void removeDevice(ICDevice device, ICRemoveDeviceCallBack? callBack) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = + await channel.invokeMethod(ICWPublishEvent.removeDevice.value, hashMap); + var name = result[ICMapKey.Method]; + var resultCode = result[ICMapKey.EnumName]; + if (callBack != null) { + callBack.callBack(device, ICConverUtil.removeDeviceCallBackCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name method"); + } + + @override + void removeDevices( + List devices, ICRemoveDeviceCallBack? callBack) async { + if (devices.isEmpty) return; + for (var device in devices) { + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = await channel.invokeMethod( + ICWPublishEvent.removeDevice.value, hashMap); + var name = result[ICMapKey.Method]; + var resultCode = result[ICMapKey.EnumName]; + if (callBack != null) { + callBack.callBack( + device, ICConverUtil.removeDeviceCallBackCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name method"); + } + } + + @override + void scanDevice() async { + channel.invokeMethod(ICWPublishEvent.startScan.value, ""); + } + + @override + void setDebugCommand(ICDevice device, Map cmd, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + channel.invokeMethod(ICWPublishEvent.debugCommand.value, cmd); + } + + @override + void setKitchenScaleUnit(ICDevice device, ICKitchenScaleUnit unit, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = unit.name; + + var result = await channel.invokeMethod( + ICWPublishEvent.setKitchenSaleUnit.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setNutritionFacts(ICDevice device, ICKitchenScaleNutritionFactType type, + int value, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = type.name; + + var result = await channel.invokeMethod( + ICWPublishEvent.KitchenSetNutritionFacts.value, hashMap); + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + } + + @override + void setOtherParams(ICDevice device, int type, Object param, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.ObjectValue] = param; + var result = await channel.invokeMethod( + ICWPublishEvent.setOtherParams.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setRulerBodyPartsType(ICDevice device, ICRulerBodyPartsType type, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = type.name; + var result = await channel.invokeMethod( + ICWPublishEvent.setRulerBodyPartsType.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setRulerMeasureMode(ICDevice device, ICRulerMeasureMode mode, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = mode.name; + var result = await channel.invokeMethod( + ICWPublishEvent.setRulerMeasureMode.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setRulerUnit( + ICDevice device, ICRulerUnit unit, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = unit.name; + + var result = + await channel.invokeMethod(ICWPublishEvent.setRulerUnit.value, hashMap); + + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setScaleUIItems( + ICDevice device, List items, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.JsonValue] = json.encode(items); + var result = await channel.invokeMethod( + ICWPublishEvent.setScaleUIItems.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setScaleUnit( + ICDevice device, ICWeightUnit unit, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = unit.name; + log("ICBluetoothManger flutter 设置单位22222---${unit.name}"); + var result = + await channel.invokeMethod(ICWPublishEvent.setScaleUnit.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setServerUrl( + ICDevice device, String server, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.StringValue] = server; + var result = + await channel.invokeMethod(ICWPublishEvent.setServerUrl.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setSkipLightSetting( + ICDevice device, + List lightEffects, + ICSkipLightMode mode, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + List> jsonData = + lightEffects.map((dev) => dev.toJson()).toList(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = mode.name; + hashMap[ICMapKey.JsonValue] = json.encode(jsonData); + var result = await channel.invokeMethod( + ICWPublishEvent.skipLightSetting.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setSkipSoundSetting(ICDevice device, ICSkipSoundSettingData config, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.JsonValue] = json.encode(config.toJson()); + var result = await channel.invokeMethod( + ICWPublishEvent.skipSoundsSetting.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void setUserInfo(ICDevice device, ICUserInfo userInfo) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.JsonValue] = json.encode(userInfo.toJson()); + hashMap[ICMapKey.Mac] = device.macAddr; + + var result = + await channel.invokeMethod(ICWPublishEvent.skipSetUserInfo.value, hashMap); + var name = result[ICMapKey.Method]; + + log("ICBluetoothManger result---$name key:"); + } + + @override + void setUserList(List list) async { + var hashMap = HashMap(); + List> jsonData = + list.map((dev) => dev.toJson()).toList(); + hashMap[ICMapKey.JsonValue] = json.encode(jsonData); + + var result = + await channel.invokeMethod(ICWPublishEvent.setUserList.value, hashMap); + var name = result[ICMapKey.Method]; + + log("ICBluetoothManger result---$name key:"); + } + + @override + void setWeight( + ICDevice device, int weight, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.IntValue] = weight; + var result = + await channel.invokeMethod(ICWPublishEvent.setWeight.value, hashMap); + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name key:"); + } + + @override + void startSkipMode(ICDevice device, ICSkipMode mode, int setting, + ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.EnumName] = mode.name; + hashMap[ICMapKey.IntValue] = setting; + var result = + await channel.invokeMethod(ICWPublishEvent.startSkip.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void stopScan() async { + scanDeviceDelegate = null; + channel.invokeMethod(ICWPublishEvent.stopScan.value, ""); + } + + @override + void stopSkip(ICDevice device, ICSettingCallback? callback) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = + await channel.invokeMethod(ICWPublishEvent.stopSkip.value, hashMap); + var name = result[ICMapKey.Method]; + if (callback != null) { + var resultCode = result[ICMapKey.EnumName]; + callback.callBack(ICConverUtil.settingCodeNameOf(resultCode)); + } + log("ICBluetoothManger result---$name key:"); + } + + @override + void stopUpgradeDevice(ICDevice device) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + var result = await channel.invokeMethod( + ICWPublishEvent.stopOTADevice.value, hashMap); + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name method"); + } + + @override + void stopUpgradeDevices(List devices) async { + var hashMap = HashMap(); + List> jsonData = + devices.map((dev) => dev.toJson()).toList(); + hashMap[ICMapKey.JsonValue] = json.encode(jsonData); + + var result = await channel.invokeMethod( + ICWPublishEvent.stopOTADevices.value, hashMap); + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name method"); + } + + @override + void updateUserInfo(ICUserInfo userInfo) async { + var hashMap = HashMap(); + hashMap[ICMapKey.JsonValue] = json.encode(userInfo.toJson()); + + var result = await channel.invokeMethod( + ICWPublishEvent.updateUserInfo.value, hashMap); + var name = result[ICMapKey.Method]; + + log("ICBluetoothManger result---$name key:"); + } + + @override + void upgradeDevice(ICDevice device, String filePath, ICOTAMode mode) async { + if (device.macAddr == null) return; + var hashMap = HashMap(); + hashMap[ICMapKey.Mac] = device.macAddr; + hashMap[ICMapKey.StringValue] = filePath; + hashMap[ICMapKey.EnumName] = mode.name; + var result = + await channel.invokeMethod(ICWPublishEvent.otaDevice.value, hashMap); + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name method"); + } + + @override + void upgradeDevices( + List devices, String filePath, ICOTAMode mode) async { + var hashMap = HashMap(); + List> jsonData = + devices.map((dev) => dev.toJson()).toList(); + + hashMap[ICMapKey.JsonValue] = json.encode(jsonData); + hashMap[ICMapKey.StringValue] = filePath; + hashMap[ICMapKey.EnumName] = mode.name; + var result = + await channel.invokeMethod(ICWPublishEvent.otaDevices.value, hashMap); + var name = result[ICMapKey.Method]; + log("ICBluetoothManger result---$name method"); + } + + + @override + void reCalcBodyFatWithWeightData(ICWeightData weightData, ICUserInfo userInfo,ICFatAlgorithmsSettingCallback callBack) async { + var hashMap = HashMap(); + hashMap[ICMapKey.JsonValue] = json.encode(weightData.toJson()); + hashMap[ICMapKey.JsonValue2] = json.encode(userInfo.toJson()); + var result = await channel.invokeMethod(ICWPublishEvent.calcBodyFat.value, hashMap); + var data = result[ICMapKey.JsonValue]; + Map map = json.decode(data); + callBack.callBack(ICWeightData.fromJson(map)); + } + + @override + void getLogPath(ICCommonCallback? callback) async { + var hashMap = HashMap(); + var result = await channel.invokeMethod(ICWPublishEvent.getLogPath.value, hashMap); + var data = result[ICMapKey.StringValue]; + if (callback != null&&data!=null) { + callback.callBack(data); + } + + } + + + + onReceiveMsg(MethodCall call) { + String method = call.method; + log("onReceiveMsg-------------$method"); + var map = call.arguments; + map.forEach((key, value) { + log("onReceiveMsg-------------$key value $value"); + }); + var mac = map[ICMapKey.Mac]; + var jsonValue = map[ICMapKey.JsonValue]; + var enumName = map[ICMapKey.EnumName]; + var boolValue = map[ICMapKey.BoolValue]; + var intValue = map[ICMapKey.IntValue]; + + log("onReceiveMsg---method:$method mac: $mac value:$jsonValue " + " step: $enumName code: $boolValue "); + + if (ICWUploadEvent.initSDK.value == method) { + onInitFinish(boolValue as bool); + } else if (ICWUploadEvent.onBleState.value == method) { + onBleState(enumName as String); + } else if (ICWUploadEvent.onDeviceConnectionChanged.value == method) { + onDeviceConnectionChanged(mac as String, enumName as String); + } else if (ICWUploadEvent.onNodeConnectionChanged.value == method) { + onNodeConnectionChanged(mac as String, 0, enumName as String); + } else if (ICWUploadEvent.onReceiveWeightData.value == method) { + onReceiveWeightData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveKitchenScaleData.value == method) { + onReceiveKitchenScaleData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveKitchenScaleUnitChanged.value == + method) { + onReceiveKitchenScaleUnitChanged(mac as String, enumName as String); + } else if (ICWUploadEvent.onReceiveCoordData.value == method) { + onReceiveCoordData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveRulerData.value == method) { + onReceiveRulerData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveHrData.value == method) { + onReceiveHrData(mac as String, intValue as int); + } else if (ICWUploadEvent.onReceiveRulerHistoryData.value == method) { + onReceiveRulerHistoryData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveWeightCenterData.value == method) { + onReceiveWeightCenterData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveWeightUnitChanged.value == method) { + onReceiveWeightUnitChanged(mac as String, enumName as String); + } else if (ICWUploadEvent.onReceiveRulerUnitChanged.value == method) { + onReceiveRulerUnitChanged(mac as String, enumName as String); + } else if (ICWUploadEvent.onReceiveRulerMeasureModeChanged.value == + method) { + onReceiveRulerMeasureModeChanged(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveMeasureStepData.value == method) { + onReceiveMeasureStepData( + mac as String, enumName as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveWeightHistoryData.value == method) { + onReceiveWeightHistoryData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveSkipData.value == method) { + onReceiveSkipData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveHistorySkipData.value == method) { + onReceiveHistorySkipData(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveSkipBattery.value == method) { + onReceiveSkipBattery(mac as String, jsonValue as int); + } else if (ICWUploadEvent.onReceiveUpgradePercent.value == method) { + onReceiveUpgradePercent( + mac as String, enumName as String, intValue as int); + } else if (ICWUploadEvent.onReceiveDeviceInfo.value == method) { + onReceiveDeviceInfo(mac as String, jsonValue as String); + } else if (ICWUploadEvent.onReceiveBattery.value == method) { + onReceiveBattery(mac as String, jsonValue as int); + } else if (ICWUploadEvent.onReceiveDebugData.value == method) { + onReceiveDebugData(mac as String, 0, jsonValue as String); + } else if (ICWUploadEvent.onReceiveConfigWifiResult.value == method) { + onReceiveConfigWifiResult(mac as String, enumName as String); + } else if (ICWUploadEvent.onScanResult.value == method) { + onScanResult(jsonValue as String); + } else if (ICWUploadEvent.onSettingCallBack.value == method) { + onSettingCallBack(enumName as String); + } + } + + void onInitFinish(bool finish) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onInitFinish(finish); + } + } + + void onBleState(String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onBleState(ICConverUtil.nameOf(data)); + } + } + + void onDeviceConnectionChanged(String mac, String stateName) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onDeviceConnectionChanged( + ICDevice(mac),ICConverUtil.connectStateNameOf(stateName)); + } + } + + void onNodeConnectionChanged(String mac, int nodeId, String state) {} + + void onReceiveWeightData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveWeightData(ICDevice(mac), ICWeightData.fromJson(map)); + } + } + + void onReceiveKitchenScaleData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate!.onReceiveKitchenScaleData( + ICDevice(mac), ICKitchenScaleData.fromJson(map)); + } + } + + void onReceiveKitchenScaleUnitChanged(String mac, String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveKitchenScaleUnitChanged( + ICDevice(mac), ICConverUtil.kitChenScaleUnitNameOf(data)); + } + } + + void onReceiveCoordData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveCoordData(ICDevice(mac), ICCoordData.fromJson(map)); + } + } + + void onReceiveRulerData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveRulerData(ICDevice(mac), ICRulerData.fromJson(map)); + } + } + + void onReceiveHrData(String mac, int hr) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveHR(ICDevice(mac), hr); + } + } + + void onReceiveRulerHistoryData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveRulerHistoryData(ICDevice(mac), ICRulerData.fromJson(map)); + } + } + + void onReceiveWeightCenterData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate!.onReceiveWeightCenterData( + ICDevice(mac), ICWeightCenterData.fromJson(map)); + } + } + + void onReceiveWeightUnitChanged(String mac, String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveWeightUnitChanged(ICDevice(mac), ICConverUtil.weightUnitNameOf(data)); + } + } + + void onReceiveRulerUnitChanged(String mac, String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate! + .onReceiveRulerUnitChanged(ICDevice(mac), ICConverUtil.rulerUnitNameOf(data)); + } + } + + void onReceiveRulerMeasureModeChanged(String mac, String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveRulerMeasureModeChanged( + ICDevice(mac), ICConverUtil.rulerMeasureModeNameOf(data)); + } + } + + void onReceiveMeasureStepData(String mac, String step, String data) { + Map map = json.decode(data); + if (deviceManagerDelegate != null) { + var measureStep = ICConverUtil.measureStepNameOf(step); + if (measureStep == ICMeasureStep.ICMeasureStepMeasureCenterData) { + deviceManagerDelegate!.onReceiveMeasureStepData(ICDevice(mac), + ICConverUtil.measureStepNameOf(step), ICWeightCenterData.fromJson(map)); + } else { + deviceManagerDelegate!.onReceiveMeasureStepData(ICDevice(mac), + ICConverUtil.measureStepNameOf(step), ICWeightData.fromJson(map)); + } + } + } + + void onReceiveWeightHistoryData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate!.onReceiveWeightHistoryData( + ICDevice(mac), ICWeightHistoryData.fromJson(map)); + } + } + + void onReceiveSkipData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveSkipData(ICDevice(mac), ICSkipData.fromJson(map)); + } + } + + void onReceiveHistorySkipData(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveSkipData(ICDevice(mac), ICSkipData.fromJson(map)); + } + } + + void onReceiveSkipBattery(String mac, int i) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveBattery(ICDevice(mac), i, Object()); + } + } + + void onReceiveUpgradePercent(String mac, String step, int i) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveUpgradePercent( + ICDevice(mac), ICConverUtil.upgradeStatusNameOf(step), i); + } + } + + void onReceiveDeviceInfo(String mac, String data) { + if (deviceManagerDelegate != null) { + Map map = json.decode(data); + deviceManagerDelegate! + .onReceiveDeviceInfo(ICDevice(mac), ICDeviceInfo.fromJson(map)); + } + } + + void onReceiveBattery(String mac, int i) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveBattery(ICDevice(mac), i, Object()); + } + } + + void onReceiveDebugData(String mac, int i, String o) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveDebugData(ICDevice(mac), i, Object()); + } + } + + void onReceiveConfigWifiResult(String mac, String data) { + if (deviceManagerDelegate != null) { + deviceManagerDelegate!.onReceiveConfigWifiResult( + ICDevice(mac), ICConverUtil.wifiStateNameOf(data)); + } + } + + void onScanResult(String data) { + if (scanDeviceDelegate != null) { + Map map = json.decode(data); + + var icScanDeviceInfo = ICScanDeviceInfo.fromJson(map); + scanDeviceDelegate!.onScanResult(icScanDeviceInfo); + } + } + + void onSettingCallBack(String data) { + + } + + + + + +} diff --git a/lib/ic_bluetooth_sdk_platform_interface.dart b/lib/ic_bluetooth_sdk_platform_interface.dart new file mode 100644 index 0000000..5fe1a3a --- /dev/null +++ b/lib/ic_bluetooth_sdk_platform_interface.dart @@ -0,0 +1,396 @@ +import 'package:flutter/foundation.dart'; +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICCommonCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICFatAlgorithmsSettingCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICScanDeviceDelegate.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_method_channel.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipLightSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipSoundSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'model/other/ICDeviceManagerConfig.dart'; + +abstract class IcBluetoothSdkPlatform extends PlatformInterface { + /// Constructs a IcBluetoothSdkPlatform. + IcBluetoothSdkPlatform() : super(token: _token); + + static final Object _token = Object(); + + static IcBluetoothSdkPlatform _instance = MethodChannelIcBluetoothSdk(); + + /// The default instance of [IcBluetoothSdkPlatform] to use. + /// + /// Defaults to [MethodChannelIcBluetoothSdk]. + static IcBluetoothSdkPlatform get instance => _instance; + + static set instance(IcBluetoothSdkPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /* + 设置称单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ + void setScaleUnit( + ICDevice device, ICWeightUnit unit, ICSettingCallback? callback); + + /* + 设置围尺单位 + + @param device 设备 + @param unit 单位 + @param callback 回调 + */ + void setRulerUnit( + ICDevice device, ICRulerUnit unit, ICSettingCallback? callback); + + /* + 设置围尺测量模式 + + @param device 设备 + @param mode 测量模式 + @param callback 回调 + */ + void setRulerMeasureMode( + ICDevice device, ICRulerMeasureMode mode, ICSettingCallback? callback); + + /* + 设置当前围尺身体部位 + + @param device 设备 + @param type 身体部位 + @param callback 回调 + */ + void setRulerBodyPartsType( + ICDevice device, ICRulerBodyPartsType type, ICSettingCallback? callback); + + /* + 设置重量到厨房秤,单位:毫克 + + @param device 设备 + @param weight 重量,单位:毫克,最大不能超过65535毫克 + @param callback 回调 + */ + void setWeight(ICDevice device, int weight, ICSettingCallback? callback); + + /* + 设置厨房秤去皮重量 + + @param device 设备 + @param callback 回调 + */ + void deleteTareWeight(ICDevice device, ICSettingCallback? callback); + + /* + 厨房秤关机 + + @param device 设备 + @param callback 回调 + */ + void powerOffKitchenScale(ICDevice device, ICSettingCallback? callback); + + /* + 设置厨房秤计量单位 + + @param device 设备 + @param unit 单位,注:如果秤不支持该单位,将不会生效 + @param callback 回调 + */ + void setKitchenScaleUnit( + ICDevice device, ICKitchenScaleUnit unit, ICSettingCallback? callback); + + /* + 设置营养成分值到厨房秤 + + @param device 设备 + @param type 营养类型 + @param value 营养值 + @param callback 回调 + */ + void setNutritionFacts(ICDevice device, ICKitchenScaleNutritionFactType type, + int value, ICSettingCallback? callback); + + /* + * 开始跳绳 + * @param device 设备 + * @param mode 跳绳模式 + * @param param 模式参数 + * @param callback 回调 + */ + void startSkipMode( + ICDevice device, ICSkipMode mode, int param, ICSettingCallback? callback); + + /* + * 停止跳绳 + * @param device 设备 + * @param callback 回调 + */ + void stopSkip(ICDevice device, ICSettingCallback? callback); + + /* + 设置用户信息给设备,调用该接口后,updateUserInfo接口将不会再对该设备生效 + 注意:目前仅跳绳设备支持 + + @param device 设备 + @param userInfo 用户信息 + */ + void setUserInfo(ICDevice device, ICUserInfo userInfo); + + /* + 双模设备配网 + + @param device 设备 + @param ssid WIFI SSID + @param password WIFI Password + */ + void configWifi(ICDevice device, String? ssid, String? password, + ICSettingCallback? callback); + + /* + 双模设备设置域名 + + @param device 设备 + @param server App服务器域名,如:https://www.google.com + */ + void setServerUrl( + ICDevice device, String server, ICSettingCallback? callback); + + /* + 设置厂商特定参数 + + @param device 设备 + @param type 根据客户意思不一样 + */ + void setOtherParams( + ICDevice device, int type, Object param, ICSettingCallback? callback); + + /* + * 设置跳绳设备灯效 + * @param device 设备 + * @param lightEffects 跳绳灯效颜色 + * @param mode 等效的模式 + * @param callback 回调 + */ + void setSkipLightSetting( + ICDevice device, + List lightEffects, + ICSkipLightMode mode, + ICSettingCallback? callback); + + /* + * 设置设备显示的项 + * @param device 设备 + * @param items UI项 + * @param callback 回调 + */ + void setScaleUIItems( + ICDevice device, List items, ICSettingCallback? callback); + + /* + * 设置跳绳设备音效 + * @param device 设备 + * @param config 音效设置 + * @param callback 回调 + */ + void setSkipSoundSetting(ICDevice device, ICSkipSoundSettingData config, + ICSettingCallback? callback); + + /* + * 下发准备 + * @param device 基站设备 + * @param callback 回调 + */ + void lockStSkip(ICDevice device, ICSettingCallback? callback); + + /* + * 查询在线状态 + * @param device 基站设备 + * @param callback 回调 + */ + void queryStAllNode(ICDevice device, ICSettingCallback? callback); + + /* + * 改变广播名 + * @param device 基站设备 + * @param name 广播名 + * @param callback 回调 + */ + void changeStName(ICDevice device, String name, ICSettingCallback? callback); + + /* + * 改变节点ID + * @param device 基站设备 + * @param dstId 节点设备更改后ID, 0~0xFF + * @param st_no 基站号码,0~0xFFFFFF + * @param callback 回调 + */ + void changeStNo( + ICDevice device, int dstId, int st_no, ICSettingCallback? callback); + + /* + * 设置调试命令 + * @param device 设备 + * @param cmd 命令 + * @param callback 回调 + */ + void setDebugCommand( + ICDevice device, Map cmd, ICSettingCallback? callback); + + /* + * SDK初始化 + * @param config 配置 + */ + void initSDK(ICDeviceManagerConfig config); + + /* + * 扫描设备 + * + */ + void scanDevice(); + + /* + * 停止扫描设备 + * + */ + void stopScan(); + + /* + * 添加单个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void addDevice(ICDevice device, ICAddDeviceCallBack? callBack); + + /* + * 添加设备列表 + * + * + * @param devices 设备 + * @param callBack 回调 + * + * + */ + void addDevices(List devices, ICAddDeviceCallBack? callback); + + /* + * 删除单个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void removeDevice(ICDevice device, ICRemoveDeviceCallBack? callBack); + + /* + * 删除多个设备 + * + * + * @param devices 设备 + * @param callBack 回调 + * + * + */ + void removeDevices(List devices, ICRemoveDeviceCallBack? callBack); + + /* + * 升级单个设备 + * + * + * @param device device + * @param callBack 回调 + * + * + */ + void upgradeDevice(ICDevice device, String filePath, ICOTAMode mode); + + /* + * 升级多个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void upgradeDevices(List devices, String filePath, ICOTAMode mode); + + /* + * 停止升级设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void stopUpgradeDevice(ICDevice device); + + /* + * 停止升级多个设备 + * + * + * @param device 设备 + * @param callBack 回调 + * + * + */ + void stopUpgradeDevices(List devices); + + /* + * 同步当前用户信息 + * + * @param userInfo 用户 + * + */ + void updateUserInfo(ICUserInfo userInfo); + + /* + * 下发用户列表 + * + * @param list 用户列表 + * + */ + void setUserList(List list); + + void onMethodCall(); + + /* + * 设置数据回调代理 + */ + void setDeviceManagerDelegate(ICDeviceManagerDelegate? delegate); + + /* + * 设置扫描回调代理 + */ + void setDeviceScanDelegate(ICScanDeviceDelegate? delegate); + + /* + * 获取日记地址 + */ + void getLogPath(ICCommonCallback? callback); + + /* + * @param weightData 体重信息 + *@param userInfo 用户信息 + *重算体脂率 + */ + void reCalcBodyFatWithWeightData(ICWeightData weightData, ICUserInfo userInfo, + ICFatAlgorithmsSettingCallback callBack); +} diff --git a/lib/model/converter/ICDeviceInfoExtConverter.dart b/lib/model/converter/ICDeviceInfoExtConverter.dart new file mode 100644 index 0000000..fbd3fd2 --- /dev/null +++ b/lib/model/converter/ICDeviceInfoExtConverter.dart @@ -0,0 +1,17 @@ +import 'dart:convert'; + + +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfoExt.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class ICDeviceInfoExtConverter implements JsonConverter { + const ICDeviceInfoExtConverter(); + + @override + ICDeviceInfoExt fromJson(String data) { + return ICDeviceInfoExt.fromJson( json.decode(data)); + } + + @override + String toJson(ICDeviceInfoExt data) => json.encode(data); +} diff --git a/lib/model/converter/ICSkipFreqDataConverter.dart b/lib/model/converter/ICSkipFreqDataConverter.dart new file mode 100644 index 0000000..e22a936 --- /dev/null +++ b/lib/model/converter/ICSkipFreqDataConverter.dart @@ -0,0 +1,18 @@ +import 'dart:convert'; + + + +import 'package:icdevicemanager_flutter/model/data/ICSkipFreqData.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class ICSkipFreqDataConverter implements JsonConverter?, String> { + const ICSkipFreqDataConverter(); + + @override + List? fromJson(String data) { + return List.from(json.decode(data).map((model)=> ICSkipFreqData.fromJson(model))); + } + + @override + String toJson(List? data) => json.encode(data); +} diff --git a/lib/model/converter/ICWeightCenterDataConverter.dart b/lib/model/converter/ICWeightCenterDataConverter.dart new file mode 100644 index 0000000..fd7513c --- /dev/null +++ b/lib/model/converter/ICWeightCenterDataConverter.dart @@ -0,0 +1,22 @@ + + +import 'dart:convert'; +import 'dart:developer'; + + +import 'package:icdevicemanager_flutter/model/data/ICWeightCenterData.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class ICWeightCenterDataConverter implements JsonConverter { + const ICWeightCenterDataConverter(); + + @override + ICWeightCenterData fromJson(String data) { + log("ICWeightCenterDataConverter---=data} $data"); + Map map = json.decode(data); + return ICWeightCenterData.fromJson(map); + } + + @override + String toJson(ICWeightCenterData data) => json.encode(data); +} diff --git a/lib/model/data/ICCoordData.dart b/lib/model/data/ICCoordData.dart new file mode 100644 index 0000000..81bb0a7 --- /dev/null +++ b/lib/model/data/ICCoordData.dart @@ -0,0 +1,19 @@ + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICCoordData.g.dart'; + +@JsonSerializable() +class ICCoordData { + int time = 0; + int x = 0; + int y = 0; + + ICCoordData(); + + + + factory ICCoordData.fromJson(Map json) => _$ICCoordDataFromJson(json); + + Map toJson() => _$ICCoordDataToJson(this); +} diff --git a/lib/model/data/ICCoordData.g.dart b/lib/model/data/ICCoordData.g.dart new file mode 100644 index 0000000..f1de208 --- /dev/null +++ b/lib/model/data/ICCoordData.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICCoordData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICCoordData _$ICCoordDataFromJson(Map json) => ICCoordData() + ..time = json['time'] as int + ..x = json['x'] as int + ..y = json['y'] as int; + +Map _$ICCoordDataToJson(ICCoordData instance) => + { + 'time': instance.time, + 'x': instance.x, + 'y': instance.y, + }; diff --git a/lib/model/data/ICKitchenScaleData.dart b/lib/model/data/ICKitchenScaleData.dart new file mode 100644 index 0000000..ce61921 --- /dev/null +++ b/lib/model/data/ICKitchenScaleData.dart @@ -0,0 +1,147 @@ + + +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + + +part 'ICKitchenScaleData.g.dart'; + +@JsonSerializable() +class ICKitchenScaleData{ + /** + 是否稳定数据, 不稳定的数据只做展示用,请勿保存 + */ + bool isStabilized=false; + + /** + 数据值,单位:mg + */ + int value_mg=0; + + /** + 数据值,单位:g + */ + double value_g=0.0; + + /** + 数据值,单位:ml + */ + double value_ml=0.0; + /** + 数据值,单位:ml milk + */ + double value_ml_milk=0.0; + + /** + 数据值,单位:oz + */ + double value_oz=0.0; + + /** + 数据值,单位:lb:oz中的lb + */ + int value_lb=0; + + /** + 数据值,单位:lb:oz中的oz + */ + double value_lb_oz=0.0; + + /** + 数据值,单位:fl.oz,美制 + */ + double value_fl_oz=0.0; + + /** + 数据值,单位:fl.oz,英制 + */ + double value_fl_oz_uk=0.0; + + /** + 数据值,单位:fl.oz,美制 + */ + double value_fl_oz_milk=0.0; + + /** + 数据值,单位:fl.oz,英制 + */ + double value_fl_oz_milk_uk=0.0; + + /** + 测量时间戳(秒) + */ + int time=0; + + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision=1; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_g = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_ml = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_lboz = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_oz = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_ml_milk = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_floz_us = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_floz_uk = 0; + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_floz_milk_us = 0; + + /** + 小数点位数,如:value_lb=70.12,则precision=2,value_lb=71.5,则precision=1 + */ + int precision_floz_milk_uk = 0; + /** + 设备数据单位类型,0:公制,1:美制,2:英制 + */ + int unitType=0; + + /** + 数字是否负数 + */ + bool? isNegative=false; + + /** + 是否去皮模式 + */ + bool? isTare=false; + + /** + ///本次数据单位 + */ + ICKitchenScaleUnit unit=ICKitchenScaleUnit.ICKitchenScaleUnitG; + + + ICKitchenScaleData(); + + factory ICKitchenScaleData.fromJson(Map json) => _$ICKitchenScaleDataFromJson(json); + + Map toJson() => _$ICKitchenScaleDataToJson(this); + + @override + String toString() { + return 'ICKitchenScaleData{isStabilized: $isStabilized, value_mg: $value_mg, value_g: $value_g, value_ml: $value_ml, value_ml_milk: $value_ml_milk, value_oz: $value_oz, value_lb: $value_lb, value_lb_oz: $value_lb_oz, value_fl_oz: $value_fl_oz, value_fl_oz_uk: $value_fl_oz_uk, value_fl_oz_milk: $value_fl_oz_milk, value_fl_oz_milk_uk: $value_fl_oz_milk_uk, time: $time, precision: $precision, precision_g: $precision_g, precision_ml: $precision_ml, precision_lboz: $precision_lboz, precision_oz: $precision_oz, precision_ml_milk: $precision_ml_milk, precision_floz_us: $precision_floz_us, precision_floz_uk: $precision_floz_uk, precision_floz_milk_us: $precision_floz_milk_us, precision_floz_milk_uk: $precision_floz_milk_uk, unitType: $unitType, isNegative: $isNegative, isTare: $isTare, unit: $unit}'; + } +} \ No newline at end of file diff --git a/lib/model/data/ICKitchenScaleData.g.dart b/lib/model/data/ICKitchenScaleData.g.dart new file mode 100644 index 0000000..688aa5c --- /dev/null +++ b/lib/model/data/ICKitchenScaleData.g.dart @@ -0,0 +1,79 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICKitchenScaleData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICKitchenScaleData _$ICKitchenScaleDataFromJson(Map json) => + ICKitchenScaleData() + ..isStabilized = json['isStabilized'] as bool + ..value_mg = json['value_mg'] as int + ..value_g = (json['value_g'] as num).toDouble() + ..value_ml = (json['value_ml'] as num).toDouble() + ..value_ml_milk = (json['value_ml_milk'] as num).toDouble() + ..value_oz = (json['value_oz'] as num).toDouble() + ..value_lb = json['value_lb'] as int + ..value_lb_oz = (json['value_lb_oz'] as num).toDouble() + ..value_fl_oz = (json['value_fl_oz'] as num).toDouble() + ..value_fl_oz_uk = (json['value_fl_oz_uk'] as num).toDouble() + ..value_fl_oz_milk = (json['value_fl_oz_milk'] as num).toDouble() + ..value_fl_oz_milk_uk = (json['value_fl_oz_milk_uk'] as num).toDouble() + ..time = json['time'] as int + ..precision = json['precision'] as int + ..precision_g = json['precision_g'] as int + ..precision_ml = json['precision_ml'] as int + ..precision_lboz = json['precision_lboz'] as int + ..precision_oz = json['precision_oz'] as int + ..precision_ml_milk = json['precision_ml_milk'] as int + ..precision_floz_us = json['precision_floz_us'] as int + ..precision_floz_uk = json['precision_floz_uk'] as int + ..precision_floz_milk_us = json['precision_floz_milk_us'] as int + ..precision_floz_milk_uk = json['precision_floz_milk_uk'] as int + ..unitType = json['unitType'] as int + ..isNegative = json['isNegative'] as bool? + ..isTare = json['isTare'] as bool? + ..unit = $enumDecode(_$ICKitchenScaleUnitEnumMap, json['unit']); + +Map _$ICKitchenScaleDataToJson(ICKitchenScaleData instance) => + { + 'isStabilized': instance.isStabilized, + 'value_mg': instance.value_mg, + 'value_g': instance.value_g, + 'value_ml': instance.value_ml, + 'value_ml_milk': instance.value_ml_milk, + 'value_oz': instance.value_oz, + 'value_lb': instance.value_lb, + 'value_lb_oz': instance.value_lb_oz, + 'value_fl_oz': instance.value_fl_oz, + 'value_fl_oz_uk': instance.value_fl_oz_uk, + 'value_fl_oz_milk': instance.value_fl_oz_milk, + 'value_fl_oz_milk_uk': instance.value_fl_oz_milk_uk, + 'time': instance.time, + 'precision': instance.precision, + 'precision_g': instance.precision_g, + 'precision_ml': instance.precision_ml, + 'precision_lboz': instance.precision_lboz, + 'precision_oz': instance.precision_oz, + 'precision_ml_milk': instance.precision_ml_milk, + 'precision_floz_us': instance.precision_floz_us, + 'precision_floz_uk': instance.precision_floz_uk, + 'precision_floz_milk_us': instance.precision_floz_milk_us, + 'precision_floz_milk_uk': instance.precision_floz_milk_uk, + 'unitType': instance.unitType, + 'isNegative': instance.isNegative, + 'isTare': instance.isTare, + 'unit': _$ICKitchenScaleUnitEnumMap[instance.unit]!, + }; + +const _$ICKitchenScaleUnitEnumMap = { + ICKitchenScaleUnit.ICKitchenScaleUnitG: 'ICKitchenScaleUnitG', + ICKitchenScaleUnit.ICKitchenScaleUnitMl: 'ICKitchenScaleUnitMl', + ICKitchenScaleUnit.ICKitchenScaleUnitLb: 'ICKitchenScaleUnitLb', + ICKitchenScaleUnit.ICKitchenScaleUnitOz: 'ICKitchenScaleUnitOz', + ICKitchenScaleUnit.ICKitchenScaleUnitMg: 'ICKitchenScaleUnitMg', + ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk: 'ICKitchenScaleUnitMlMilk', + ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater: 'ICKitchenScaleUnitFlOzWater', + ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk: 'ICKitchenScaleUnitFlOzMilk', +}; diff --git a/lib/model/data/ICRulerData.dart b/lib/model/data/ICRulerData.dart new file mode 100644 index 0000000..beabdb8 --- /dev/null +++ b/lib/model/data/ICRulerData.dart @@ -0,0 +1,82 @@ + +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + + +part 'ICRulerData.g.dart'; + +@JsonSerializable() +class ICRulerData{ + /** + 是否稳定数据 + @notice 如果数据不稳定,则只有distance有效,不稳定的数据只做展示用,请勿保存 + */ + bool isStabilized=false; + + /** + 测量长度(0.1mm) + */ + int distance=0; + + /** + 距离inch + */ + double distance_in=0.0; + + /** + 距离ft + */ + int distance_ft=0; + /** + 距离ft'in + */ + double distance_ft_in=0.0; + + /** + 距离cm + */ + double distance_cm=0.0; + + /** + inch距离小数点位数,如:distance_in=70.12,则precision_in=2,distance_in=71.5,则precision_in=1 + */ + int precision_in=1; + + /** + cm距离小数点位数,如:distance_cm=70.12,则precision_cm=2,distance_cm=71.5,则precision_cm=1 + */ + int precision_cm=1; + + /** + * + 本次测量的单位 + */ + ICRulerUnit unit=ICRulerUnit.ICRulerUnitCM; + + /** + 本次测量的单位 + */ + ICRulerMeasureMode mode=ICRulerMeasureMode.ICRulerMeasureModeLength; + + + /** + 时间戳 + */ + int time=0; + + /** + 身体部位类型 + */ + ICRulerBodyPartsType partsType=ICRulerBodyPartsType.ICRulerPartsTypeCalf; + + ICRulerData(); + + factory ICRulerData.fromJson(Map json) => _$ICRulerDataFromJson(json); + + Map toJson() => _$ICRulerDataToJson(this); + + @override + String toString() { + return 'ICRulerData{isStabilized: $isStabilized, distance: $distance, distance_in: $distance_in, distance_ft: $distance_ft, distance_ft_in: $distance_ft_in, distance_cm: $distance_cm, precision_in: $precision_in, precision_cm: $precision_cm, unit: $unit, mode: $mode, time: $time, partsType: $partsType}'; + } +} \ No newline at end of file diff --git a/lib/model/data/ICRulerData.g.dart b/lib/model/data/ICRulerData.g.dart new file mode 100644 index 0000000..fab3f04 --- /dev/null +++ b/lib/model/data/ICRulerData.g.dart @@ -0,0 +1,58 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICRulerData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICRulerData _$ICRulerDataFromJson(Map json) => ICRulerData() + ..isStabilized = json['isStabilized'] as bool + ..distance = json['distance'] as int + ..distance_in = (json['distance_in'] as num).toDouble() + ..distance_ft = json['distance_ft'] as int + ..distance_ft_in = (json['distance_ft_in'] as num).toDouble() + ..distance_cm = (json['distance_cm'] as num).toDouble() + ..precision_in = json['precision_in'] as int + ..precision_cm = json['precision_cm'] as int + ..unit = $enumDecode(_$ICRulerUnitEnumMap, json['unit']) + ..mode = $enumDecode(_$ICRulerMeasureModeEnumMap, json['mode']) + ..time = json['time'] as int + ..partsType = $enumDecode(_$ICRulerBodyPartsTypeEnumMap, json['partsType']); + +Map _$ICRulerDataToJson(ICRulerData instance) => + { + 'isStabilized': instance.isStabilized, + 'distance': instance.distance, + 'distance_in': instance.distance_in, + 'distance_ft': instance.distance_ft, + 'distance_ft_in': instance.distance_ft_in, + 'distance_cm': instance.distance_cm, + 'precision_in': instance.precision_in, + 'precision_cm': instance.precision_cm, + 'unit': _$ICRulerUnitEnumMap[instance.unit]!, + 'mode': _$ICRulerMeasureModeEnumMap[instance.mode]!, + 'time': instance.time, + 'partsType': _$ICRulerBodyPartsTypeEnumMap[instance.partsType]!, + }; + +const _$ICRulerUnitEnumMap = { + ICRulerUnit.ICRulerUnitCM: 'ICRulerUnitCM', + ICRulerUnit.ICRulerUnitInch: 'ICRulerUnitInch', + ICRulerUnit.ICRulerUnitFtInch: 'ICRulerUnitFtInch', +}; + +const _$ICRulerMeasureModeEnumMap = { + ICRulerMeasureMode.ICRulerMeasureModeLength: 'ICRulerMeasureModeLength', + ICRulerMeasureMode.ICRulerMeasureModeGirth: 'ICRulerMeasureModeGirth', +}; + +const _$ICRulerBodyPartsTypeEnumMap = { + ICRulerBodyPartsType.ICRulerPartsTypeShoulder: 'ICRulerPartsTypeShoulder', + ICRulerBodyPartsType.ICRulerPartsTypeBicep: 'ICRulerPartsTypeBicep', + ICRulerBodyPartsType.ICRulerPartsTypeChest: 'ICRulerPartsTypeChest', + ICRulerBodyPartsType.ICRulerPartsTypeWaist: 'ICRulerPartsTypeWaist', + ICRulerBodyPartsType.ICRulerPartsTypeHip: 'ICRulerPartsTypeHip', + ICRulerBodyPartsType.ICRulerPartsTypeThigh: 'ICRulerPartsTypeThigh', + ICRulerBodyPartsType.ICRulerPartsTypeCalf: 'ICRulerPartsTypeCalf', +}; diff --git a/lib/model/data/ICSkipData.dart b/lib/model/data/ICSkipData.dart new file mode 100644 index 0000000..5494ace --- /dev/null +++ b/lib/model/data/ICSkipData.dart @@ -0,0 +1,114 @@ + + +import 'package:icdevicemanager_flutter/model/converter/ICSkipFreqDataConverter.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipFreqData.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import '../other/ICConstant.dart'; + + + + +part 'ICSkipData.g.dart'; + +@JsonSerializable() +class ICSkipData{ + /** + 是否稳定 + */ + bool isStabilized=false; + + /** + 节点ID + */ + int nodeId=0; + /** + 节点电量 + */ + int battery=0; + /** + 节点信息 + */ + int nodeInfo=0; + + /** + * 测量时间,单位:秒 + */ + int time = 0; + + /** + * 跳绳模式 + */ + ICSkipMode mode = ICSkipMode.ICSkipModeFreedom; + + /** + * 设置的参数 + */ + int setting = 0; + + /** + * 跳绳使用的时间 + */ + int elapsed_time = 0; + + /** + * 跳绳实际使用的时间,不是所有都支持 + */ + int actual_time = 0; + + /** + * 跳的次数 + */ + int skip_count = 0; + + /** + * 平均频次 + */ + int avg_freq = 0; + + /** + * 最快频次 + */ + int fastest_freq = 0; + + + /** + * 绊绳总数 + */ + int freq_count = 0; + + /** + * 最多连跳 + */ + int most_jump = 0; + + + + /** + * 热量消耗 + */ + double calories_burned = 0; + + /** + * 燃脂效率 + */ + double fat_burn_efficiency = 0; + + + /** + * 跳绳频次数据 + */ + @ICSkipFreqDataConverter() + List? freqs = []; + + ICSkipData(); + + factory ICSkipData.fromJson(Map json) => _$ICSkipDataFromJson(json); + + Map toJson() => _$ICSkipDataToJson(this); + + @override + String toString() { + return 'ICSkipData{isStabilized: $isStabilized, nodeId: $nodeId, battery: $battery, nodeInfo: $nodeInfo, time: $time, mode: $mode, setting: $setting, elapsed_time: $elapsed_time, actual_time: $actual_time, skip_count: $skip_count, avg_freq: $avg_freq, fastest_freq: $fastest_freq, freq_count: $freq_count, most_jump: $most_jump, calories_burned: $calories_burned, fat_burn_efficiency: $fat_burn_efficiency, freqs: $freqs}'; + } +} \ No newline at end of file diff --git a/lib/model/data/ICSkipData.g.dart b/lib/model/data/ICSkipData.g.dart new file mode 100644 index 0000000..501e32e --- /dev/null +++ b/lib/model/data/ICSkipData.g.dart @@ -0,0 +1,60 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICSkipData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICSkipData _$ICSkipDataFromJson(Map json) => ICSkipData() + ..isStabilized = json['isStabilized'] as bool + ..nodeId = json['nodeId'] as int + ..battery = json['battery'] as int + ..nodeInfo = json['nodeInfo'] as int + ..time = json['time'] as int + ..mode = $enumDecode(_$ICSkipModeEnumMap, json['mode']) + ..setting = json['setting'] as int + ..elapsed_time = json['elapsed_time'] as int + ..actual_time = json['actual_time'] as int + ..skip_count = json['skip_count'] as int + ..avg_freq = json['avg_freq'] as int + ..fastest_freq = json['fastest_freq'] as int + ..freq_count = json['freq_count'] as int + ..most_jump = json['most_jump'] as int + ..calories_burned = (json['calories_burned'] as num).toDouble() + ..fat_burn_efficiency = (json['fat_burn_efficiency'] as num).toDouble() + ..freqs = _$JsonConverterFromJson?>( + json['freqs'], const ICSkipFreqDataConverter().fromJson); + +Map _$ICSkipDataToJson(ICSkipData instance) => + { + 'isStabilized': instance.isStabilized, + 'nodeId': instance.nodeId, + 'battery': instance.battery, + 'nodeInfo': instance.nodeInfo, + 'time': instance.time, + 'mode': _$ICSkipModeEnumMap[instance.mode]!, + 'setting': instance.setting, + 'elapsed_time': instance.elapsed_time, + 'actual_time': instance.actual_time, + 'skip_count': instance.skip_count, + 'avg_freq': instance.avg_freq, + 'fastest_freq': instance.fastest_freq, + 'freq_count': instance.freq_count, + 'most_jump': instance.most_jump, + 'calories_burned': instance.calories_burned, + 'fat_burn_efficiency': instance.fat_burn_efficiency, + 'freqs': const ICSkipFreqDataConverter().toJson(instance.freqs), + }; + +const _$ICSkipModeEnumMap = { + ICSkipMode.ICSkipModeFreedom: 'ICSkipModeFreedom', + ICSkipMode.ICSkipModeTiming: 'ICSkipModeTiming', + ICSkipMode.ICSkipModeCount: 'ICSkipModeCount', +}; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); diff --git a/lib/model/data/ICSkipFreqData.dart b/lib/model/data/ICSkipFreqData.dart new file mode 100644 index 0000000..bb577f5 --- /dev/null +++ b/lib/model/data/ICSkipFreqData.dart @@ -0,0 +1,23 @@ + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICSkipFreqData.g.dart'; + +@JsonSerializable() +class ICSkipFreqData{ + /** + * 持续时间 + */ + int duration = 0; + + /** + * 次数 + */ + int skip_count = 0; + + ICSkipFreqData(); + + factory ICSkipFreqData.fromJson(Map json) => _$ICSkipFreqDataFromJson(json); + + Map toJson() => _$ICSkipFreqDataToJson(this); +} \ No newline at end of file diff --git a/lib/model/data/ICSkipFreqData.g.dart b/lib/model/data/ICSkipFreqData.g.dart new file mode 100644 index 0000000..797608a --- /dev/null +++ b/lib/model/data/ICSkipFreqData.g.dart @@ -0,0 +1,18 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICSkipFreqData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICSkipFreqData _$ICSkipFreqDataFromJson(Map json) => + ICSkipFreqData() + ..duration = json['duration'] as int + ..skip_count = json['skip_count'] as int; + +Map _$ICSkipFreqDataToJson(ICSkipFreqData instance) => + { + 'duration': instance.duration, + 'skip_count': instance.skip_count, + }; diff --git a/lib/model/data/ICSkipLightSettingData.dart b/lib/model/data/ICSkipLightSettingData.dart new file mode 100644 index 0000000..816c4c2 --- /dev/null +++ b/lib/model/data/ICSkipLightSettingData.dart @@ -0,0 +1,18 @@ + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICSkipLightSettingData.g.dart'; + +@JsonSerializable() +class ICSkipLightSettingData{ + int r=0; + int g=0; + int b=0; + int rpm=0; + + ICSkipLightSettingData(); + + factory ICSkipLightSettingData.fromJson(Map json) => _$ICSkipLightSettingDataFromJson(json); + + Map toJson() => _$ICSkipLightSettingDataToJson(this); +} \ No newline at end of file diff --git a/lib/model/data/ICSkipLightSettingData.g.dart b/lib/model/data/ICSkipLightSettingData.g.dart new file mode 100644 index 0000000..f0da28b --- /dev/null +++ b/lib/model/data/ICSkipLightSettingData.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICSkipLightSettingData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICSkipLightSettingData _$ICSkipLightSettingDataFromJson( + Map json) => + ICSkipLightSettingData() + ..r = json['r'] as int + ..g = json['g'] as int + ..b = json['b'] as int + ..rpm = json['rpm'] as int; + +Map _$ICSkipLightSettingDataToJson( + ICSkipLightSettingData instance) => + { + 'r': instance.r, + 'g': instance.g, + 'b': instance.b, + 'rpm': instance.rpm, + }; diff --git a/lib/model/data/ICSkipSoundSettingData.dart b/lib/model/data/ICSkipSoundSettingData.dart new file mode 100644 index 0000000..9cd7d09 --- /dev/null +++ b/lib/model/data/ICSkipSoundSettingData.dart @@ -0,0 +1,55 @@ + +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'ICSkipSoundSettingData.g.dart'; + +@JsonSerializable() +class ICSkipSoundSettingData { + /* + 是否开启语音开关 + */ + bool soundOn = false; + + /* + 语音类型 + */ + ICSkipSoundType soundType = ICSkipSoundType.ICSkipSoundTypeFemale; + + /* + 声音大小 + */ + int soundVolume = 0; + + /* + 满分开关 + */ + bool fullScoreOn = false; + + /* + 满分速率 + */ + int fullScoreBPM = 0; + + /* + 语音间隔模式 + */ + ICSkipSoundMode soundMode = ICSkipSoundMode.ICSkipSoundModeCount; + + /* + 模式参数 + */ + int modeParam = 0; + + /* + 是否自动停止播放,true:APP下发开始后,跳绳不会播放语音 ,false:跳绳和APP都会播放语音 + */ + bool isAutoStop = false; + + ICSkipSoundSettingData(); + + + factory ICSkipSoundSettingData.fromJson(Map json) => _$ICSkipSoundSettingDataFromJson(json); + + Map toJson() => _$ICSkipSoundSettingDataToJson(this); +} diff --git a/lib/model/data/ICSkipSoundSettingData.g.dart b/lib/model/data/ICSkipSoundSettingData.g.dart new file mode 100644 index 0000000..7bd0eac --- /dev/null +++ b/lib/model/data/ICSkipSoundSettingData.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICSkipSoundSettingData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICSkipSoundSettingData _$ICSkipSoundSettingDataFromJson( + Map json) => + ICSkipSoundSettingData() + ..soundOn = json['soundOn'] as bool + ..soundType = $enumDecode(_$ICSkipSoundTypeEnumMap, json['soundType']) + ..soundVolume = json['soundVolume'] as int + ..fullScoreOn = json['fullScoreOn'] as bool + ..fullScoreBPM = json['fullScoreBPM'] as int + ..soundMode = $enumDecode(_$ICSkipSoundModeEnumMap, json['soundMode']) + ..modeParam = json['modeParam'] as int + ..isAutoStop = json['isAutoStop'] as bool; + +Map _$ICSkipSoundSettingDataToJson( + ICSkipSoundSettingData instance) => + { + 'soundOn': instance.soundOn, + 'soundType': _$ICSkipSoundTypeEnumMap[instance.soundType]!, + 'soundVolume': instance.soundVolume, + 'fullScoreOn': instance.fullScoreOn, + 'fullScoreBPM': instance.fullScoreBPM, + 'soundMode': _$ICSkipSoundModeEnumMap[instance.soundMode]!, + 'modeParam': instance.modeParam, + 'isAutoStop': instance.isAutoStop, + }; + +const _$ICSkipSoundTypeEnumMap = { + ICSkipSoundType.ICSkipSoundTypeNone: 'ICSkipSoundTypeNone', + ICSkipSoundType.ICSkipSoundTypeFemale: 'ICSkipSoundTypeFemale', + ICSkipSoundType.ICSkipSoundTypeMale: 'ICSkipSoundTypeMale', +}; + +const _$ICSkipSoundModeEnumMap = { + ICSkipSoundMode.ICSkipSoundModeNone: 'ICSkipSoundModeNone', + ICSkipSoundMode.ICSkipSoundModeTime: 'ICSkipSoundModeTime', + ICSkipSoundMode.ICSkipSoundModeCount: 'ICSkipSoundModeCount', +}; diff --git a/lib/model/data/ICWeightCenterData.dart b/lib/model/data/ICWeightCenterData.dart new file mode 100644 index 0000000..946b867 --- /dev/null +++ b/lib/model/data/ICWeightCenterData.dart @@ -0,0 +1,112 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'ICWeightCenterData.g.dart'; + +@JsonSerializable() +class ICWeightCenterData{ + + /** + 数据是否稳定, 不稳定的数据只做展示用,请勿保存 + */ + bool isStabilized=false; + + /** + 测量时间戳(秒) + */ + int time=0; + + /** + kg体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_kg=1 + */ + int precision_kg=1; + + /** + lb体重小数点位数,如:weight=70.12,则precision=2,weight=71.5,则precision_lb=1 + */ + int precision_lb=1; + + /** + st:lb体重小数点位数 + */ + int precision_st_lb=1; + + /** + kg分度值 + */ + int kg_scale_division=0; + + /** + lb分度值 + */ + int lb_scale_division=0; + + /** + 左边体重占比(%) + */ + double leftPercent=0.0; + + /** + 右边体重占比(%) + */ + double rightPercent=0.0; + + /** + 左边体重(g) + */ + int left_weight_g=0; + + /** + 右边体重(g) + */ + int right_weight_g=0; + /** + 左边体重(kg) + */ + double left_weight_kg=0.0; + + /** + 右边体重(kg) + */ + double right_weight_kg=0.0; + + /** + 左边体重(lb) + */ + double left_weight_lb=0.0; + + /** + 右边体重(lb) + */ + double right_weight_lb=0.0; + + /** + 左边体重(st:lb) + */ + int left_weight_st=0; + + /** + 右边体重(st:lb) + */ + int right_weight_st=0; + + /** + 左边体重(st:lb) + */ + double left_weight_st_lb=0.0; + + /** + 右边体重(st:lb) + */ + double right_weight_st_lb=0.0; + + ICWeightCenterData(); + + factory ICWeightCenterData.fromJson(Map json) => _$ICWeightCenterDataFromJson(json); + + Map toJson() => _$ICWeightCenterDataToJson(this); + + @override + String toString() { + return 'ICWeightCenterData{isStabilized: $isStabilized, time: $time, precision_kg: $precision_kg, precision_lb: $precision_lb, precision_st_lb: $precision_st_lb, kg_scale_division: $kg_scale_division, lb_scale_division: $lb_scale_division, leftPercent: $leftPercent, rightPercent: $rightPercent, left_weight_g: $left_weight_g, right_weight_g: $right_weight_g, left_weight_kg: $left_weight_kg, right_weight_kg: $right_weight_kg, left_weight_lb: $left_weight_lb, right_weight_lb: $right_weight_lb, left_weight_st: $left_weight_st, right_weight_st: $right_weight_st, left_weight_st_lb: $left_weight_st_lb, right_weight_st_lb: $right_weight_st_lb}'; + } +} \ No newline at end of file diff --git a/lib/model/data/ICWeightCenterData.g.dart b/lib/model/data/ICWeightCenterData.g.dart new file mode 100644 index 0000000..b5bbe93 --- /dev/null +++ b/lib/model/data/ICWeightCenterData.g.dart @@ -0,0 +1,52 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICWeightCenterData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICWeightCenterData _$ICWeightCenterDataFromJson(Map json) => + ICWeightCenterData() + ..isStabilized = json['isStabilized'] as bool + ..time = json['time'] as int + ..precision_kg = json['precision_kg'] as int + ..precision_lb = json['precision_lb'] as int + ..precision_st_lb = json['precision_st_lb'] as int + ..kg_scale_division = json['kg_scale_division'] as int + ..lb_scale_division = json['lb_scale_division'] as int + ..leftPercent = (json['leftPercent'] as num).toDouble() + ..rightPercent = (json['rightPercent'] as num).toDouble() + ..left_weight_g = json['left_weight_g'] as int + ..right_weight_g = json['right_weight_g'] as int + ..left_weight_kg = (json['left_weight_kg'] as num).toDouble() + ..right_weight_kg = (json['right_weight_kg'] as num).toDouble() + ..left_weight_lb = (json['left_weight_lb'] as num).toDouble() + ..right_weight_lb = (json['right_weight_lb'] as num).toDouble() + ..left_weight_st = json['left_weight_st'] as int + ..right_weight_st = json['right_weight_st'] as int + ..left_weight_st_lb = (json['left_weight_st_lb'] as num).toDouble() + ..right_weight_st_lb = (json['right_weight_st_lb'] as num).toDouble(); + +Map _$ICWeightCenterDataToJson(ICWeightCenterData instance) => + { + 'isStabilized': instance.isStabilized, + 'time': instance.time, + 'precision_kg': instance.precision_kg, + 'precision_lb': instance.precision_lb, + 'precision_st_lb': instance.precision_st_lb, + 'kg_scale_division': instance.kg_scale_division, + 'lb_scale_division': instance.lb_scale_division, + 'leftPercent': instance.leftPercent, + 'rightPercent': instance.rightPercent, + 'left_weight_g': instance.left_weight_g, + 'right_weight_g': instance.right_weight_g, + 'left_weight_kg': instance.left_weight_kg, + 'right_weight_kg': instance.right_weight_kg, + 'left_weight_lb': instance.left_weight_lb, + 'right_weight_lb': instance.right_weight_lb, + 'left_weight_st': instance.left_weight_st, + 'right_weight_st': instance.right_weight_st, + 'left_weight_st_lb': instance.left_weight_st_lb, + 'right_weight_st_lb': instance.right_weight_st_lb, + }; diff --git a/lib/model/data/ICWeightData.dart b/lib/model/data/ICWeightData.dart new file mode 100644 index 0000000..d6fd2b7 --- /dev/null +++ b/lib/model/data/ICWeightData.dart @@ -0,0 +1,299 @@ +import 'package:icdevicemanager_flutter/model/converter/ICWeightCenterDataConverter.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightExtData.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import '../other/ICConstant.dart'; + +part 'ICWeightData.g.dart'; + +@JsonSerializable() +class ICWeightData { + /** + 用户ID,默认:0 + */ + int? userId = 0; + + /** + 是否稳定数据,如果数据不稳定,则只有weight有效,不稳定的数据只做展示用,请勿保存 + */ + bool isStabilized = false; + + /** + 体重(g) + */ + int weight_g = 0; + + /** + 体重(kg) + */ + double weight_kg = 0.0; + + /** + 体重(磅) + */ + double weight_lb = 0.0; + + /** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ + int weight_st = 0; + + /** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ + double weight_st_lb = 0.0; + + /** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ + int precision_kg = 1; + + /** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ + int precision_lb = 1; + + /** + st:lb体重小数点位数 + */ + int precision_st_lb = 1; + + /** + kg分度值 + */ + int kg_scale_division = 0; + + /** + lb分度值 + */ + int lb_scale_division = 0; + + /** + 温度 + */ + double temperature = 0.0; + + /** + 支持心率测量 + */ + bool isSupportHR = false; + + /** + 心率值 + */ + int hr = 0; + + /** + 时间戳 + */ + int time = 0; + + /** + 身体质量指数BMI(精度:0.1) + */ + double bmi = 0.0; + + /** + 体脂率(百分比, 精度:0.1) + */ + double bodyFatPercent = 0.0; + + /** + 皮下脂肪率(百分比, 精度:0.1) + */ + double subcutaneousFatPercent = 0.0; + + /** + 内脏脂肪指数(精度:0.1) + */ + double visceralFat = 0.0; + + /** + 肌肉率(百分比, 精度:0.1) + */ + double musclePercent = 0.0; + + /** + 基础代谢率(单位:kcal) + */ + int bmr = 0; + + /** + 骨重量(单位:kg,精度:0.1) + */ + double boneMass = 0.0; + + /** + 水含量(百分比,精度:0.1) + */ + double moisturePercent = 0.0; + + /** + 身体年龄 + */ + double physicalAge = 0.0; + + /** + 蛋白率(百分比,精度:0.1) + */ + double proteinPercent = 0.0; + + /** + 骨骼肌率(百分比,精度:0.1) + */ + double smPercent = 0.0; + + /** + 电极数,4电极或者8电极 + */ + int electrode = 4; + + /** + 身体评分 + */ + double bodyScore = 0.0; + + /** + 身体类型 + */ + int bodyType = 0; + + /** + 目标体重 + */ + double targetWeight = 0.0; + + /** + 脂肪量控制 + */ + double bfmControl = 0.0; + + /** + 去脂体重控制 + */ + double ffmControl = 0.0; + + /** + 体重控制 + */ + double weightControl = 0.0; + + /** + 标准体重 + */ + double weightStandard = 0.0; + + /** + 标准脂肪量 + */ + double bfmStandard = 0.0; + + /** + 标准BMI + */ + double bmiStandard = 0.0; + + /** + 标准骨骼肌量 + */ + double smmStandard = 0.0; + + /** + 标准去脂体重 + */ + double ffmStandard = 0.0; + + double bfpStandard = 0.0; // 标准脂肪率 + int bmrStandard = 0; // 标准BMR + + double bmiMax = 0.0; + double bmiMin = 0.0; + double bfmMax = 0.0; + double bfmMin = 0.0; + double bfpMax = 0.0; + double bfpMin = 0.0; + double weightMax = 0.0; + double weightMin = 0.0; + double smmMax = 0.0; + double smmMin = 0.0; + double boneMax = 0.0; + double boneMin = 0.0; + int bmrMax = 0; + int bmrMin = 0; + double waterMassMax = 0.0; + double waterMassMin = 0.0; + double proteinMassMax = 0.0; + double proteinMassMin = 0.0; + double muscleMassMax = 0.0; + double muscleMassMin = 0.0; + + /** + 骨骼肌质量指数 + */ + double smi = 0.0; + + /** + 肥胖程度 + */ + int obesityDegree = 0; + + int state = 0; + + /** + 全身阻抗(8电极)或全身阻抗(4电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp = 0.0; + + /** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp2 = 0.0; + + /** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp3 = 0.0; + + /** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp4 = 0.0; + + /** + 右腳阻抗(8电极)(单位:欧姆ohm),如:阻抗等于0,则代表测量不到阻抗 + */ + double imp5 = 0.0; + + /** + 体重扩展数据(8电极的部分数据在这里面) + */ + @ICWeightCenterDataConverter() + ICWeightExtData? extData; + + /** + 数据计算方式(0:sdk,1:设备计算,2:app计算) + */ + int data_calc_type = 0; + + /** + 本次体脂数据计算的算法类型 + */ + ICBFAType? bfa_type = ICBFAType.ICBFATypeUnknown; + + int impendenceType = 0; + + int impendenceProperty = 0; + + List? impendences; + + ICWeightData(); + + factory ICWeightData.fromJson(Map json) => + _$ICWeightDataFromJson(json); + Map toJson() => _$ICWeightDataToJson(this); + + @override + String toString() { + return 'ICWeightData{userId: $userId, isStabilized: $isStabilized, weight_g: $weight_g, weight_kg: $weight_kg, weight_lb: $weight_lb, weight_st: $weight_st, weight_st_lb: $weight_st_lb, precision_kg: $precision_kg, precision_lb: $precision_lb, precision_st_lb: $precision_st_lb, kg_scale_division: $kg_scale_division, lb_scale_division: $lb_scale_division, temperature: $temperature, isSupportHR: $isSupportHR, hr: $hr, time: $time, bmi: $bmi, bodyFatPercent: $bodyFatPercent, subcutaneousFatPercent: $subcutaneousFatPercent, visceralFat: $visceralFat, musclePercent: $musclePercent, bmr: $bmr, boneMass: $boneMass, moisturePercent: $moisturePercent, physicalAge: $physicalAge, proteinPercent: $proteinPercent, smPercent: $smPercent, electrode: $electrode, bodyScore: $bodyScore, bodyType: $bodyType, targetWeight: $targetWeight, bfmControl: $bfmControl, ffmControl: $ffmControl, weightControl: $weightControl, weightStandard: $weightStandard, bfmStandard: $bfmStandard, bmiStandard: $bmiStandard, smmStandard: $smmStandard, ffmStandard: $ffmStandard, bfpStandard: $bfpStandard, bmrStandard: $bmrStandard, bmiMax: $bmiMax, bmiMin: $bmiMin, bfmMax: $bfmMax, bfmMin: $bfmMin, bfpMax: $bfpMax, bfpMin: $bfpMin, weightMax: $weightMax, weightMin: $weightMin, smmMax: $smmMax, smmMin: $smmMin, boneMax: $boneMax, boneMin: $boneMin, bmrMax: $bmrMax, bmrMin: $bmrMin, waterMassMax: $waterMassMax, waterMassMin: $waterMassMin, proteinMassMax: $proteinMassMax, proteinMassMin: $proteinMassMin, muscleMassMax: $muscleMassMax, muscleMassMin: $muscleMassMin, smi: $smi, obesityDegree: $obesityDegree, state: $state, imp: $imp, imp2: $imp2, imp3: $imp3, imp4: $imp4, imp5: $imp5, extData: $extData, data_calc_type: $data_calc_type, bfa_type: $bfa_type, impendenceType: $impendenceType, impendenceProperty: $impendenceProperty, impendences: $impendences}'; + } +} diff --git a/lib/model/data/ICWeightData.g.dart b/lib/model/data/ICWeightData.g.dart new file mode 100644 index 0000000..a32747d --- /dev/null +++ b/lib/model/data/ICWeightData.g.dart @@ -0,0 +1,200 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICWeightData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICWeightData _$ICWeightDataFromJson(Map json) => ICWeightData() + ..userId = json['userId'] as int? + ..isStabilized = json['isStabilized'] as bool + ..weight_g = json['weight_g'] as int + ..weight_kg = (json['weight_kg'] as num).toDouble() + ..weight_lb = (json['weight_lb'] as num).toDouble() + ..weight_st = json['weight_st'] as int + ..weight_st_lb = (json['weight_st_lb'] as num).toDouble() + ..precision_kg = json['precision_kg'] as int + ..precision_lb = json['precision_lb'] as int + ..precision_st_lb = json['precision_st_lb'] as int + ..kg_scale_division = json['kg_scale_division'] as int + ..lb_scale_division = json['lb_scale_division'] as int + ..temperature = (json['temperature'] as num).toDouble() + ..isSupportHR = json['isSupportHR'] as bool + ..hr = json['hr'] as int + ..time = json['time'] as int + ..bmi = (json['bmi'] as num).toDouble() + ..bodyFatPercent = (json['bodyFatPercent'] as num).toDouble() + ..subcutaneousFatPercent = (json['subcutaneousFatPercent'] as num).toDouble() + ..visceralFat = (json['visceralFat'] as num).toDouble() + ..musclePercent = (json['musclePercent'] as num).toDouble() + ..bmr = json['bmr'] as int + ..boneMass = (json['boneMass'] as num).toDouble() + ..moisturePercent = (json['moisturePercent'] as num).toDouble() + ..physicalAge = (json['physicalAge'] as num).toDouble() + ..proteinPercent = (json['proteinPercent'] as num).toDouble() + ..smPercent = (json['smPercent'] as num).toDouble() + ..electrode = json['electrode'] as int + ..bodyScore = (json['bodyScore'] as num).toDouble() + ..bodyType = json['bodyType'] as int + ..targetWeight = (json['targetWeight'] as num).toDouble() + ..bfmControl = (json['bfmControl'] as num).toDouble() + ..ffmControl = (json['ffmControl'] as num).toDouble() + ..weightControl = (json['weightControl'] as num).toDouble() + ..weightStandard = (json['weightStandard'] as num).toDouble() + ..bfmStandard = (json['bfmStandard'] as num).toDouble() + ..bmiStandard = (json['bmiStandard'] as num).toDouble() + ..smmStandard = (json['smmStandard'] as num).toDouble() + ..ffmStandard = (json['ffmStandard'] as num).toDouble() + ..bfpStandard = (json['bfpStandard'] as num).toDouble() + ..bmrStandard = json['bmrStandard'] as int + ..bmiMax = (json['bmiMax'] as num).toDouble() + ..bmiMin = (json['bmiMin'] as num).toDouble() + ..bfmMax = (json['bfmMax'] as num).toDouble() + ..bfmMin = (json['bfmMin'] as num).toDouble() + ..bfpMax = (json['bfpMax'] as num).toDouble() + ..bfpMin = (json['bfpMin'] as num).toDouble() + ..weightMax = (json['weightMax'] as num).toDouble() + ..weightMin = (json['weightMin'] as num).toDouble() + ..smmMax = (json['smmMax'] as num).toDouble() + ..smmMin = (json['smmMin'] as num).toDouble() + ..boneMax = (json['boneMax'] as num).toDouble() + ..boneMin = (json['boneMin'] as num).toDouble() + ..bmrMax = json['bmrMax'] as int + ..bmrMin = json['bmrMin'] as int + ..waterMassMax = (json['waterMassMax'] as num).toDouble() + ..waterMassMin = (json['waterMassMin'] as num).toDouble() + ..proteinMassMax = (json['proteinMassMax'] as num).toDouble() + ..proteinMassMin = (json['proteinMassMin'] as num).toDouble() + ..muscleMassMax = (json['muscleMassMax'] as num).toDouble() + ..muscleMassMin = (json['muscleMassMin'] as num).toDouble() + ..smi = (json['smi'] as num).toDouble() + ..obesityDegree = json['obesityDegree'] as int + ..state = json['state'] as int + ..imp = (json['imp'] as num).toDouble() + ..imp2 = (json['imp2'] as num).toDouble() + ..imp3 = (json['imp3'] as num).toDouble() + ..imp4 = (json['imp4'] as num).toDouble() + ..imp5 = (json['imp5'] as num).toDouble() + ..extData = json['extData'] == null + ? null + : ICWeightExtData.fromJson(json['extData'] as Map) + ..data_calc_type = json['data_calc_type'] as int + ..bfa_type = $enumDecodeNullable(_$ICBFATypeEnumMap, json['bfa_type']) + ..impendenceType = json['impendenceType'] as int + ..impendenceProperty = json['impendenceProperty'] as int + ..impendences = (json['impendences'] as List?) + ?.map((e) => (e as num).toDouble()) + .toList(); + +Map _$ICWeightDataToJson(ICWeightData instance) => + { + 'userId': instance.userId, + 'isStabilized': instance.isStabilized, + 'weight_g': instance.weight_g, + 'weight_kg': instance.weight_kg, + 'weight_lb': instance.weight_lb, + 'weight_st': instance.weight_st, + 'weight_st_lb': instance.weight_st_lb, + 'precision_kg': instance.precision_kg, + 'precision_lb': instance.precision_lb, + 'precision_st_lb': instance.precision_st_lb, + 'kg_scale_division': instance.kg_scale_division, + 'lb_scale_division': instance.lb_scale_division, + 'temperature': instance.temperature, + 'isSupportHR': instance.isSupportHR, + 'hr': instance.hr, + 'time': instance.time, + 'bmi': instance.bmi, + 'bodyFatPercent': instance.bodyFatPercent, + 'subcutaneousFatPercent': instance.subcutaneousFatPercent, + 'visceralFat': instance.visceralFat, + 'musclePercent': instance.musclePercent, + 'bmr': instance.bmr, + 'boneMass': instance.boneMass, + 'moisturePercent': instance.moisturePercent, + 'physicalAge': instance.physicalAge, + 'proteinPercent': instance.proteinPercent, + 'smPercent': instance.smPercent, + 'electrode': instance.electrode, + 'bodyScore': instance.bodyScore, + 'bodyType': instance.bodyType, + 'targetWeight': instance.targetWeight, + 'bfmControl': instance.bfmControl, + 'ffmControl': instance.ffmControl, + 'weightControl': instance.weightControl, + 'weightStandard': instance.weightStandard, + 'bfmStandard': instance.bfmStandard, + 'bmiStandard': instance.bmiStandard, + 'smmStandard': instance.smmStandard, + 'ffmStandard': instance.ffmStandard, + 'bfpStandard': instance.bfpStandard, + 'bmrStandard': instance.bmrStandard, + 'bmiMax': instance.bmiMax, + 'bmiMin': instance.bmiMin, + 'bfmMax': instance.bfmMax, + 'bfmMin': instance.bfmMin, + 'bfpMax': instance.bfpMax, + 'bfpMin': instance.bfpMin, + 'weightMax': instance.weightMax, + 'weightMin': instance.weightMin, + 'smmMax': instance.smmMax, + 'smmMin': instance.smmMin, + 'boneMax': instance.boneMax, + 'boneMin': instance.boneMin, + 'bmrMax': instance.bmrMax, + 'bmrMin': instance.bmrMin, + 'waterMassMax': instance.waterMassMax, + 'waterMassMin': instance.waterMassMin, + 'proteinMassMax': instance.proteinMassMax, + 'proteinMassMin': instance.proteinMassMin, + 'muscleMassMax': instance.muscleMassMax, + 'muscleMassMin': instance.muscleMassMin, + 'smi': instance.smi, + 'obesityDegree': instance.obesityDegree, + 'state': instance.state, + 'imp': instance.imp, + 'imp2': instance.imp2, + 'imp3': instance.imp3, + 'imp4': instance.imp4, + 'imp5': instance.imp5, + 'extData': instance.extData, + 'data_calc_type': instance.data_calc_type, + 'bfa_type': _$ICBFATypeEnumMap[instance.bfa_type], + 'impendenceType': instance.impendenceType, + 'impendenceProperty': instance.impendenceProperty, + 'impendences': instance.impendences, + }; + +const _$ICBFATypeEnumMap = { + ICBFAType.ICBFATypeWLA01: 'ICBFATypeWLA01', + ICBFAType.ICBFATypeWLA02: 'ICBFATypeWLA02', + ICBFAType.ICBFATypeWLA03: 'ICBFATypeWLA03', + ICBFAType.ICBFATypeWLA04: 'ICBFATypeWLA04', + ICBFAType.ICBFATypeWLA05: 'ICBFATypeWLA05', + ICBFAType.ICBFATypeWLA06: 'ICBFATypeWLA06', + ICBFAType.ICBFATypeWLA07: 'ICBFATypeWLA07', + ICBFAType.ICBFATypeWLA08: 'ICBFATypeWLA08', + ICBFAType.ICBFATypeWLA09: 'ICBFATypeWLA09', + ICBFAType.ICBFATypeWLA10: 'ICBFATypeWLA10', + ICBFAType.ICBFATypeWLA11: 'ICBFATypeWLA11', + ICBFAType.ICBFATypeWLA12: 'ICBFATypeWLA12', + ICBFAType.ICBFATypeWLA13: 'ICBFATypeWLA13', + ICBFAType.ICBFATypeWLA14: 'ICBFATypeWLA14', + ICBFAType.ICBFATypeWLA15: 'ICBFATypeWLA15', + ICBFAType.ICBFATypeWLA16: 'ICBFATypeWLA16', + ICBFAType.ICBFATypeWLA17: 'ICBFATypeWLA17', + ICBFAType.ICBFATypeWLA18: 'ICBFATypeWLA18', + ICBFAType.ICBFATypeWLA19: 'ICBFATypeWLA19', + ICBFAType.ICBFATypeWLA20: 'ICBFATypeWLA20', + ICBFAType.ICBFATypeWLA22: 'ICBFATypeWLA22', + ICBFAType.ICBFATypeWLA23: 'ICBFATypeWLA23', + ICBFAType.ICBFATypeWLA24: 'ICBFATypeWLA24', + ICBFAType.ICBFATypeWLA25: 'ICBFATypeWLA25', + ICBFAType.ICBFATypeWLA26: 'ICBFATypeWLA26', + ICBFAType.ICBFATypeWLA27: 'ICBFATypeWLA27', + ICBFAType.ICBFATypeWLA28: 'ICBFATypeWLA28', + ICBFAType.ICBFATypeWLA29: 'ICBFATypeWLA29', + ICBFAType.ICBFATypeUnknown: 'ICBFATypeUnknown', + ICBFAType.ICBFATypeRev: 'ICBFATypeRev', +}; diff --git a/lib/model/data/ICWeightExtData.dart b/lib/model/data/ICWeightExtData.dart new file mode 100644 index 0000000..c71746b --- /dev/null +++ b/lib/model/data/ICWeightExtData.dart @@ -0,0 +1,118 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'ICWeightExtData.g.dart'; + +@JsonSerializable() +class ICWeightExtData { + /** + 左手体脂率(单位:%, 精度:0.1) + */ + double left_arm = 0.0; + + /** + 右手体脂率(单位:%, 精度:0.1) + */ + double right_arm = 0.0; + + /** + 左脚体脂率(单位:%, 精度:0.1) + */ + double left_leg = 0.0; + + /** + 右脚体脂率(单位:%, 精度:0.1) + */ + double right_leg = 0.0; + + /** + 躯干体脂率(单位:%, 精度:0.1) + */ + double all_body = 0.0; + + /** + 左手脂肪量(单位:kg, 精度:0.1) + */ + double left_arm_kg = 0.0; + + /** + 右手脂肪量率(单位:kg, 精度:0.1) + */ + double right_arm_kg = 0.0; + + /** + 左脚脂肪量(单位:kg, 精度:0.1) + */ + double left_leg_kg = 0.0; + + /** + 右脚脂肪量(单位:kg, 精度:0.1) + */ + double right_leg_kg = 0.0; + + /** + 躯干脂肪量(单位:kg, 精度:0.1) + */ + double all_body_kg = 0.0; + + /** + 左手肌肉率(单位:%, 精度:0.1) + */ + double left_arm_muscle = 0.0; + + /** + 右手肌肉率(单位:%, 精度:0.1) + */ + double right_arm_muscle = 0.0; + + /** + 左脚肌肉率(单位:%, 精度:0.1) + */ + double left_leg_muscle = 0.0; + + /** + 右脚肌肉率(单位:%, 精度:0.1) + */ + double right_leg_muscle = 0.0; + + /** + 躯干肌肉率(单位:%, 精度:0.1) + */ + double all_body_muscle = 0.0; + + /** + 左手肌肉量(单位:kg, 精度:0.1) + */ + double left_arm_muscle_kg = 0.0; + + /** + 右手肌肉量(单位:kg, 精度:0.1) + */ + double right_arm_muscle_kg = 0.0; + + /** + 左脚肌肉量(单位:kg, 精度:0.1) + */ + double left_leg_muscle_kg = 0.0; + + /** + 右脚肌肉量(单位:kg, 精度:0.1) + */ + double right_leg_muscle_kg = 0.0; + + /** + 躯干肌肉量(单位:kg, 精度:0.1) + */ + double all_body_muscle_kg = 0.0; + + ICWeightExtData(); + + factory ICWeightExtData.fromJson(Map json) => + _$ICWeightExtDataFromJson(json); + + Map toJson() => _$ICWeightExtDataToJson(this); + + @override + String toString() { + return 'ICWeightExtData{left_arm: $left_arm, right_arm: $right_arm, left_leg: $left_leg, right_leg: $right_leg, all_body: $all_body, left_arm_kg: $left_arm_kg, right_arm_kg: $right_arm_kg, left_leg_kg: $left_leg_kg, right_leg_kg: $right_leg_kg, all_body_kg: $all_body_kg, left_arm_muscle: $left_arm_muscle, right_arm_muscle: $right_arm_muscle, left_leg_muscle: $left_leg_muscle, right_leg_muscle: $right_leg_muscle, all_body_muscle: $all_body_muscle, left_arm_muscle_kg: $left_arm_muscle_kg, right_arm_muscle_kg: $right_arm_muscle_kg, left_leg_muscle_kg: $left_leg_muscle_kg, right_leg_muscle_kg: $right_leg_muscle_kg, all_body_muscle_kg: $all_body_muscle_kg}'; + } +} diff --git a/lib/model/data/ICWeightExtData.g.dart b/lib/model/data/ICWeightExtData.g.dart new file mode 100644 index 0000000..c9abf43 --- /dev/null +++ b/lib/model/data/ICWeightExtData.g.dart @@ -0,0 +1,54 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICWeightExtData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICWeightExtData _$ICWeightExtDataFromJson(Map json) => + ICWeightExtData() + ..left_arm = (json['left_arm'] as num).toDouble() + ..right_arm = (json['right_arm'] as num).toDouble() + ..left_leg = (json['left_leg'] as num).toDouble() + ..right_leg = (json['right_leg'] as num).toDouble() + ..all_body = (json['all_body'] as num).toDouble() + ..left_arm_kg = (json['left_arm_kg'] as num).toDouble() + ..right_arm_kg = (json['right_arm_kg'] as num).toDouble() + ..left_leg_kg = (json['left_leg_kg'] as num).toDouble() + ..right_leg_kg = (json['right_leg_kg'] as num).toDouble() + ..all_body_kg = (json['all_body_kg'] as num).toDouble() + ..left_arm_muscle = (json['left_arm_muscle'] as num).toDouble() + ..right_arm_muscle = (json['right_arm_muscle'] as num).toDouble() + ..left_leg_muscle = (json['left_leg_muscle'] as num).toDouble() + ..right_leg_muscle = (json['right_leg_muscle'] as num).toDouble() + ..all_body_muscle = (json['all_body_muscle'] as num).toDouble() + ..left_arm_muscle_kg = (json['left_arm_muscle_kg'] as num).toDouble() + ..right_arm_muscle_kg = (json['right_arm_muscle_kg'] as num).toDouble() + ..left_leg_muscle_kg = (json['left_leg_muscle_kg'] as num).toDouble() + ..right_leg_muscle_kg = (json['right_leg_muscle_kg'] as num).toDouble() + ..all_body_muscle_kg = (json['all_body_muscle_kg'] as num).toDouble(); + +Map _$ICWeightExtDataToJson(ICWeightExtData instance) => + { + 'left_arm': instance.left_arm, + 'right_arm': instance.right_arm, + 'left_leg': instance.left_leg, + 'right_leg': instance.right_leg, + 'all_body': instance.all_body, + 'left_arm_kg': instance.left_arm_kg, + 'right_arm_kg': instance.right_arm_kg, + 'left_leg_kg': instance.left_leg_kg, + 'right_leg_kg': instance.right_leg_kg, + 'all_body_kg': instance.all_body_kg, + 'left_arm_muscle': instance.left_arm_muscle, + 'right_arm_muscle': instance.right_arm_muscle, + 'left_leg_muscle': instance.left_leg_muscle, + 'right_leg_muscle': instance.right_leg_muscle, + 'all_body_muscle': instance.all_body_muscle, + 'left_arm_muscle_kg': instance.left_arm_muscle_kg, + 'right_arm_muscle_kg': instance.right_arm_muscle_kg, + 'left_leg_muscle_kg': instance.left_leg_muscle_kg, + 'right_leg_muscle_kg': instance.right_leg_muscle_kg, + 'all_body_muscle_kg': instance.all_body_muscle_kg, + }; diff --git a/lib/model/data/ICWeightHistoryData.dart b/lib/model/data/ICWeightHistoryData.dart new file mode 100644 index 0000000..cdbc2b8 --- /dev/null +++ b/lib/model/data/ICWeightHistoryData.dart @@ -0,0 +1,141 @@ + + +import 'package:icdevicemanager_flutter/model/converter/ICWeightCenterDataConverter.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import '../other/ICConstant.dart'; +import 'ICWeightCenterData.dart'; + + +part 'ICWeightHistoryData.g.dart'; + +@JsonSerializable() +class ICWeightHistoryData { + /** + 用户ID,默认:0 + */ + int userId = 0; + + /** + 体重(g) + */ + int weight_g = 0; + + /** + 体重(kg) + */ + double weight_kg = 0.0; + + /** + 体重(lb) + */ + double weight_lb = 0.0; + + /** + 体重(st:lb),注:这个字段跟weight_st_lb一起使用 + */ + int weight_st = 0; + + /** + 体重(st:lb),注:这个字段跟weight_st一起使用 + */ + double weight_st_lb = 0.0; + + /** + kg体重小数点位数,如:weight_kg=70.12,则precision=2,weight_kg=71.5,则precision_kg=1 + */ + int precision_kg = 1; + + /** + lb体重小数点位数,如:weight_lb=70.12,则precision=2,weight_lb=71.5,则precision_lb=1 + */ + int precision_lb = 1; + + /** + st:lb体重小数点位数 + */ + int precision_st_lb = 1; + + /** + kg分度值 + */ + int kg_scale_division = 0; + + /** + lb分度值 + */ + int lb_scale_division = 0; + + /** + 测量时间戳(秒) + */ + int time = 0; + + /** + 心率值 + */ + int hr = 0; + + /** + 电极数,4电极或者8电极 + */ + int electrode = 4; + + /** + 全身阻抗(单位:欧姆ohm), `electrode=4`时,只使用这个阻抗,如阻抗等于0,则代表测量不到阻抗 + */ + double imp = 0; + + /** + 左手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp2 = 0; + + /** + 右手阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp3 = 0; + + /** + 左腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp4 = 0; + + /** + 右腳阻抗(8电极)(单位:欧姆ohm),如阻抗等于0,则代表测量不到阻抗 + */ + double imp5 = 0; + + /** + 平衡数据 + */ + @ICWeightCenterDataConverter() + ICWeightCenterData? centerData; + + /** + 数据计算方式(0:sdk,1:设备计算) + */ + int data_calc_type = 0; + + /** + 本次体脂数据计算的算法类型 + */ + ICBFAType bfa_type = ICBFAType.ICBFATypeUnknown; + + int impendenceType = 0; + + int impendenceProperty = 0; + + List? impendences; + + ICWeightHistoryData(); + + + factory ICWeightHistoryData.fromJson(Map json) => _$ICWeightHistoryDataFromJson(json); + Map toJson() => _$ICWeightHistoryDataToJson(this); + + @override + String toString() { + return 'ICWeightHistoryData{userId: $userId, weight_g: $weight_g, weight_kg: $weight_kg, weight_lb: $weight_lb, weight_st: $weight_st, weight_st_lb: $weight_st_lb, precision_kg: $precision_kg, precision_lb: $precision_lb, precision_st_lb: $precision_st_lb, kg_scale_division: $kg_scale_division, lb_scale_division: $lb_scale_division, time: $time, hr: $hr, electrode: $electrode, imp: $imp, imp2: $imp2, imp3: $imp3, imp4: $imp4, imp5: $imp5, centerData: $centerData, data_calc_type: $data_calc_type, bfa_type: $bfa_type, impendenceType: $impendenceType, impendenceProperty: $impendenceProperty, impendences: $impendences}'; + } +} diff --git a/lib/model/data/ICWeightHistoryData.g.dart b/lib/model/data/ICWeightHistoryData.g.dart new file mode 100644 index 0000000..19c5fad --- /dev/null +++ b/lib/model/data/ICWeightHistoryData.g.dart @@ -0,0 +1,114 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICWeightHistoryData.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICWeightHistoryData _$ICWeightHistoryDataFromJson(Map json) => + ICWeightHistoryData() + ..userId = json['userId'] as int + ..weight_g = json['weight_g'] as int + ..weight_kg = (json['weight_kg'] as num).toDouble() + ..weight_lb = (json['weight_lb'] as num).toDouble() + ..weight_st = json['weight_st'] as int + ..weight_st_lb = (json['weight_st_lb'] as num).toDouble() + ..precision_kg = json['precision_kg'] as int + ..precision_lb = json['precision_lb'] as int + ..precision_st_lb = json['precision_st_lb'] as int + ..kg_scale_division = json['kg_scale_division'] as int + ..lb_scale_division = json['lb_scale_division'] as int + ..time = json['time'] as int + ..hr = json['hr'] as int + ..electrode = json['electrode'] as int + ..imp = (json['imp'] as num).toDouble() + ..imp2 = (json['imp2'] as num).toDouble() + ..imp3 = (json['imp3'] as num).toDouble() + ..imp4 = (json['imp4'] as num).toDouble() + ..imp5 = (json['imp5'] as num).toDouble() + ..centerData = _$JsonConverterFromJson( + json['centerData'], const ICWeightCenterDataConverter().fromJson) + ..data_calc_type = json['data_calc_type'] as int + ..bfa_type = $enumDecode(_$ICBFATypeEnumMap, json['bfa_type']) + ..impendenceType = json['impendenceType'] as int + ..impendenceProperty = json['impendenceProperty'] as int + ..impendences = (json['impendences'] as List?) + ?.map((e) => (e as num).toDouble()) + .toList(); + +Map _$ICWeightHistoryDataToJson( + ICWeightHistoryData instance) => + { + 'userId': instance.userId, + 'weight_g': instance.weight_g, + 'weight_kg': instance.weight_kg, + 'weight_lb': instance.weight_lb, + 'weight_st': instance.weight_st, + 'weight_st_lb': instance.weight_st_lb, + 'precision_kg': instance.precision_kg, + 'precision_lb': instance.precision_lb, + 'precision_st_lb': instance.precision_st_lb, + 'kg_scale_division': instance.kg_scale_division, + 'lb_scale_division': instance.lb_scale_division, + 'time': instance.time, + 'hr': instance.hr, + 'electrode': instance.electrode, + 'imp': instance.imp, + 'imp2': instance.imp2, + 'imp3': instance.imp3, + 'imp4': instance.imp4, + 'imp5': instance.imp5, + 'centerData': _$JsonConverterToJson( + instance.centerData, const ICWeightCenterDataConverter().toJson), + 'data_calc_type': instance.data_calc_type, + 'bfa_type': _$ICBFATypeEnumMap[instance.bfa_type]!, + 'impendenceType': instance.impendenceType, + 'impendenceProperty': instance.impendenceProperty, + 'impendences': instance.impendences, + }; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); + +const _$ICBFATypeEnumMap = { + ICBFAType.ICBFATypeWLA01: 'ICBFATypeWLA01', + ICBFAType.ICBFATypeWLA02: 'ICBFATypeWLA02', + ICBFAType.ICBFATypeWLA03: 'ICBFATypeWLA03', + ICBFAType.ICBFATypeWLA04: 'ICBFATypeWLA04', + ICBFAType.ICBFATypeWLA05: 'ICBFATypeWLA05', + ICBFAType.ICBFATypeWLA06: 'ICBFATypeWLA06', + ICBFAType.ICBFATypeWLA07: 'ICBFATypeWLA07', + ICBFAType.ICBFATypeWLA08: 'ICBFATypeWLA08', + ICBFAType.ICBFATypeWLA09: 'ICBFATypeWLA09', + ICBFAType.ICBFATypeWLA10: 'ICBFATypeWLA10', + ICBFAType.ICBFATypeWLA11: 'ICBFATypeWLA11', + ICBFAType.ICBFATypeWLA12: 'ICBFATypeWLA12', + ICBFAType.ICBFATypeWLA13: 'ICBFATypeWLA13', + ICBFAType.ICBFATypeWLA14: 'ICBFATypeWLA14', + ICBFAType.ICBFATypeWLA15: 'ICBFATypeWLA15', + ICBFAType.ICBFATypeWLA16: 'ICBFATypeWLA16', + ICBFAType.ICBFATypeWLA17: 'ICBFATypeWLA17', + ICBFAType.ICBFATypeWLA18: 'ICBFATypeWLA18', + ICBFAType.ICBFATypeWLA19: 'ICBFATypeWLA19', + ICBFAType.ICBFATypeWLA20: 'ICBFATypeWLA20', + ICBFAType.ICBFATypeWLA22: 'ICBFATypeWLA22', + ICBFAType.ICBFATypeWLA23: 'ICBFATypeWLA23', + ICBFAType.ICBFATypeWLA24: 'ICBFATypeWLA24', + ICBFAType.ICBFATypeWLA25: 'ICBFATypeWLA25', + ICBFAType.ICBFATypeWLA26: 'ICBFATypeWLA26', + ICBFAType.ICBFATypeWLA27: 'ICBFATypeWLA27', + ICBFAType.ICBFATypeWLA28: 'ICBFATypeWLA28', + ICBFAType.ICBFATypeWLA29: 'ICBFATypeWLA29', + ICBFAType.ICBFATypeUnknown: 'ICBFATypeUnknown', + ICBFAType.ICBFATypeRev: 'ICBFATypeRev', +}; + +Json? _$JsonConverterToJson( + Value? value, + Json? Function(Value value) toJson, +) => + value == null ? null : toJson(value); diff --git a/lib/model/device/ICDevice.dart b/lib/model/device/ICDevice.dart new file mode 100644 index 0000000..422269d --- /dev/null +++ b/lib/model/device/ICDevice.dart @@ -0,0 +1,15 @@ + + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICDevice.g.dart'; +@JsonSerializable() +class ICDevice { + String? macAddr; + + ICDevice(this.macAddr); + + factory ICDevice.fromJson(Map json) => _$ICDeviceFromJson(json); + + Map toJson() => _$ICDeviceToJson(this); +} \ No newline at end of file diff --git a/lib/model/device/ICDevice.g.dart b/lib/model/device/ICDevice.g.dart new file mode 100644 index 0000000..4a2effe --- /dev/null +++ b/lib/model/device/ICDevice.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICDevice.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICDevice _$ICDeviceFromJson(Map json) => ICDevice( + json['macAddr'] as String?, + ); + +Map _$ICDeviceToJson(ICDevice instance) => { + 'macAddr': instance.macAddr, + }; diff --git a/lib/model/device/ICDeviceInfo.dart b/lib/model/device/ICDeviceInfo.dart new file mode 100644 index 0000000..3cce887 --- /dev/null +++ b/lib/model/device/ICDeviceInfo.dart @@ -0,0 +1,66 @@ +import 'package:icdevicemanager_flutter/model/converter/ICDeviceInfoExtConverter.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfoExt.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'ICDeviceInfo.g.dart'; + +@JsonSerializable() +class ICDeviceInfo { + String mac = ""; + + String model = ""; + + String sn = ""; + + String firmwareVer = ""; + + String softwareVer = ""; + + String hardwareVer = ""; + + String manufactureName = ""; + + int kg_scale_division=0; + int lb_scale_division=0; + bool isSupportHr=false; + bool isSupportGravity=false; + bool isSupportBalance=false; + bool isSupportOTA=false; + bool isSupportOffline=false; + int bfDataCalcType=0; + bool isSupportUserInfo=false; + int maxUserCount=0; + int batteryType=0; + ICBFAType? bfaType; + ICBFAType? bfaType2; + bool isSupportUnitKg=false; + bool isSupportUnitLb=false; + bool isSupportUnitStLb=false; + bool isSupportUnitJin=false; + bool isSupportChangePole=false; + int pole=0; + int impendenceType=0; + int impendenceCount=0; + int impendencePrecision=0; + int impendencePropert=0; + bool enableMeasureImpendence=false; + bool enableMeasureHr=false; + bool enableMeasureBalance=false; + bool enableMeasureGravity =false; + + @ICDeviceInfoExtConverter() + ICDeviceInfoExt? extInfo; + + ICDeviceInfo(); + + factory ICDeviceInfo.fromJson(Map json) => + _$ICDeviceInfoFromJson(json); + + Map toJson() => _$ICDeviceInfoToJson(this); + + @override + String toString() { + return 'ICDeviceInfo{mac: $mac, model: $model, sn: $sn, firmwareVer: $firmwareVer, softwareVer: $softwareVer, hardwareVer: $hardwareVer, manufactureName: $manufactureName, kg_scale_division: $kg_scale_division, lb_scale_division: $lb_scale_division, isSupportHr: $isSupportHr, isSupportGravity: $isSupportGravity, isSupportBalance: $isSupportBalance, isSupportOTA: $isSupportOTA, isSupportOffline: $isSupportOffline, bfDataCalcType: $bfDataCalcType, isSupportUserInfo: $isSupportUserInfo, maxUserCount: $maxUserCount, batteryType: $batteryType, bfaType: $bfaType, bfaType2: $bfaType2, isSupportUnitKg: $isSupportUnitKg, isSupportUnitLb: $isSupportUnitLb, isSupportUnitStLb: $isSupportUnitStLb, isSupportUnitJin: $isSupportUnitJin, isSupportChangePole: $isSupportChangePole, pole: $pole, impendenceType: $impendenceType, impendenceCount: $impendenceCount, impendencePrecision: $impendencePrecision, impendencePropert: $impendencePropert, enableMeasureImpendence: $enableMeasureImpendence, enableMeasureHr: $enableMeasureHr, enableMeasureBalance: $enableMeasureBalance, enableMeasureGravity: $enableMeasureGravity, extInfo: $extInfo}'; + } +} diff --git a/lib/model/device/ICDeviceInfo.g.dart b/lib/model/device/ICDeviceInfo.g.dart new file mode 100644 index 0000000..5e46ee7 --- /dev/null +++ b/lib/model/device/ICDeviceInfo.g.dart @@ -0,0 +1,130 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICDeviceInfo.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICDeviceInfo _$ICDeviceInfoFromJson(Map json) => ICDeviceInfo() + ..mac = json['mac'] as String + ..model = json['model'] as String + ..sn = json['sn'] as String + ..firmwareVer = json['firmwareVer'] as String + ..softwareVer = json['softwareVer'] as String + ..hardwareVer = json['hardwareVer'] as String + ..manufactureName = json['manufactureName'] as String + ..kg_scale_division = json['kg_scale_division'] as int + ..lb_scale_division = json['lb_scale_division'] as int + ..isSupportHr = json['isSupportHr'] as bool + ..isSupportGravity = json['isSupportGravity'] as bool + ..isSupportBalance = json['isSupportBalance'] as bool + ..isSupportOTA = json['isSupportOTA'] as bool + ..isSupportOffline = json['isSupportOffline'] as bool + ..bfDataCalcType = json['bfDataCalcType'] as int + ..isSupportUserInfo = json['isSupportUserInfo'] as bool + ..maxUserCount = json['maxUserCount'] as int + ..batteryType = json['batteryType'] as int + ..bfaType = $enumDecodeNullable(_$ICBFATypeEnumMap, json['bfaType']) + ..bfaType2 = $enumDecodeNullable(_$ICBFATypeEnumMap, json['bfaType2']) + ..isSupportUnitKg = json['isSupportUnitKg'] as bool + ..isSupportUnitLb = json['isSupportUnitLb'] as bool + ..isSupportUnitStLb = json['isSupportUnitStLb'] as bool + ..isSupportUnitJin = json['isSupportUnitJin'] as bool + ..isSupportChangePole = json['isSupportChangePole'] as bool + ..pole = json['pole'] as int + ..impendenceType = json['impendenceType'] as int + ..impendenceCount = json['impendenceCount'] as int + ..impendencePrecision = json['impendencePrecision'] as int + ..impendencePropert = json['impendencePropert'] as int + ..enableMeasureImpendence = json['enableMeasureImpendence'] as bool + ..enableMeasureHr = json['enableMeasureHr'] as bool + ..enableMeasureBalance = json['enableMeasureBalance'] as bool + ..enableMeasureGravity = json['enableMeasureGravity'] as bool + ..extInfo = _$JsonConverterFromJson( + json['extInfo'], const ICDeviceInfoExtConverter().fromJson); + +Map _$ICDeviceInfoToJson(ICDeviceInfo instance) => + { + 'mac': instance.mac, + 'model': instance.model, + 'sn': instance.sn, + 'firmwareVer': instance.firmwareVer, + 'softwareVer': instance.softwareVer, + 'hardwareVer': instance.hardwareVer, + 'manufactureName': instance.manufactureName, + 'kg_scale_division': instance.kg_scale_division, + 'lb_scale_division': instance.lb_scale_division, + 'isSupportHr': instance.isSupportHr, + 'isSupportGravity': instance.isSupportGravity, + 'isSupportBalance': instance.isSupportBalance, + 'isSupportOTA': instance.isSupportOTA, + 'isSupportOffline': instance.isSupportOffline, + 'bfDataCalcType': instance.bfDataCalcType, + 'isSupportUserInfo': instance.isSupportUserInfo, + 'maxUserCount': instance.maxUserCount, + 'batteryType': instance.batteryType, + 'bfaType': _$ICBFATypeEnumMap[instance.bfaType], + 'bfaType2': _$ICBFATypeEnumMap[instance.bfaType2], + 'isSupportUnitKg': instance.isSupportUnitKg, + 'isSupportUnitLb': instance.isSupportUnitLb, + 'isSupportUnitStLb': instance.isSupportUnitStLb, + 'isSupportUnitJin': instance.isSupportUnitJin, + 'isSupportChangePole': instance.isSupportChangePole, + 'pole': instance.pole, + 'impendenceType': instance.impendenceType, + 'impendenceCount': instance.impendenceCount, + 'impendencePrecision': instance.impendencePrecision, + 'impendencePropert': instance.impendencePropert, + 'enableMeasureImpendence': instance.enableMeasureImpendence, + 'enableMeasureHr': instance.enableMeasureHr, + 'enableMeasureBalance': instance.enableMeasureBalance, + 'enableMeasureGravity': instance.enableMeasureGravity, + 'extInfo': _$JsonConverterToJson( + instance.extInfo, const ICDeviceInfoExtConverter().toJson), + }; + +const _$ICBFATypeEnumMap = { + ICBFAType.ICBFATypeWLA01: 'ICBFATypeWLA01', + ICBFAType.ICBFATypeWLA02: 'ICBFATypeWLA02', + ICBFAType.ICBFATypeWLA03: 'ICBFATypeWLA03', + ICBFAType.ICBFATypeWLA04: 'ICBFATypeWLA04', + ICBFAType.ICBFATypeWLA05: 'ICBFATypeWLA05', + ICBFAType.ICBFATypeWLA06: 'ICBFATypeWLA06', + ICBFAType.ICBFATypeWLA07: 'ICBFATypeWLA07', + ICBFAType.ICBFATypeWLA08: 'ICBFATypeWLA08', + ICBFAType.ICBFATypeWLA09: 'ICBFATypeWLA09', + ICBFAType.ICBFATypeWLA10: 'ICBFATypeWLA10', + ICBFAType.ICBFATypeWLA11: 'ICBFATypeWLA11', + ICBFAType.ICBFATypeWLA12: 'ICBFATypeWLA12', + ICBFAType.ICBFATypeWLA13: 'ICBFATypeWLA13', + ICBFAType.ICBFATypeWLA14: 'ICBFATypeWLA14', + ICBFAType.ICBFATypeWLA15: 'ICBFATypeWLA15', + ICBFAType.ICBFATypeWLA16: 'ICBFATypeWLA16', + ICBFAType.ICBFATypeWLA17: 'ICBFATypeWLA17', + ICBFAType.ICBFATypeWLA18: 'ICBFATypeWLA18', + ICBFAType.ICBFATypeWLA19: 'ICBFATypeWLA19', + ICBFAType.ICBFATypeWLA20: 'ICBFATypeWLA20', + ICBFAType.ICBFATypeWLA22: 'ICBFATypeWLA22', + ICBFAType.ICBFATypeWLA23: 'ICBFATypeWLA23', + ICBFAType.ICBFATypeWLA24: 'ICBFATypeWLA24', + ICBFAType.ICBFATypeWLA25: 'ICBFATypeWLA25', + ICBFAType.ICBFATypeWLA26: 'ICBFATypeWLA26', + ICBFAType.ICBFATypeWLA27: 'ICBFATypeWLA27', + ICBFAType.ICBFATypeWLA28: 'ICBFATypeWLA28', + ICBFAType.ICBFATypeWLA29: 'ICBFATypeWLA29', + ICBFAType.ICBFATypeUnknown: 'ICBFATypeUnknown', + ICBFAType.ICBFATypeRev: 'ICBFATypeRev', +}; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); + +Json? _$JsonConverterToJson( + Value? value, + Json? Function(Value value) toJson, +) => + value == null ? null : toJson(value); diff --git a/lib/model/device/ICDeviceInfoExt.dart b/lib/model/device/ICDeviceInfoExt.dart new file mode 100644 index 0000000..251f47d --- /dev/null +++ b/lib/model/device/ICDeviceInfoExt.dart @@ -0,0 +1,15 @@ + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICDeviceInfoExt.g.dart'; +@JsonSerializable() +class ICDeviceInfoExt{ + + String? ext; + + ICDeviceInfoExt(); + + factory ICDeviceInfoExt.fromJson(Map json) => _$ICDeviceInfoExtFromJson(json); + + Map toJson() => _$ICDeviceInfoExtToJson(this); +} \ No newline at end of file diff --git a/lib/model/device/ICDeviceInfoExt.g.dart b/lib/model/device/ICDeviceInfoExt.g.dart new file mode 100644 index 0000000..7604f2d --- /dev/null +++ b/lib/model/device/ICDeviceInfoExt.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICDeviceInfoExt.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICDeviceInfoExt _$ICDeviceInfoExtFromJson(Map json) => + ICDeviceInfoExt()..ext = json['ext'] as String?; + +Map _$ICDeviceInfoExtToJson(ICDeviceInfoExt instance) => + { + 'ext': instance.ext, + }; diff --git a/lib/model/device/ICKitchenDeviceInfoExt.dart b/lib/model/device/ICKitchenDeviceInfoExt.dart new file mode 100644 index 0000000..7df161d --- /dev/null +++ b/lib/model/device/ICKitchenDeviceInfoExt.dart @@ -0,0 +1,10 @@ + +import 'package:json_annotation/json_annotation.dart'; + +part 'ICKitchenDeviceInfoExt.g.dart'; +@JsonSerializable() +class ICKitchenDeviceInfoExt{ + String? ext; + + ICKitchenDeviceInfoExt(); +} \ No newline at end of file diff --git a/lib/model/device/ICKitchenDeviceInfoExt.g.dart b/lib/model/device/ICKitchenDeviceInfoExt.g.dart new file mode 100644 index 0000000..e784e30 --- /dev/null +++ b/lib/model/device/ICKitchenDeviceInfoExt.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICKitchenDeviceInfoExt.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICKitchenDeviceInfoExt _$ICKitchenDeviceInfoExtFromJson( + Map json) => + ICKitchenDeviceInfoExt()..ext = json['ext'] as String?; + +Map _$ICKitchenDeviceInfoExtToJson( + ICKitchenDeviceInfoExt instance) => + { + 'ext': instance.ext, + }; diff --git a/lib/model/device/ICScaleDeviceInfo.dart b/lib/model/device/ICScaleDeviceInfo.dart new file mode 100644 index 0000000..a7d9063 --- /dev/null +++ b/lib/model/device/ICScaleDeviceInfo.dart @@ -0,0 +1,85 @@ + + + +import 'package:icdevicemanager_flutter/model/converter/ICDeviceInfoExtConverter.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDeviceInfoExt.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import '../other/ICConstant.dart'; + + +part 'ICScaleDeviceInfo.g.dart'; +@JsonSerializable() +class ICScaleDeviceInfo { + + + String mac = ""; + + String model = ""; + + String sn = ""; + + String firmwareVer = ""; + + String softwareVer = ""; + + String hardwareVer = ""; + + String manufactureName = ""; + + @ICDeviceInfoExtConverter() + ICDeviceInfoExt? extInfo ; + + int kg_scale_division = 0; + + int lb_scale_division = 0; + + bool isSupportHr = false; + + bool isSupportGravity = false; + + bool isSupportBalance = false; + + bool isSupportOTA = false; + + bool isSupportOffline = false; + + int bfDataCalcType = 0; + + bool isSupportUserInfo = false; + + int maxUserCount = 0; + + int batteryType = 0; + + ICBFAType bfaType = ICBFAType.ICBFATypeUnknown; + ICBFAType bfaType2 = ICBFAType.ICBFATypeUnknown; + + bool isSupportUnitKg = false; + + bool isSupportUnitLb = false; + + bool isSupportUnitStLb = false; + + bool isSupportUnitJin = false; + + bool isSupportChangePole = false; + + int pole = 0; + + int impendenceType = 0; + int impendenceCount = 0; + int impendencePrecision = 0; + + int impendenceProperty = 0; + + bool enableMeasureImpendence = false; + + bool enableMeasureHr = false; + + bool enableMeasureBalance = false; + + bool enableMeasureGravity = false; + + ICScaleDeviceInfo(); +} diff --git a/lib/model/device/ICScaleDeviceInfo.g.dart b/lib/model/device/ICScaleDeviceInfo.g.dart new file mode 100644 index 0000000..a59757b --- /dev/null +++ b/lib/model/device/ICScaleDeviceInfo.g.dart @@ -0,0 +1,131 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICScaleDeviceInfo.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICScaleDeviceInfo _$ICScaleDeviceInfoFromJson(Map json) => + ICScaleDeviceInfo() + ..mac = json['mac'] as String + ..model = json['model'] as String + ..sn = json['sn'] as String + ..firmwareVer = json['firmwareVer'] as String + ..softwareVer = json['softwareVer'] as String + ..hardwareVer = json['hardwareVer'] as String + ..manufactureName = json['manufactureName'] as String + ..extInfo = _$JsonConverterFromJson( + json['extInfo'], const ICDeviceInfoExtConverter().fromJson) + ..kg_scale_division = json['kg_scale_division'] as int + ..lb_scale_division = json['lb_scale_division'] as int + ..isSupportHr = json['isSupportHr'] as bool + ..isSupportGravity = json['isSupportGravity'] as bool + ..isSupportBalance = json['isSupportBalance'] as bool + ..isSupportOTA = json['isSupportOTA'] as bool + ..isSupportOffline = json['isSupportOffline'] as bool + ..bfDataCalcType = json['bfDataCalcType'] as int + ..isSupportUserInfo = json['isSupportUserInfo'] as bool + ..maxUserCount = json['maxUserCount'] as int + ..batteryType = json['batteryType'] as int + ..bfaType = $enumDecode(_$ICBFATypeEnumMap, json['bfaType']) + ..bfaType2 = $enumDecode(_$ICBFATypeEnumMap, json['bfaType2']) + ..isSupportUnitKg = json['isSupportUnitKg'] as bool + ..isSupportUnitLb = json['isSupportUnitLb'] as bool + ..isSupportUnitStLb = json['isSupportUnitStLb'] as bool + ..isSupportUnitJin = json['isSupportUnitJin'] as bool + ..isSupportChangePole = json['isSupportChangePole'] as bool + ..pole = json['pole'] as int + ..impendenceType = json['impendenceType'] as int + ..impendenceCount = json['impendenceCount'] as int + ..impendencePrecision = json['impendencePrecision'] as int + ..impendenceProperty = json['impendenceProperty'] as int + ..enableMeasureImpendence = json['enableMeasureImpendence'] as bool + ..enableMeasureHr = json['enableMeasureHr'] as bool + ..enableMeasureBalance = json['enableMeasureBalance'] as bool + ..enableMeasureGravity = json['enableMeasureGravity'] as bool; + +Map _$ICScaleDeviceInfoToJson(ICScaleDeviceInfo instance) => + { + 'mac': instance.mac, + 'model': instance.model, + 'sn': instance.sn, + 'firmwareVer': instance.firmwareVer, + 'softwareVer': instance.softwareVer, + 'hardwareVer': instance.hardwareVer, + 'manufactureName': instance.manufactureName, + 'extInfo': _$JsonConverterToJson( + instance.extInfo, const ICDeviceInfoExtConverter().toJson), + 'kg_scale_division': instance.kg_scale_division, + 'lb_scale_division': instance.lb_scale_division, + 'isSupportHr': instance.isSupportHr, + 'isSupportGravity': instance.isSupportGravity, + 'isSupportBalance': instance.isSupportBalance, + 'isSupportOTA': instance.isSupportOTA, + 'isSupportOffline': instance.isSupportOffline, + 'bfDataCalcType': instance.bfDataCalcType, + 'isSupportUserInfo': instance.isSupportUserInfo, + 'maxUserCount': instance.maxUserCount, + 'batteryType': instance.batteryType, + 'bfaType': _$ICBFATypeEnumMap[instance.bfaType]!, + 'bfaType2': _$ICBFATypeEnumMap[instance.bfaType2]!, + 'isSupportUnitKg': instance.isSupportUnitKg, + 'isSupportUnitLb': instance.isSupportUnitLb, + 'isSupportUnitStLb': instance.isSupportUnitStLb, + 'isSupportUnitJin': instance.isSupportUnitJin, + 'isSupportChangePole': instance.isSupportChangePole, + 'pole': instance.pole, + 'impendenceType': instance.impendenceType, + 'impendenceCount': instance.impendenceCount, + 'impendencePrecision': instance.impendencePrecision, + 'impendenceProperty': instance.impendenceProperty, + 'enableMeasureImpendence': instance.enableMeasureImpendence, + 'enableMeasureHr': instance.enableMeasureHr, + 'enableMeasureBalance': instance.enableMeasureBalance, + 'enableMeasureGravity': instance.enableMeasureGravity, + }; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); + +const _$ICBFATypeEnumMap = { + ICBFAType.ICBFATypeWLA01: 'ICBFATypeWLA01', + ICBFAType.ICBFATypeWLA02: 'ICBFATypeWLA02', + ICBFAType.ICBFATypeWLA03: 'ICBFATypeWLA03', + ICBFAType.ICBFATypeWLA04: 'ICBFATypeWLA04', + ICBFAType.ICBFATypeWLA05: 'ICBFATypeWLA05', + ICBFAType.ICBFATypeWLA06: 'ICBFATypeWLA06', + ICBFAType.ICBFATypeWLA07: 'ICBFATypeWLA07', + ICBFAType.ICBFATypeWLA08: 'ICBFATypeWLA08', + ICBFAType.ICBFATypeWLA09: 'ICBFATypeWLA09', + ICBFAType.ICBFATypeWLA10: 'ICBFATypeWLA10', + ICBFAType.ICBFATypeWLA11: 'ICBFATypeWLA11', + ICBFAType.ICBFATypeWLA12: 'ICBFATypeWLA12', + ICBFAType.ICBFATypeWLA13: 'ICBFATypeWLA13', + ICBFAType.ICBFATypeWLA14: 'ICBFATypeWLA14', + ICBFAType.ICBFATypeWLA15: 'ICBFATypeWLA15', + ICBFAType.ICBFATypeWLA16: 'ICBFATypeWLA16', + ICBFAType.ICBFATypeWLA17: 'ICBFATypeWLA17', + ICBFAType.ICBFATypeWLA18: 'ICBFATypeWLA18', + ICBFAType.ICBFATypeWLA19: 'ICBFATypeWLA19', + ICBFAType.ICBFATypeWLA20: 'ICBFATypeWLA20', + ICBFAType.ICBFATypeWLA22: 'ICBFATypeWLA22', + ICBFAType.ICBFATypeWLA23: 'ICBFATypeWLA23', + ICBFAType.ICBFATypeWLA24: 'ICBFATypeWLA24', + ICBFAType.ICBFATypeWLA25: 'ICBFATypeWLA25', + ICBFAType.ICBFATypeWLA26: 'ICBFATypeWLA26', + ICBFAType.ICBFATypeWLA27: 'ICBFATypeWLA27', + ICBFAType.ICBFATypeWLA28: 'ICBFATypeWLA28', + ICBFAType.ICBFATypeWLA29: 'ICBFATypeWLA29', + ICBFAType.ICBFATypeUnknown: 'ICBFATypeUnknown', + ICBFAType.ICBFATypeRev: 'ICBFATypeRev', +}; + +Json? _$JsonConverterToJson( + Value? value, + Json? Function(Value value) toJson, +) => + value == null ? null : toJson(value); diff --git a/lib/model/device/ICScanDeviceInfo.dart b/lib/model/device/ICScanDeviceInfo.dart new file mode 100644 index 0000000..f7b82ff --- /dev/null +++ b/lib/model/device/ICScanDeviceInfo.dart @@ -0,0 +1,34 @@ + + + + +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + + +part 'ICScanDeviceInfo.g.dart'; +@JsonSerializable() +class ICScanDeviceInfo { + String? name; + ICDeviceType? type; + ICDeviceSubType? subType; + ICDeviceCommunicationType? communicationType; + String? macAddr; + + List? services; + int rssi = 0; + int st_no = 0; + int nodeId = 0; + int deviceFlag = 0; + + ICScanDeviceInfo(); + + factory ICScanDeviceInfo.fromJson(Map json) => _$ICScanDeviceInfoFromJson(json); + + Map toJson() => _$ICScanDeviceInfoToJson(this); + + @override + String toString() { + return 'ICScanDeviceInfo{name: $name, type: $type, subType: $subType, communicationType: $communicationType, macAddr: $macAddr, services: $services, rssi: $rssi, st_no: $st_no, nodeId: $nodeId, deviceFlag: $deviceFlag}'; + } +} diff --git a/lib/model/device/ICScanDeviceInfo.g.dart b/lib/model/device/ICScanDeviceInfo.g.dart new file mode 100644 index 0000000..2c5f419 --- /dev/null +++ b/lib/model/device/ICScanDeviceInfo.g.dart @@ -0,0 +1,74 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICScanDeviceInfo.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICScanDeviceInfo _$ICScanDeviceInfoFromJson(Map json) => + ICScanDeviceInfo() + ..name = json['name'] as String? + ..type = $enumDecodeNullable(_$ICDeviceTypeEnumMap, json['type']) + ..subType = $enumDecodeNullable(_$ICDeviceSubTypeEnumMap, json['subType']) + ..communicationType = $enumDecodeNullable( + _$ICDeviceCommunicationTypeEnumMap, json['communicationType']) + ..macAddr = json['macAddr'] as String? + ..services = + (json['services'] as List?)?.map((e) => e as String).toList() + ..rssi = json['rssi'] as int + ..st_no = json['st_no'] as int + ..nodeId = json['nodeId'] as int + ..deviceFlag = json['deviceFlag'] as int; + +Map _$ICScanDeviceInfoToJson(ICScanDeviceInfo instance) => + { + 'name': instance.name, + 'type': _$ICDeviceTypeEnumMap[instance.type], + 'subType': _$ICDeviceSubTypeEnumMap[instance.subType], + 'communicationType': + _$ICDeviceCommunicationTypeEnumMap[instance.communicationType], + 'macAddr': instance.macAddr, + 'services': instance.services, + 'rssi': instance.rssi, + 'st_no': instance.st_no, + 'nodeId': instance.nodeId, + 'deviceFlag': instance.deviceFlag, + }; + +const _$ICDeviceTypeEnumMap = { + ICDeviceType.ICDeviceTypeUnKnown: 'ICDeviceTypeUnKnown', + ICDeviceType.ICDeviceTypeWeightScale: 'ICDeviceTypeWeightScale', + ICDeviceType.ICDeviceTypeFatScale: 'ICDeviceTypeFatScale', + ICDeviceType.ICDeviceTypeFatScaleWithTemperature: + 'ICDeviceTypeFatScaleWithTemperature', + ICDeviceType.ICDeviceTypeKitchenScale: 'ICDeviceTypeKitchenScale', + ICDeviceType.ICDeviceTypeRuler: 'ICDeviceTypeRuler', + ICDeviceType.ICDeviceTypeBalance: 'ICDeviceTypeBalance', + ICDeviceType.ICDeviceTypeSkip: 'ICDeviceTypeSkip', + ICDeviceType.ICDeviceTypeHR: 'ICDeviceTypeHR', +}; + +const _$ICDeviceSubTypeEnumMap = { + ICDeviceSubType.ICDeviceSubTypeDefault: 'ICDeviceSubTypeDefault', + ICDeviceSubType.ICDeviceSubTypeEightElectrode: + 'ICDeviceSubTypeEightElectrode', + ICDeviceSubType.ICDeviceSubTypeHeight: 'ICDeviceSubTypeHeight', + ICDeviceSubType.ICDeviceSubTypeEightElectrode2: + 'ICDeviceSubTypeEightElectrode2', + ICDeviceSubType.ICDeviceSubTypeScaleDual: 'ICDeviceSubTypeScaleDual', + ICDeviceSubType.ICDeviceSubTypeLightEffect: 'ICDeviceSubTypeLightEffect', + ICDeviceSubType.ICDeviceSubTypeColor: 'ICDeviceSubTypeColor', + ICDeviceSubType.ICDeviceSubTypeSound: 'ICDeviceSubTypeSound', + ICDeviceSubType.ICDeviceSubTypeLightAndSound: 'ICDeviceSubTypeLightAndSound', + ICDeviceSubType.ICDeviceSubTypeBaseSt: 'ICDeviceSubTypeBaseSt', +}; + +const _$ICDeviceCommunicationTypeEnumMap = { + ICDeviceCommunicationType.ICDeviceCommunicationTypeUnknown: + 'ICDeviceCommunicationTypeUnknown', + ICDeviceCommunicationType.ICDeviceCommunicationTypeConnect: + 'ICDeviceCommunicationTypeConnect', + ICDeviceCommunicationType.ICDeviceCommunicationTypeBroadcast: + 'ICDeviceCommunicationTypeBroadcast', +}; diff --git a/lib/model/device/ICUserInfo.dart b/lib/model/device/ICUserInfo.dart new file mode 100644 index 0000000..00b4f4a --- /dev/null +++ b/lib/model/device/ICUserInfo.dart @@ -0,0 +1,115 @@ +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'ICUserInfo.g.dart'; + +@JsonSerializable() +class ICUserInfo { + /** + 用户编号,默认:1 + */ + int userIndex = 1; + + /** + 用户ID,默认:0 + */ + int userId = 0; + + /** + 用户呢称,默认:"icomon" + */ + String nickName = "icomon"; + + /** + 身高(cm),默认:172cm + */ + double height = 172; + + /** + 当前体重(kg),默认:60.0kg + */ + double weight = 60; + /** + 目标体重(kg),默认:50.0kg + */ + double targetWeight = 50; + + /** + 年龄,默认:24 + */ + int age = 24; + + /** + 体重方向,默认:0 减重,1:增重 + */ + int weightDirection = 0; + + /** + 使用体脂算法版本,默认:ICBFATypeWLA01 + */ + ICBFAType bfaType = ICBFAType.valueOf(0); + + /** + 用户类型,默认:ICPeopleTypeNormal + */ + ICPeopleType peopleType = ICPeopleType.ICPeopleTypeNormal; + + /** + 性别,默认:ICSexTypeMale + */ + ICSexType sex = ICSexType.ICSexTypeMale; + + /** + 用户默认的体重单位,默认:ICWeightUnitKg + */ + ICWeightUnit weightUnit = ICWeightUnit.ICWeightUnitKg; + + /** + 用户默认的围尺单位,默认:ICRulerUnitCM + */ + ICRulerUnit rulerUnit = ICRulerUnit.ICRulerUnitCM; + + /** + 用户默认的围尺测量模式,默认:ICRulerMeasureModeLength + */ + ICRulerMeasureMode rulerMode = ICRulerMeasureMode.ICRulerMeasureModeLength; + + /** + 厨房秤默认单位,默认:ICKitchenScaleUnitG + */ + ICKitchenScaleUnit kitchenUnit = ICKitchenScaleUnit.ICKitchenScaleUnitG; + + /** + * 是否启用测量阻抗,默认:true,仅支持的设备有效 + */ + bool enableMeasureImpendence = true; + /** + * 是否启用测量HR,默认:true,仅支持的设备有效 + */ + bool enableMeasureHr = true; + /** + * 是否启用测量平衡,默认:true,仅支持的设备有效 + */ + bool enableMeasureBalance = true; + /** + * 是否启用测量重心,默认:true,仅支持的设备有效 + */ + bool enableMeasureGravity = true; + + /** + * 最后一次的阻抗 + */ + int lastImp = 0; + + ICUserInfo(); + + factory ICUserInfo.fromJson(Map json) => + _$ICUserInfoFromJson(json); + + Map toJson() => _$ICUserInfoToJson(this); + + @override + String toString() { + return 'ICUserInfo{userIndex: $userIndex, userId: $userId, nickName: $nickName, height: $height, weight: $weight, targetWeight: $targetWeight, age: $age, weightDirection: $weightDirection, bfaType: $bfaType, peopleType: $peopleType, sex: $sex, weightUnit: $weightUnit, rulerUnit: $rulerUnit, rulerMode: $rulerMode, kitchenUnit: $kitchenUnit, enableMeasureImpendence: $enableMeasureImpendence, enableMeasureHr: $enableMeasureHr, enableMeasureBalance: $enableMeasureBalance, enableMeasureGravity: $enableMeasureGravity, lastImp: $lastImp}'; + } +} diff --git a/lib/model/device/ICUserInfo.g.dart b/lib/model/device/ICUserInfo.g.dart new file mode 100644 index 0000000..15678ae --- /dev/null +++ b/lib/model/device/ICUserInfo.g.dart @@ -0,0 +1,126 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ICUserInfo.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ICUserInfo _$ICUserInfoFromJson(Map json) => ICUserInfo() + ..userIndex = json['userIndex'] as int + ..userId = json['userId'] as int + ..nickName = json['nickName'] as String + ..height = json['height'] as double + ..weight = (json['weight'] as num).toDouble() + ..targetWeight = (json['targetWeight'] as num).toDouble() + ..age = json['age'] as int + ..weightDirection = json['weightDirection'] as int + ..bfaType = $enumDecode(_$ICBFATypeEnumMap, json['bfaType']) + ..peopleType = $enumDecode(_$ICPeopleTypeEnumMap, json['peopleType']) + ..sex = $enumDecode(_$ICSexTypeEnumMap, json['sex']) + ..weightUnit = $enumDecode(_$ICWeightUnitEnumMap, json['weightUnit']) + ..rulerUnit = $enumDecode(_$ICRulerUnitEnumMap, json['rulerUnit']) + ..rulerMode = $enumDecode(_$ICRulerMeasureModeEnumMap, json['rulerMode']) + ..kitchenUnit = $enumDecode(_$ICKitchenScaleUnitEnumMap, json['kitchenUnit']) + ..enableMeasureImpendence = json['enableMeasureImpendence'] as bool + ..enableMeasureHr = json['enableMeasureHr'] as bool + ..enableMeasureBalance = json['enableMeasureBalance'] as bool + ..enableMeasureGravity = json['enableMeasureGravity'] as bool + ..lastImp = json['lastImp'] as int; + +Map _$ICUserInfoToJson(ICUserInfo instance) => + { + 'userIndex': instance.userIndex, + 'userId': instance.userId, + 'nickName': instance.nickName, + 'height': instance.height, + 'weight': instance.weight, + 'targetWeight': instance.targetWeight, + 'age': instance.age, + 'weightDirection': instance.weightDirection, + 'bfaType': _$ICBFATypeEnumMap[instance.bfaType]!, + 'peopleType': _$ICPeopleTypeEnumMap[instance.peopleType]!, + 'sex': _$ICSexTypeEnumMap[instance.sex]!, + 'weightUnit': _$ICWeightUnitEnumMap[instance.weightUnit]!, + 'rulerUnit': _$ICRulerUnitEnumMap[instance.rulerUnit]!, + 'rulerMode': _$ICRulerMeasureModeEnumMap[instance.rulerMode]!, + 'kitchenUnit': _$ICKitchenScaleUnitEnumMap[instance.kitchenUnit]!, + 'enableMeasureImpendence': instance.enableMeasureImpendence, + 'enableMeasureHr': instance.enableMeasureHr, + 'enableMeasureBalance': instance.enableMeasureBalance, + 'enableMeasureGravity': instance.enableMeasureGravity, + 'lastImp': instance.lastImp, + }; + +const _$ICBFATypeEnumMap = { + ICBFAType.ICBFATypeWLA01: 'ICBFATypeWLA01', + ICBFAType.ICBFATypeWLA02: 'ICBFATypeWLA02', + ICBFAType.ICBFATypeWLA03: 'ICBFATypeWLA03', + ICBFAType.ICBFATypeWLA04: 'ICBFATypeWLA04', + ICBFAType.ICBFATypeWLA05: 'ICBFATypeWLA05', + ICBFAType.ICBFATypeWLA06: 'ICBFATypeWLA06', + ICBFAType.ICBFATypeWLA07: 'ICBFATypeWLA07', + ICBFAType.ICBFATypeWLA08: 'ICBFATypeWLA08', + ICBFAType.ICBFATypeWLA09: 'ICBFATypeWLA09', + ICBFAType.ICBFATypeWLA10: 'ICBFATypeWLA10', + ICBFAType.ICBFATypeWLA11: 'ICBFATypeWLA11', + ICBFAType.ICBFATypeWLA12: 'ICBFATypeWLA12', + ICBFAType.ICBFATypeWLA13: 'ICBFATypeWLA13', + ICBFAType.ICBFATypeWLA14: 'ICBFATypeWLA14', + ICBFAType.ICBFATypeWLA15: 'ICBFATypeWLA15', + ICBFAType.ICBFATypeWLA16: 'ICBFATypeWLA16', + ICBFAType.ICBFATypeWLA17: 'ICBFATypeWLA17', + ICBFAType.ICBFATypeWLA18: 'ICBFATypeWLA18', + ICBFAType.ICBFATypeWLA19: 'ICBFATypeWLA19', + ICBFAType.ICBFATypeWLA20: 'ICBFATypeWLA20', + ICBFAType.ICBFATypeWLA22: 'ICBFATypeWLA22', + ICBFAType.ICBFATypeWLA23: 'ICBFATypeWLA23', + ICBFAType.ICBFATypeWLA24: 'ICBFATypeWLA24', + ICBFAType.ICBFATypeWLA25: 'ICBFATypeWLA25', + ICBFAType.ICBFATypeWLA26: 'ICBFATypeWLA26', + ICBFAType.ICBFATypeWLA27: 'ICBFATypeWLA27', + ICBFAType.ICBFATypeWLA28: 'ICBFATypeWLA28', + ICBFAType.ICBFATypeWLA29: 'ICBFATypeWLA29', + ICBFAType.ICBFATypeUnknown: 'ICBFATypeUnknown', + ICBFAType.ICBFATypeRev: 'ICBFATypeRev', +}; + +const _$ICPeopleTypeEnumMap = { + ICPeopleType.ICPeopleTypeNormal: 'ICPeopleTypeNormal', + ICPeopleType.ICPeopleTypeSportman: 'ICPeopleTypeSportman', +}; + +const _$ICSexTypeEnumMap = { + ICSexType.ICSexTypeUnknown: 'ICSexTypeUnknown', + ICSexType.ICSexTypeMale: 'ICSexTypeMale', + ICSexType.ICSexTypeFemale: 'ICSexTypeFemal', +}; + +const _$ICWeightUnitEnumMap = { + ICWeightUnit.ICWeightUnitKg: 'ICWeightUnitKg', + ICWeightUnit.ICWeightUnitLb: 'ICWeightUnitLb', + ICWeightUnit.ICWeightUnitSt: 'ICWeightUnitSt', + ICWeightUnit.ICWeightUnitJin: 'ICWeightUnitJin', +}; + +const _$ICRulerUnitEnumMap = { + ICRulerUnit.ICRulerUnitCM: 'ICRulerUnitCM', + ICRulerUnit.ICRulerUnitInch: 'ICRulerUnitInch', + ICRulerUnit.ICRulerUnitFtInch: 'ICRulerUnitFtInch', +}; + +const _$ICRulerMeasureModeEnumMap = { + ICRulerMeasureMode.ICRulerMeasureModeLength: 'ICRulerMeasureModeLength', + ICRulerMeasureMode.ICRulerMeasureModeGirth: 'ICRulerMeasureModeGirth', +}; + +const _$ICKitchenScaleUnitEnumMap = { + ICKitchenScaleUnit.ICKitchenScaleUnitG: 'ICKitchenScaleUnitG', + ICKitchenScaleUnit.ICKitchenScaleUnitMl: 'ICKitchenScaleUnitMl', + ICKitchenScaleUnit.ICKitchenScaleUnitLb: 'ICKitchenScaleUnitLb', + ICKitchenScaleUnit.ICKitchenScaleUnitOz: 'ICKitchenScaleUnitOz', + ICKitchenScaleUnit.ICKitchenScaleUnitMg: 'ICKitchenScaleUnitMg', + ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk: 'ICKitchenScaleUnitMlMilk', + ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater: 'ICKitchenScaleUnitFlOzWater', + ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk: 'ICKitchenScaleUnitFlOzMilk', +}; diff --git a/lib/model/other/ICConstant.dart b/lib/model/other/ICConstant.dart new file mode 100644 index 0000000..10f65ed --- /dev/null +++ b/lib/model/other/ICConstant.dart @@ -0,0 +1,788 @@ +/** + 设备类型 + **/ +enum ICDeviceType { + /// 未知 + ///*/ + ICDeviceTypeUnKnown, + + /// 体重秤 + ///*/ + ICDeviceTypeWeightScale, + + /// 脂肪秤 + ///*/ + ICDeviceTypeFatScale, + + /// 脂肪秤(带温度显示) + ///*/ + ICDeviceTypeFatScaleWithTemperature, + + /// 厨房秤 + ///*/ + ICDeviceTypeKitchenScale, + + /// 围尺 + ///*/ + ICDeviceTypeRuler, + + /// 平衡秤 + ///*/ + ICDeviceTypeBalance, + + /// 跳绳 + ///*/ + ICDeviceTypeSkip, + + /// HR + ///*/ + ICDeviceTypeHR, +} + +/** + 蓝牙状态 + */ +enum ICBleState { + /// 未知状态 + ///*/ + ICBleStateUnknown, + + /// 手机不支持BLE + ///*/ + ICBleStateUnsupported, + + /// 应用未获取蓝牙授权 + ///*/ + ICBleStateUnauthorized, + + /// 蓝牙关闭 + ///*/ + ICBleStatePoweredOff, + + /// 蓝牙打开 + ///*/ + ICBleStatePoweredOn, + + /// 蓝牙异常,建议开关蓝牙或重启手机 + ///*/ + ICBleStateException + + + +} + +/** + 设备子类型 + **/ +enum ICDeviceSubType { + /// 默认 + ///*/ + ICDeviceSubTypeDefault, + + /// 8电极设备 + ///*/ + ICDeviceSubTypeEightElectrode, + + /// 身高设备 + ///*/ + ICDeviceSubTypeHeight, + + /// 8电极设备2 + ///*/ + ICDeviceSubTypeEightElectrode2, + + /// 双模设备 + ///*/ + ICDeviceSubTypeScaleDual, + + /// 跳绳带灯效 + ///*/ + ICDeviceSubTypeLightEffect, + + /// 彩屏秤 + ///*/ + ICDeviceSubTypeColor, + + /// 跳绳带语音 + ///*/ + ICDeviceSubTypeSound, + + /// 跳绳带灯效和语音 + ///*/ + ICDeviceSubTypeLightAndSound, + + /// 基站 + ICDeviceSubTypeBaseSt, +} + +/** + 设备通讯方式 + + */ +enum ICDeviceCommunicationType { + /** + 未知 + */ + ICDeviceCommunicationTypeUnknown, + + /** + 连接式 + */ + ICDeviceCommunicationTypeConnect, + + /** + 广播式 + */ + ICDeviceCommunicationTypeBroadcast, +} + +/** + 设备连接状态 + + */ +enum ICDeviceConnectState { + /// 已连接 + ///*/ + ICDeviceConnectStateConnected, + + /// 已断开 + ///*/ + ICDeviceConnectStateDisconnected; + + + + +} + +/// 添加设备回调代码 +enum ICAddDeviceCallBackCode { + /// 添加成功 + ICAddDeviceCallBackCodeSuccess, + + /// 添加失败,SDK未初始化 + ICAddDeviceCallBackCodeFailedAndSDKNotInit, + + /// 添加失败,设备已存在 + ICAddDeviceCallBackCodeFailedAndExist, + + /// 添加失败,设备参数有错 + ICAddDeviceCallBackCodeFailedAndDeviceParamError; + +} + +/// 删除设备回调代码 +enum ICRemoveDeviceCallBackCode { + /// 删除成功 + ICRemoveDeviceCallBackCodeSuccess, + + /// 删除失败,SDK未初始化 + ICRemoveDeviceCallBackCodeFailedAndSDKNotInit, + + /// 删除失败,设备不存在 + ICRemoveDeviceCallBackCodeFailedAndNotExist, + + /// 删除失败,设备参数有错 + ICRemoveDeviceCallBackCodeFailedAndDeviceParamError; + + +} + +/** + 设置回调错误代码 + + */ +enum ICSettingCallBackCode { + /// 设置成功 + ///*/ + ICSettingCallBackCodeSuccess, + + /// 设置失败,SDK没有初始化 + ///*/ + ICSettingCallBackCodeSDKNotInit, + + /// 设置失败,SDK没有启动 + ///*/ + ICSettingCallBackCodeSDKNotStart, + + /// 设置失败,找不到设备或者设备未连接,请等待设备连接上后再设置 + ///*/ + ICSettingCallBackCodeDeviceNotFound, + + /// 设置失败,设备不支持该功能 + ///*/ + ICSettingCallBackCodeFunctionIsNotSupport, + + /// 设置失败,设备已断开 + ///*/ + ICSettingCallBackCodeDeviceDisConnected, + + /// 设置失败,无效参数 + ///*/ + ICSettingCallBackCodeInvalidParameter, + + /// 设置失败 + ///*/ + ICSettingCallBackCodeFailed + + +} + +/** + 体重秤单位 + */ +enum ICWeightUnit { + /// 公斤 + ICWeightUnitKg, + + /// 磅 + ICWeightUnitLb, + + /// 英石 + ICWeightUnitSt, + + /// 斤 + ICWeightUnitJin; + + + +} + +/** + 围尺单位 + */ +enum ICRulerUnit { + /// 厘米cm + ICRulerUnitCM, + + /// 英寸inch + ICRulerUnitInch, + + /// 英尺'英寸 + ICRulerUnitFtInch; + + +} + +/** + 围尺测量模式 + */ +enum ICRulerMeasureMode { + /// 长度模式 + ICRulerMeasureModeLength, + + /// 围度模式 + ICRulerMeasureModeGirth; + +} + +/** + 围尺设置的部位类型 + */ +enum ICRulerBodyPartsType { + /// 肩膀 + ICRulerPartsTypeShoulder, + + /// 手臂 + ICRulerPartsTypeBicep, + + /// 胸 + ICRulerPartsTypeChest, + + /// 腰 + ICRulerPartsTypeWaist, + + /// 臀 + ICRulerPartsTypeHip, + + /// 大腿 + ICRulerPartsTypeThigh, + + /// 小腿 + ICRulerPartsTypeCalf; + + + +} + +/** + 性别 + */ +enum ICSexType { + /// 未知/保密 + ICSexTypeUnknown, + + /// 男 + ICSexTypeMale, + + /// 女 + ICSexTypeFemale +} + +/** + 厨房秤单位 + */ +enum ICKitchenScaleUnit { + /// 克 + ICKitchenScaleUnitG, + + /// ml(water) + ICKitchenScaleUnitMl, + + /// 磅 + ICKitchenScaleUnitLb, + + /// 盎司 + ICKitchenScaleUnitOz, + + /// 毫克 + ICKitchenScaleUnitMg, + + /// ml(牛奶) + ICKitchenScaleUnitMlMilk, + + /// 盎司(水) + ICKitchenScaleUnitFlOzWater, + + /// 盎司(牛奶) + ICKitchenScaleUnitFlOzMilk + + + +} + +/** + 厨房秤营养成分类型 + */ +enum ICKitchenScaleNutritionFactType { + /* + * 卡路里, 最大不超过4294967295 + */ + ICKitchenScaleNutritionFactTypeCalorie, + + /* + * 总卡路里, 最大不超过4294967295 + */ + ICKitchenScaleNutritionFactTypeTotalCalorie, + + /* + * 总脂肪 + */ + ICKitchenScaleNutritionFactTypeTotalFat, + + /* + * 总蛋白质 + */ + ICKitchenScaleNutritionFactTypeTotalProtein, + + /* + * 总碳水化合物 + */ + ICKitchenScaleNutritionFactTypeTotalCarbohydrates, + + /* + * 总脂肪纤维 + */ + ICKitchenScaleNutritionFactTypeTotalFiber, + + /* + * 总胆固醇 + */ + ICKitchenScaleNutritionFactTypeTotalCholesterd, + + /* + * 总钠含量 + */ + ICKitchenScaleNutritionFactTypeTotalSodium, + + /* + * 总糖含量 + */ + ICKitchenScaleNutritionFactTypeTotalSugar, + + /* + * 脂肪 + */ + ICKitchenScaleNutritionFactTypeFat, + + /* + * 蛋白质 + */ + ICKitchenScaleNutritionFactTypeProtein, + + /* + * 碳水化合物 + */ + ICKitchenScaleNutritionFactTypeCarbohydrates, + + /* + * 膳食纤维 + */ + ICKitchenScaleNutritionFactTypeFiber, + + /* + * 胆固醇 + */ + ICKitchenScaleNutritionFactTypeCholesterd, + + /* + * 钠含量 + */ + ICKitchenScaleNutritionFactTypeSodium, + + /* + * 糖含量 + */ + ICKitchenScaleNutritionFactTypeSugar, +} + +/** + 算法版本 + */ +enum ICBFAType { + + ICBFATypeWLA01, + ICBFATypeWLA02, + ICBFATypeWLA03, + ICBFATypeWLA04, + ICBFATypeWLA05, + ICBFATypeWLA06, + ICBFATypeWLA07, + ICBFATypeWLA08, + ICBFATypeWLA09, + ICBFATypeWLA10, + ICBFATypeWLA11, + ICBFATypeWLA12, + ICBFATypeWLA13, + ICBFATypeWLA14, + ICBFATypeWLA15, + ICBFATypeWLA16, + ICBFATypeWLA17, + ICBFATypeWLA18, + ICBFATypeWLA19, + ICBFATypeWLA20, + ICBFATypeWLA22, + ICBFATypeWLA23, + ICBFATypeWLA24, + ICBFATypeWLA25, + ICBFATypeWLA26, + ICBFATypeWLA27, + ICBFATypeWLA28, + ICBFATypeWLA29, + ICBFATypeUnknown, + ICBFATypeRev; + + + + static ICBFAType valueOf(int value) { + switch (value) { + // #if WLA01 + case 0: + return ICBFATypeWLA01; + // #endif WLA01 + // #if WLA02 + case 1: + return ICBFATypeWLA02; + // #endif WLA02 + // #if WLA03 + case 2: + return ICBFATypeWLA03; + // #endif WLA03 + // #if WLA04 + case 3: + return ICBFATypeWLA04; + // #endif WLA04 + // #if WLA05 + case 4: + return ICBFATypeWLA05; + // #endif WLA05 + // #if WLA06 + case 5: + return ICBFATypeWLA06; + // #endif WLA06 + // #if WLA07 + case 6: + return ICBFATypeWLA07; + // #endif WLA07 + // #if WLA08 + case 7: + return ICBFATypeWLA08; + // #endif WLA08 + // #if WLA09 + case 8: + return ICBFATypeWLA09; + // #endif WLA09 + // #if WLA10 + case 9: + return ICBFATypeWLA10; + // #endif WLA10 + // #if WLA11 + case 10: + return ICBFATypeWLA11; + // #endif WLA11 + // #if WLA12 + case 11: + return ICBFATypeWLA12; + // #endif WLA12 + // #if WLA13 + case 12: + return ICBFATypeWLA13; + // #endif WLA13 + // #if WLA14 + case 13: + return ICBFATypeWLA14; + // #endif WLA14 + // #if WLA15 + case 14: + return ICBFATypeWLA15; + // #endif WLA15 + // #if WLA16 + case 15: + return ICBFATypeWLA16; + // #endif WLA16 + // #if WLA17 + case 16: + return ICBFATypeWLA17; + // #endif WLA17 + // #if WLA18 + case 17: + return ICBFATypeWLA18; + // #endif WLA18 + // #if WLA19 + case 18: + return ICBFATypeWLA19; + // #endif WLA19 + // #if WLA22 + case 21: + return ICBFATypeWLA22; + // #endif WLA22 + // #if WLA23 + case 22: + return ICBFATypeWLA23; + // #endif WLA23 + // #if WLA24 + case 23: + return ICBFATypeWLA24; + // #endif WLA24 + // #if WLA25 + case 24: + return ICBFATypeWLA25; + // #endif WLA25 + // #if WLA26 + case 25: + return ICBFATypeWLA26; + // #endif WLA26 + // #if WLA27 + case 26: + return ICBFATypeWLA27; + // #endif WLA27 + // #if WLA28 + case 27: + return ICBFATypeWLA28; + // #endif WLA28 + // #if WLA29 + case 28: + return ICBFATypeWLA29; + // #endif WLA29 + } + return ICBFATypeRev; + } +} + +/** + 用户类型 + */ +enum ICPeopleType { + /* + * 普通人 + */ + ICPeopleTypeNormal, + + /* + * 运动员 + */ + ICPeopleTypeSportman, +} + +/** + 数据类型 + */ +enum ICMeasureStep { + /* + * 测量体重 (ICWeightData) + */ + ICMeasureStepMeasureWeightData("ICMeasureStepMeasureWeightData"), + + /* + * 测量平衡 (ICWeightCenterData) + */ + ICMeasureStepMeasureCenterData("ICMeasureStepMeasureWeightData"), + + /* + * 开始测量阻抗 + */ + ICMeasureStepAdcStart("ICMeasureStepAdcStart"), + + /* + * 测量阻抗结束 (ICWeightData) + */ + ICMeasureStepAdcResult("ICMeasureStepAdcResult"), + + /* + * 开始测量心率 + */ + ICMeasureStepHrStart("ICMeasureStepHrStart"), + + /* + * 测量心率结束 (ICWeightData) + */ + ICMeasureStepHrResult("ICMeasureStepHrResult"), + + /* + * 测量结束 + */ + ICMeasureStepMeasureOver("ICMeasureStepMeasureOver"); + + final String value; + + const ICMeasureStep(this.value); + + +} + +/// 跳绳模式 +enum ICSkipMode { + /// 自由跳 + ICSkipModeFreedom, + /// 计时跳 + ICSkipModeTiming, + + /// 计次跳 + ICSkipModeCount; + + +} + +/* + * 跳绳灯效模式 + */ +enum ICSkipLightMode { + /* + * 无 + */ + ICSkipLightModeNone, + /* + * 速度模式 + */ + ICSkipLightModeRPM, + /* + * 计时模式 + */ + ICSkipLightModeTimer, + /* + * 计次模式 + */ + ICSkipLightModeCount, + /* + * 百分比模式 + */ + ICSkipLightModePercent, + /* + * 绊绳次数模式 + */ + ICSkipLightModeTripRope, + /* + * 测量模式模式 + */ + ICSkipLightModeMeasuring, +} + +/// 升级状态 +enum ICUpgradeStatus { + /// 升级成功 + ICUpgradeStatusSuccess, + + /// 升级中 + ICUpgradeStatusUpgrading, + + /// 升级失败 + ICUpgradeStatusFail, + + /// 升级失败,文件无效 + ICUpgradeStatusFailFileInvalid, + + /// 升级失败,设备不支持升级 + ICUpgradeStatusFailNotSupport + + +} + +/// Wifi配网状态 +enum ICConfigWifiState { + ICConfigWifiStateSuccess, + ICConfigWifiStateWifiConnecting, + ICConfigWifiStateServerConnecting, + ICConfigWifiStateWifiConnectFail, + ICConfigWifiStateServerConnectFail, + ICConfigWifiStatePasswordFail, + ICConfigWifiStateFail + + +} + +/* + * 语音类型 + */ +enum ICSkipSoundType { + /* + * 无 + */ + ICSkipSoundTypeNone, + /* + * 标准中文女声 + */ + ICSkipSoundTypeFemale, + /* + * 标准中文男声 + */ + ICSkipSoundTypeMale, +} + +/* + * 语音模式 + */ +enum ICSkipSoundMode { + /* + * 无 + */ + ICSkipSoundModeNone, + /* + * 按间隔时长 + */ + ICSkipSoundModeTime, + /* + * 按间隔个数 + */ + ICSkipSoundModeCount, +} + +/* + * 升级模式 + */ +enum ICOTAMode { + /* + * 自动模式 + */ + ICOTAModeAuto, + /* + * 模式1 + */ + ICOTAMode1, + /* + * 模式2 + */ + ICOTAMode2, + /* + * 模式3 + */ + ICOTAMode3, +} diff --git a/lib/model/other/ICDeviceManagerConfig.dart b/lib/model/other/ICDeviceManagerConfig.dart new file mode 100644 index 0000000..c1736fd --- /dev/null +++ b/lib/model/other/ICDeviceManagerConfig.dart @@ -0,0 +1,8 @@ +class ICDeviceManagerConfig{ + /** + 是否自动填充连接秤的阻抗(默认:false) + */ + bool is_fill_adc = false; + + ICDeviceManagerConfig(); +} \ No newline at end of file diff --git a/lib/model/other/ICMapKey.dart b/lib/model/other/ICMapKey.dart new file mode 100644 index 0000000..f0ab556 --- /dev/null +++ b/lib/model/other/ICMapKey.dart @@ -0,0 +1,17 @@ +class ICMapKey { + static String Method = "Method"; + static String Mac = "Mac"; + static String Password = "Password"; + static String SSID = "SSID"; + static String DstId = "DstId"; + static String StNo = "StNo"; + + static String JsonValue = "JsonValue"; + static String JsonValue2 = "JsonValue2"; + static String EnumName ="EnumName"; + static String BoolValue ="BoolValue"; + static String ObjectValue ="ObjectValue"; + static String IntValue ="IntValue"; + static String StringValue ="StringValue"; + +} diff --git a/lib/model/other/ICWPublishEvent.dart b/lib/model/other/ICWPublishEvent.dart new file mode 100644 index 0000000..21b4620 --- /dev/null +++ b/lib/model/other/ICWPublishEvent.dart @@ -0,0 +1,52 @@ +enum ICWPublishEvent { + initSDK("InitSDK"), + addDevice("AddDevice"), + addDevices("AddDevices"), + removeDevice("RemoveDevice"), + removeDevices("RemoveDevices"), + otaDevice("OTADevice"), + otaDevices("OTADevices"), + stopOTADevice("StopOTADevice"), + stopOTADevices("StopOTADevices"), + stopScan("StopScan"), + startScan("StartScan"), + updateUserInfo("SetUserInfo"), + setUserList("SetUserList"), + configWifi("configWifi"), + setScaleUnit("setScaleUnit"), + setRulerUnit("RulerUnitSetting"), + setRulerMeasureMode("RulerModeSetting"), + setRulerBodyPartsType("RulerBodyPartSetting"), + setWeight("SkipSetWeight"), + KitchenCMD("KitchenCMD"), + KitchenFactory("KitchenFactory"), + deleteTareWeight("KitchenTareWeight"), + powerOffKitchenScale("KitchenPowerOff"), + setKitchenSaleUnit("KitchenUnitSetting"), + KitchenSetNutritionFacts("KitchenSetNutritionFacts"), + stopSkip("SkipStop"), + startSkip("SkipStart"), + SetSkipMode("SetSkipMode"), + lockStSkip("SkipLockSt"), + skipLightSetting("SkipLightSetting"), + skipSoundsSetting("SkipSoundSetting"), + skipSetUserInfo("SkipSetUserInfo"), + changeStNo("changeStNo"), + changeStName("changeStName"), + setOtherParams("setOtherParams"), + setScaleUIItems("setScaleUIItems"), + setServerUrl("setServerUrl"), + queryStAllNode("queryStAllNode"), + debugCommand("debugCommand"), + calcBodyFat("CalcBodyFat"), + getLogPath("LogPath"); + + final String value; + + const ICWPublishEvent(this.value); + + String getValue() { + return value; + } +} + diff --git a/lib/model/other/ICWUploadEvent.dart b/lib/model/other/ICWUploadEvent.dart new file mode 100644 index 0000000..efe029f --- /dev/null +++ b/lib/model/other/ICWUploadEvent.dart @@ -0,0 +1,43 @@ +enum ICWUploadEvent { + initSDK("InitSDK"), + onBleState("onBleState"), + onNodeConnectionChanged("onNodeConnectionChanged"), + onDeviceConnectionChanged("onDeviceConnectionChanged"), + + onReceiveHrData("onReceiveHrData"), + onReceiveSkipData("onReceiveSkipData"), + onReceiveRulerData("onReceiveRulerData"), + onReceiveCoordData("onReceiveCoordData"), + onReceiveDebugData("onReceiveDebugData"), + onReceiveWeightData("onReceiveWeightData"), + onReceiveMeasureStepData("onReceiveMeasureStepData"), + onReceiveHistorySkipData("onReceiveHistorySkipData"), + onReceiveRulerHistoryData("onReceiveRulerHistoryData"), + onReceiveWeightCenterData("onReceiveWeightCenterData"), + onReceiveKitchenScaleData("onReceiveKitchenScaleData"), + + onReceiveRulerUnitChanged("onReceiveRulerUnitChanged"), + onReceiveWeightHistoryData("onReceiveWeightHistoryData"), + onReceiveWeightUnitChanged("onReceiveWeightUnitChanged"), + onReceiveKitchenScaleUnitChanged("onReceiveKitchenScaleUnitChanged"), + onReceiveRulerMeasureModeChanged("onReceiveRulerMeasureModeChanged"), + + onReceiveBattery("onReceiveBattery"), + onReceiveDeviceInfo("onReceiveDeviceInfo"), + onReceiveSkipBattery("onReceiveSkipBattery"), + onReceiveUpgradePercent("onReceiveUpgradePercent"), + onReceiveConfigWifiResult("onReceiveConfigWifiResult"), + + onScanResult("onScanResult"), + onSettingCallBack("onSettingCallBack"), + onAddDeviceCallBack("onAddDeviceCallBack"), + onRemoveDeviceCallBack("onRemoveDeviceCallBack"); + + final String value; + + const ICWUploadEvent(this.value); + + String getValue() { + return value; + } +} diff --git a/lib/utils/ICConverUtil.dart b/lib/utils/ICConverUtil.dart new file mode 100644 index 0000000..96ac328 --- /dev/null +++ b/lib/utils/ICConverUtil.dart @@ -0,0 +1,270 @@ +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; + +class ICConverUtil { + static ICBleState nameOf(String name) { + switch (name) { + case "ICBleStateUnknown": + return ICBleState.ICBleStateUnknown; + case "ICBleStateUnsupported": + return ICBleState.ICBleStateUnsupported; + case "ICBleStateUnauthorized": + return ICBleState.ICBleStateUnauthorized; + + case "ICBleStatePoweredOff": + return ICBleState.ICBleStatePoweredOff; + case "ICBleStatePoweredOn": + return ICBleState.ICBleStatePoweredOn; + case "ICBleStateException": + return ICBleState.ICBleStateException; + } + return ICBleState.ICBleStateException; + } + + static ICDeviceConnectState connectStateNameOf(String value) { + if ("ICDeviceConnectStateConnected" == value) { + return ICDeviceConnectState.ICDeviceConnectStateConnected; + } else { + return ICDeviceConnectState.ICDeviceConnectStateDisconnected; + } + } + + + static ICAddDeviceCallBackCode AddDeviceCallBackCodeNameOf(String name) { + switch (name) { + case "ICAddDeviceCallBackCodeSuccess": + return ICAddDeviceCallBackCode.ICAddDeviceCallBackCodeSuccess; + case "ICAddDeviceCallBackCodeFailedAndSDKNotInit": + return ICAddDeviceCallBackCode.ICAddDeviceCallBackCodeFailedAndSDKNotInit; + case "ICAddDeviceCallBackCodeFailedAndExist": + return ICAddDeviceCallBackCode.ICAddDeviceCallBackCodeFailedAndExist; + } + return ICAddDeviceCallBackCode.ICAddDeviceCallBackCodeFailedAndDeviceParamError; + } + + + static ICRemoveDeviceCallBackCode removeDeviceCallBackCodeNameOf(String name) { + switch (name) { + case "ICRemoveDeviceCallBackCodeSuccess": + return ICRemoveDeviceCallBackCode.ICRemoveDeviceCallBackCodeSuccess; + case "ICRemoveDeviceCallBackCodeFailedAndSDKNotInit": + return ICRemoveDeviceCallBackCode.ICRemoveDeviceCallBackCodeFailedAndSDKNotInit; + case "ICRemoveDeviceCallBackCodeFailedAndNotExist": + return ICRemoveDeviceCallBackCode.ICRemoveDeviceCallBackCodeFailedAndNotExist; + } + return ICRemoveDeviceCallBackCode.ICRemoveDeviceCallBackCodeFailedAndDeviceParamError; + } + + + static ICSettingCallBackCode settingCodeNameOf(String name) { + switch (name) { + case "ICSettingCallBackCodeSuccess": + return ICSettingCallBackCode.ICSettingCallBackCodeSuccess; + case "ICSettingCallBackCodeSDKNotInit": + return ICSettingCallBackCode. ICSettingCallBackCodeSDKNotInit; + case "ICSettingCallBackCodeSDKNotStart": + return ICSettingCallBackCode.ICSettingCallBackCodeSDKNotStart; + case "ICSettingCallBackCodeDeviceNotFound": + return ICSettingCallBackCode.ICSettingCallBackCodeDeviceNotFound; + case "ICSettingCallBackCodeFunctionIsNotSupport": + return ICSettingCallBackCode.ICSettingCallBackCodeFunctionIsNotSupport; + case "ICSettingCallBackCodeDeviceDisConnected": + return ICSettingCallBackCode.ICSettingCallBackCodeDeviceDisConnected; + case "ICSettingCallBackCodeInvalidParameter": + return ICSettingCallBackCode.ICSettingCallBackCodeInvalidParameter; + } + return ICSettingCallBackCode.ICSettingCallBackCodeFailed; + } + + + static ICWeightUnit weightUnitValueOf(int value) { + switch (value) { + case 0: + return ICWeightUnit.ICWeightUnitKg; + case 1: + return ICWeightUnit.ICWeightUnitLb; + case 2: + return ICWeightUnit.ICWeightUnitSt; + case 3: + return ICWeightUnit.ICWeightUnitJin; + } + return ICWeightUnit.ICWeightUnitKg; + } + + static ICWeightUnit weightUnitNameOf(String name) { + switch (name) { + case "ICWeightUnitKg": + return ICWeightUnit.ICWeightUnitKg; + case "ICWeightUnitLb": + return ICWeightUnit.ICWeightUnitLb; + case "ICWeightUnitSt": + return ICWeightUnit.ICWeightUnitSt; + case "ICWeightUnitJin": + return ICWeightUnit.ICWeightUnitJin; + } + return ICWeightUnit.ICWeightUnitKg; + } + + static ICRulerUnit rulerUnitNameOf(String name) { + switch (name) { + case "ICRulerUnitCM": + return ICRulerUnit.ICRulerUnitCM; + case "ICRulerUnitInch": + return ICRulerUnit.ICRulerUnitInch; + case "ICRulerUnitFtInch": + return ICRulerUnit.ICRulerUnitFtInch; + } + return ICRulerUnit.ICRulerUnitCM; + } + + static ICRulerUnit rulerUnitValueOf(int value) { + switch (value) { + case 0: + return ICRulerUnit.ICRulerUnitCM; + case 1: + return ICRulerUnit. ICRulerUnitInch; + case 2: + return ICRulerUnit.ICRulerUnitFtInch; + } + return ICRulerUnit.ICRulerUnitCM; + } + + static ICRulerMeasureMode rulerMeasureModeValueOf(int value) { + switch (value) { + case 1: + return ICRulerMeasureMode.ICRulerMeasureModeLength; + case 2: + return ICRulerMeasureMode.ICRulerMeasureModeGirth; + } + return ICRulerMeasureMode.ICRulerMeasureModeLength; + } + + static ICRulerMeasureMode rulerMeasureModeNameOf(String value) { + switch (value) { + case "ICRulerMeasureModeLength": + return ICRulerMeasureMode.ICRulerMeasureModeLength; + case "ICRulerMeasureModeGirth": + return ICRulerMeasureMode.ICRulerMeasureModeGirth; + } + return ICRulerMeasureMode.ICRulerMeasureModeLength; + } + + + static ICRulerBodyPartsType rulerBodyPartsValueOf(int value) { + switch (value) { + case 1: + return ICRulerBodyPartsType.ICRulerPartsTypeShoulder; + case 2: + return ICRulerBodyPartsType.ICRulerPartsTypeBicep; + case 3: + return ICRulerBodyPartsType.ICRulerPartsTypeChest; + case 4: + return ICRulerBodyPartsType.ICRulerPartsTypeWaist; + case 5: + return ICRulerBodyPartsType.ICRulerPartsTypeHip; + case 6: + return ICRulerBodyPartsType.ICRulerPartsTypeThigh; + case 7: + return ICRulerBodyPartsType.ICRulerPartsTypeCalf; + } + return ICRulerBodyPartsType.ICRulerPartsTypeShoulder; + } + + static ICConfigWifiState wifiStateNameOf(String value) { + switch (value) { + case "ICConfigWifiStateSuccess": + return ICConfigWifiState.ICConfigWifiStateSuccess; + case "ICConfigWifiStateWifiConnecting": + return ICConfigWifiState.ICConfigWifiStateWifiConnecting; + case "ICConfigWifiStateServerConnecting": + return ICConfigWifiState.ICConfigWifiStateServerConnecting; + case "ICConfigWifiStateWifiConnectFail": + return ICConfigWifiState.ICConfigWifiStateWifiConnectFail; + case "ICConfigWifiStateServerConnectFail": + return ICConfigWifiState.ICConfigWifiStateServerConnectFail; + case "ICConfigWifiStatePasswordFail": + return ICConfigWifiState.ICConfigWifiStatePasswordFail; + } + return ICConfigWifiState.ICConfigWifiStateFail; + } + + static ICUpgradeStatus upgradeStatusNameOf(String value) { + switch (value) { + case "ICUpgradeStatusSuccess": + return ICUpgradeStatus.ICUpgradeStatusSuccess; + case "ICUpgradeStatusUpgrading": + return ICUpgradeStatus.ICUpgradeStatusUpgrading; + case "ICUpgradeStatusFail": + return ICUpgradeStatus.ICUpgradeStatusFail; + case "ICUpgradeStatusFailFileInvalid": + return ICUpgradeStatus.ICUpgradeStatusFailFileInvalid; + case "ICUpgradeStatusFailNotSupport": + return ICUpgradeStatus.ICUpgradeStatusFailNotSupport; + } + return ICUpgradeStatus.ICUpgradeStatusFailNotSupport; + } + + static ICMeasureStep measureStepNameOf(String value) { + switch (value) { + case "ICMeasureStepMeasureWeightData": + return ICMeasureStep.ICMeasureStepMeasureWeightData; + case "ICMeasureStepMeasureCenterData": + return ICMeasureStep.ICMeasureStepMeasureCenterData; + case "ICMeasureStepAdcStart": + return ICMeasureStep.ICMeasureStepAdcStart; + case "ICMeasureStepAdcResult": + return ICMeasureStep.ICMeasureStepAdcResult; + case "ICMeasureStepHrStart": + return ICMeasureStep.ICMeasureStepHrStart; + case "ICMeasureStepHrResult": + return ICMeasureStep.ICMeasureStepHrResult; + case "ICMeasureStepMeasureOver": + return ICMeasureStep.ICMeasureStepMeasureOver; + } + + return ICMeasureStep.ICMeasureStepMeasureWeightData; + } + + static ICKitchenScaleUnit kitChenScaleUnitNameOf(String name) { + switch (name) { + case "ICKitchenScaleUnitG": + return ICKitchenScaleUnit. ICKitchenScaleUnitG; + case "ICKitchenScaleUnitMl": + return ICKitchenScaleUnit. ICKitchenScaleUnitMl; + case "ICKitchenScaleUnitLb": + return ICKitchenScaleUnit.ICKitchenScaleUnitLb; + case "ICKitchenScaleUnitOz": + return ICKitchenScaleUnit.ICKitchenScaleUnitOz; + case "ICKitchenScaleUnitMg": + return ICKitchenScaleUnit.ICKitchenScaleUnitMg; + case "ICKitchenScaleUnitMlMilk": + return ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk; + case "ICKitchenScaleUnitFlOzWater": + return ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater; + case "ICKitchenScaleUnitFlOzMilk": + return ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk; + } + return ICKitchenScaleUnit.ICKitchenScaleUnitG; + } + + static ICKitchenScaleUnit kitchenScaleValueOf(int value) { + switch (value) { + case 0: + return ICKitchenScaleUnit. ICKitchenScaleUnitG; + case 1: + return ICKitchenScaleUnit.ICKitchenScaleUnitMl; + case 2: + return ICKitchenScaleUnit.ICKitchenScaleUnitLb; + case 3: + return ICKitchenScaleUnit.ICKitchenScaleUnitOz; + case 4: + return ICKitchenScaleUnit.ICKitchenScaleUnitMg; + case 5: + return ICKitchenScaleUnit.ICKitchenScaleUnitMlMilk; + case 6: + return ICKitchenScaleUnit.ICKitchenScaleUnitFlOzWater; + case 7: + return ICKitchenScaleUnit.ICKitchenScaleUnitFlOzMilk; + } + return ICKitchenScaleUnit.ICKitchenScaleUnitG; + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..cc72a13 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,541 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "4826f97faae3af9761f26c52e56b2aa5ffd18d2c1721d984ad85137721c25f43" + url: "https://pub.dev" + source: hosted + version: "31.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "7337610c3f9cd13e6b7c6bb0f410644091cf63c9a1436e73352a70f3286abb03" + url: "https://pub.dev" + source: hosted + version: "2.8.0" + args: + dependency: transitive + description: + name: args + sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: de3ecca84980ee5e632888a04f4a72d8e3c390104fd5edb3a724785f66e9e97a + url: "https://pub.dev" + source: hosted + version: "2.0.3" + build_config: + dependency: transitive + description: + name: build_config + sha256: "9160104f468c8117f7dddd3c94d8f440d0f82a324bf29eb84e0b434cff7a0e03" + url: "https://pub.dev" + source: hosted + version: "0.4.7" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "02d9e94f2b7f6e4de0f0cd24dc9e2cd0c00fec082265ca89d3b32282cb7381bc" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "4666aef1d045c5ca15ebba63e400bd4e4fbd9f0dd06e791b51ab210da78a27f7" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + build_runner: + dependency: "direct main" + description: + name: build_runner + sha256: cd95f4d4a6a13b0dc1408b0a4b086bffdac08dcb61e45a0e1f2f58905d4c97a5 + url: "https://pub.dev" + source: hosted + version: "1.12.2" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "653b9dfd0472476ca837ef62786717434b8fa4f5e5521c85d7376dd3234aefeb" + url: "https://pub.dev" + source: hosted + version: "6.1.12" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" + url: "https://pub.dev" + source: hosted + version: "8.4.3" + change_app_package_name: + dependency: "direct dev" + description: + name: change_app_package_name + sha256: f9ebaf68a4b5a68c581492579bb68273c523ef325fbf9ce2f1b57fb136ad023b + url: "https://pub.dev" + source: hosted + version: "1.1.0" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + url: "https://pub.dev" + source: hosted + version: "0.3.5" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "48ae73ba8dbf1923de91e0fd65736148f63f6c6fb0925bdda05c1df0298c55e1" + url: "https://pub.dev" + source: hosted + version: "3.7.0" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "6e8086e1d3c2f6bc15056ee248c4ddc48c2bc71287c0961bf801a08633ed4333" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" + source: hosted + version: "2.0.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + graphs: + dependency: transitive + description: + name: graphs + sha256: e84da18c5bd9854f4222e62d762e0ffd290726ffc5785dcb976f8c16ff797f5e + url: "https://pub.dev" + source: hosted + version: "1.0.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + sha256: cb314f00b2488de7bc575207e54402cd2f92363f333a7933fd1b0631af226baa + url: "https://pub.dev" + source: hosted + version: "4.6.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: "0cec7060459254cf1ff980c08dedca6fa50917724a3c3ec8c5026cb88dee8238" + url: "https://pub.dev" + source: hosted + version: "6.3.1" + lints: + dependency: transitive + description: + name: lints + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + logging: + dependency: transitive + description: + name: logging + sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" + source: hosted + version: "0.12.13" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" + source: hosted + version: "1.8.2" + pedantic: + dependency: transitive + description: + name: pedantic + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + plugin_platform_interface: + dependency: "direct main" + description: + name: plugin_platform_interface + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + url: "https://pub.dev" + source: hosted + version: "1.4.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "3e743f02b0916cf719347492bc475f1fc270302c4f650544f16a55e9a463a143" + url: "https://pub.dev" + source: hosted + version: "1.0.5" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "522d9b05c40ec14f479ce4428337d106c0465fedab42f514582c198460a784fe" + url: "https://pub.dev" + source: hosted + version: "1.3.2" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" + source: hosted + version: "0.4.16" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b + url: "https://pub.dev" + source: hosted + version: "2.3.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.dev" + source: hosted + version: "3.1.1" +sdks: + dart: ">=2.19.0 <3.0.0" + flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..6c2ba83 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,77 @@ +name: icdevicemanager_flutter +description: A new Flutter project. +version: 0.0.1 +homepage: + +environment: + sdk: ">=2.17.5 <3.0.0" + flutter: ">=2.5.0" + +dependencies: + flutter: + sdk: flutter + + json_annotation: ^4.6.0 + build_runner: ^1.7.0 + plugin_platform_interface: ^2.0.2 + +dev_dependencies: + change_app_package_name: ^1.0.0 + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + json_serializable: ^6.3.1 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: cn.icomon.icdevicemanager.flutter + pluginClass: ICBluetoothSDKPlugin + ios: + pluginClass: FlutterSwiftPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/test/flutter_swift_method_channel_test.dart b/test/flutter_swift_method_channel_test.dart new file mode 100644 index 0000000..fe61382 --- /dev/null +++ b/test/flutter_swift_method_channel_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter/services.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_method_channel.dart'; +import 'package:flutter_test/flutter_test.dart'; + + +void main() { + MethodChannelIcBluetoothSdk platform = MethodChannelIcBluetoothSdk(); + const MethodChannel channel = MethodChannel('ic_bluetooth_sdk'); + + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) async { + return '42'; + }); + }); + + tearDown(() { + channel.setMockMethodCallHandler(null); + }); + + test('getPlatformVersion', () async { + }); +} diff --git a/test/flutter_swift_test.dart b/test/flutter_swift_test.dart new file mode 100644 index 0000000..e91a9b4 --- /dev/null +++ b/test/flutter_swift_test.dart @@ -0,0 +1,241 @@ +import 'package:icdevicemanager_flutter/callback/ICAddDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICCommonCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICDeviceManagerCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICFatAlgorithmsSettingCallback.dart'; +import 'package:icdevicemanager_flutter/callback/ICRemoveDeviceCallBack.dart'; +import 'package:icdevicemanager_flutter/callback/ICScanDeviceDelegate.dart'; +import 'package:icdevicemanager_flutter/callback/ICSettingCallback.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_method_channel.dart'; +import 'package:icdevicemanager_flutter/ic_bluetooth_sdk_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipLightSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICSkipSoundSettingData.dart'; +import 'package:icdevicemanager_flutter/model/data/ICWeightData.dart'; +import 'package:icdevicemanager_flutter/model/device/ICDevice.dart'; +import 'package:icdevicemanager_flutter/model/device/ICUserInfo.dart'; +import 'package:icdevicemanager_flutter/model/other/ICConstant.dart'; +import 'package:icdevicemanager_flutter/model/other/ICDeviceManagerConfig.dart'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +class MockFlutterSwiftPlatform + with MockPlatformInterfaceMixin + implements IcBluetoothSdkPlatform { + + @override + Future getPlatformVersion() => Future.value('42'); + + @override + void addDevice(ICDevice device, ICAddDeviceCallBack? callBack) { + + } + + @override + void addDevices(List devices, ICAddDeviceCallBack? callback) { + + } + + @override + void changeStName(ICDevice device, String name, ICSettingCallback? callback) { + + } + + @override + void changeStNo(ICDevice device, int dstId, int st_no, ICSettingCallback? callback) { + + } + + @override + void configWifi(ICDevice device, String? ssid, String? password, ICSettingCallback? callback) { + + } + + @override + void deleteTareWeight(ICDevice device, ICSettingCallback? callback) { + + } + + @override + void initSDK(ICDeviceManagerConfig config) { + + } + + @override + void lockStSkip(ICDevice device, ICSettingCallback? callback) { + + } + + @override + void onMethodCall() { + + } + + @override + void powerOffKitchenScale(ICDevice device, ICSettingCallback? callback) { + + } + + @override + void queryStAllNode(ICDevice device, ICSettingCallback? callback) { + + } + + @override + void removeDevice(ICDevice device, ICRemoveDeviceCallBack? callBack) { + + } + + @override + void removeDevices(List devices, ICRemoveDeviceCallBack? callBack) { + + } + + @override + void scanDevice() { + + } + + @override + void setDebugCommand(ICDevice device, Map cmd, ICSettingCallback? callback) { + + } + + @override + void setDeviceManagerDelegate(ICDeviceManagerDelegate? delegate) { + + } + + @override + void setDeviceScanDelegate(ICScanDeviceDelegate? delegate) { + + } + + @override + void setKitchenScaleUnit(ICDevice device, ICKitchenScaleUnit unit, ICSettingCallback? callback) { + + } + + @override + void setNutritionFacts(ICDevice device, ICKitchenScaleNutritionFactType type, int value, ICSettingCallback? callback) { + + } + + @override + void setOtherParams(ICDevice device, int type, Object param, ICSettingCallback? callback) { + + } + + @override + void setRulerBodyPartsType(ICDevice device, ICRulerBodyPartsType type, ICSettingCallback? callback) { + + } + + @override + void setRulerMeasureMode(ICDevice device, ICRulerMeasureMode mode, ICSettingCallback? callback) { + + } + + @override + void setRulerUnit(ICDevice device, ICRulerUnit unit, ICSettingCallback? callback) { + + } + + @override + void setScaleUIItems(ICDevice device, List items, ICSettingCallback? callback) { + + } + + @override + void setScaleUnit(ICDevice device, ICWeightUnit unit, ICSettingCallback? callback) { + + } + + @override + void setServerUrl(ICDevice device, String server, ICSettingCallback? callback) { + + } + + @override + void setSkipLightSetting(ICDevice device, List lightEffects, ICSkipLightMode mode, ICSettingCallback? callback) { + + } + + @override + void setSkipSoundSetting(ICDevice device, ICSkipSoundSettingData config, ICSettingCallback? callback) { + + } + + @override + void setUserInfo(ICDevice device, ICUserInfo userInfo) { + + } + + @override + void setUserList(List list) { + + } + + @override + void setWeight(ICDevice device, int weight, ICSettingCallback? callback) { + + } + + @override + void startSkipMode(ICDevice device, ICSkipMode mode, int param, ICSettingCallback? callback) { + + } + + @override + void stopScan() { + + } + + @override + void stopSkip(ICDevice device, ICSettingCallback? callback) { + + } + + @override + void stopUpgradeDevice(ICDevice device) { + + } + + @override + void stopUpgradeDevices(List devices) { + + } + + @override + void updateUserInfo(ICUserInfo userInfo) { + + } + + @override + void upgradeDevice(ICDevice device, String filePath, ICOTAMode mode) { + + } + + @override + void upgradeDevices(List devices, String filePath, ICOTAMode mode) { + + } + + @override + void reCalcBodyFatWithWeightData(ICWeightData weightData, ICUserInfo userInfo, ICFatAlgorithmsSettingCallback callBack) { + + } + + @override + void getLogPath(ICCommonCallback? callback) { + + } +} + +void main() { + final IcBluetoothSdkPlatform initialPlatform = IcBluetoothSdkPlatform.instance; + + test('$MethodChannelIcBluetoothSdk is the default instance', () { + expect(initialPlatform, isInstanceOf()); + }); + +}