diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..748f1da --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +SIGA_ENDPOINT=https://siga.utem.cl +EXDEV_API_ENDPOINT=https://api.exdev.cl \ No newline at end of file diff --git a/.gitignore b/.gitignore index c01502e..0ea7ca7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # MiUTEM android/app/google-services.json ios/Runner/GoogleService-Info.plist +.env* +!.env.example # Miscellaneous *.class diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..d8e9561 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml new file mode 100644 index 0000000..02b915b --- /dev/null +++ b/.idea/git_toolbox_prj.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..212ae46 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 2451673..59ef89b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -9,7 +9,7 @@ plugins { } android { - namespace = "cl.exdev.miutem" + namespace = "cl.inndev.miutem" compileSdk = 34 ndkVersion = flutter.ndkVersion @@ -24,7 +24,7 @@ android { // AQUI SE TIENE QUE USAR LA CONFIGURACION DEL KEYSTORE QUE TIENE LA APP OFICIAL defaultConfig { - applicationId = "cl.exdev.miutem" + applicationId = "cl.inndev.miutem" minSdk = 23 targetSdk = 34 diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 7c56964..1dc6cf7 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 12.0 + 13.0 diff --git a/ios/Podfile b/ios/Podfile index 74c3caa..e5f5d0b 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '13.0' +platform :ios, '16.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -31,10 +31,6 @@ target 'Runner' do use_frameworks! use_modular_headers! - pod 'FirebaseFirestore', - :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', - :tag => '11.4.0' - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..11abf6f --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,1589 @@ +PODS: + - abseil/algorithm (1.20240722.0): + - abseil/algorithm/algorithm (= 1.20240722.0) + - abseil/algorithm/container (= 1.20240722.0) + - abseil/algorithm/algorithm (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/algorithm/container (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base (1.20240722.0): + - abseil/base/atomic_hook (= 1.20240722.0) + - abseil/base/base (= 1.20240722.0) + - abseil/base/base_internal (= 1.20240722.0) + - abseil/base/config (= 1.20240722.0) + - abseil/base/core_headers (= 1.20240722.0) + - abseil/base/cycleclock_internal (= 1.20240722.0) + - abseil/base/dynamic_annotations (= 1.20240722.0) + - abseil/base/endian (= 1.20240722.0) + - abseil/base/errno_saver (= 1.20240722.0) + - abseil/base/fast_type_id (= 1.20240722.0) + - abseil/base/log_severity (= 1.20240722.0) + - abseil/base/malloc_internal (= 1.20240722.0) + - abseil/base/no_destructor (= 1.20240722.0) + - abseil/base/nullability (= 1.20240722.0) + - abseil/base/poison (= 1.20240722.0) + - abseil/base/prefetch (= 1.20240722.0) + - abseil/base/pretty_function (= 1.20240722.0) + - abseil/base/raw_logging_internal (= 1.20240722.0) + - abseil/base/spinlock_wait (= 1.20240722.0) + - abseil/base/strerror (= 1.20240722.0) + - abseil/base/throw_delegate (= 1.20240722.0) + - abseil/base/atomic_hook (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/base (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/cycleclock_internal + - abseil/base/dynamic_annotations + - abseil/base/log_severity + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/spinlock_wait + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/base_internal (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/config (1.20240722.0): + - abseil/xcprivacy + - abseil/base/core_headers (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/cycleclock_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/xcprivacy + - abseil/base/dynamic_annotations (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/endian (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/xcprivacy + - abseil/base/errno_saver (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/fast_type_id (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/log_severity (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/malloc_internal (1.20240722.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/base/no_destructor (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/xcprivacy + - abseil/base/nullability (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/poison (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal + - abseil/xcprivacy + - abseil/base/prefetch (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/pretty_function (1.20240722.0): + - abseil/xcprivacy + - abseil/base/raw_logging_internal (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/base/log_severity + - abseil/xcprivacy + - abseil/base/spinlock_wait (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/xcprivacy + - abseil/base/strerror (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/xcprivacy + - abseil/base/throw_delegate (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/cleanup/cleanup (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/cleanup/cleanup_internal + - abseil/xcprivacy + - abseil/cleanup/cleanup_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/common (1.20240722.0): + - abseil/meta/type_traits + - abseil/types/optional + - abseil/xcprivacy + - abseil/container/common_policy_traits (1.20240722.0): + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/compressed_tuple (1.20240722.0): + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/container_memory (1.20240722.0): + - abseil/base/config + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/fixed_array (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/throw_delegate + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/xcprivacy + - abseil/container/flat_hash_map (1.20240722.0): + - abseil/algorithm/container + - abseil/base/core_headers + - abseil/container/container_memory + - abseil/container/hash_container_defaults + - abseil/container/raw_hash_map + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/flat_hash_set (1.20240722.0): + - abseil/algorithm/container + - abseil/base/core_headers + - abseil/container/container_memory + - abseil/container/hash_container_defaults + - abseil/container/raw_hash_set + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/hash_container_defaults (1.20240722.0): + - abseil/base/config + - abseil/container/hash_function_defaults + - abseil/xcprivacy + - abseil/container/hash_function_defaults (1.20240722.0): + - abseil/base/config + - abseil/container/common + - abseil/hash/hash + - abseil/meta/type_traits + - abseil/strings/cord + - abseil/strings/strings + - abseil/xcprivacy + - abseil/container/hash_policy_traits (1.20240722.0): + - abseil/container/common_policy_traits + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/hashtable_debug_hooks (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/container/hashtablez_sampler (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/memory/memory + - abseil/profiling/exponential_biased + - abseil/profiling/sample_recorder + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/inlined_vector (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/container/inlined_vector_internal + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/inlined_vector_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/span + - abseil/xcprivacy + - abseil/container/layout (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/demangle_internal + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/types/span + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/raw_hash_map (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/container/container_memory + - abseil/container/raw_hash_set + - abseil/xcprivacy + - abseil/container/raw_hash_set (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/endian + - abseil/base/prefetch + - abseil/base/raw_logging_internal + - abseil/container/common + - abseil/container/compressed_tuple + - abseil/container/container_memory + - abseil/container/hash_policy_traits + - abseil/container/hashtable_debug_hooks + - abseil/container/hashtablez_sampler + - abseil/hash/hash + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/crc/cpu_detect (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/xcprivacy + - abseil/crc/crc32c (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/prefetch + - abseil/crc/cpu_detect + - abseil/crc/crc_internal + - abseil/crc/non_temporal_memcpy + - abseil/strings/str_format + - abseil/strings/strings + - abseil/xcprivacy + - abseil/crc/crc_cord_state (1.20240722.0): + - abseil/base/config + - abseil/base/no_destructor + - abseil/crc/crc32c + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/crc/crc_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/prefetch + - abseil/base/raw_logging_internal + - abseil/crc/cpu_detect + - abseil/memory/memory + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/crc/non_temporal_arm_intrinsics (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/crc/non_temporal_memcpy (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/crc/non_temporal_arm_intrinsics + - abseil/xcprivacy + - abseil/debugging/bounded_utf8_length_sequence (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/debugging/debugging_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/errno_saver + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/debugging/decode_rust_punycode (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/debugging/bounded_utf8_length_sequence + - abseil/debugging/utf8_for_code_point + - abseil/xcprivacy + - abseil/debugging/demangle_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/debugging/demangle_rust + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/debugging/demangle_rust (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/decode_rust_punycode + - abseil/xcprivacy + - abseil/debugging/examine_stack (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/xcprivacy + - abseil/debugging/stacktrace (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/debugging/debugging_internal + - abseil/xcprivacy + - abseil/debugging/symbolize (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/debugging_internal + - abseil/debugging/demangle_internal + - abseil/strings/strings + - abseil/xcprivacy + - abseil/debugging/utf8_for_code_point (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/flags/commandlineflag (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/flags/commandlineflag_internal + - abseil/strings/strings + - abseil/types/optional + - abseil/xcprivacy + - abseil/flags/commandlineflag_internal (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/xcprivacy + - abseil/flags/config (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/path_util + - abseil/flags/program_name + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/flags/flag (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/commandlineflag + - abseil/flags/config + - abseil/flags/flag_internal + - abseil/flags/reflection + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/flag_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/flags/config + - abseil/flags/marshalling + - abseil/flags/reflection + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/utility/utility + - abseil/xcprivacy + - abseil/flags/marshalling (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/numeric/int128 + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/optional + - abseil/xcprivacy + - abseil/flags/path_util (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/private_handle_accessor (1.20240722.0): + - abseil/base/config + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/program_name (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/path_util + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/flags/reflection (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/container/flat_hash_map + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/flags/config + - abseil/flags/private_handle_accessor + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/functional/any_invocable (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/functional/bind_front (1.20240722.0): + - abseil/base/base_internal + - abseil/container/compressed_tuple + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/functional/function_ref (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/functional/any_invocable + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/hash/city (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/xcprivacy + - abseil/hash/hash (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/container/fixed_array + - abseil/functional/function_ref + - abseil/hash/city + - abseil/hash/low_level_hash + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/types/optional + - abseil/types/variant + - abseil/utility/utility + - abseil/xcprivacy + - abseil/hash/low_level_hash (1.20240722.0): + - abseil/base/config + - abseil/base/endian + - abseil/base/prefetch + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/log/absl_check (1.20240722.0): + - abseil/log/internal/check_impl + - abseil/xcprivacy + - abseil/log/absl_log (1.20240722.0): + - abseil/log/internal/log_impl + - abseil/xcprivacy + - abseil/log/absl_vlog_is_on (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/vlog_config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/check (1.20240722.0): + - abseil/log/internal/check_impl + - abseil/log/internal/check_op + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/globals (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/hash/hash + - abseil/log/internal/vlog_config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/append_truncated (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/check_impl (1.20240722.0): + - abseil/base/core_headers + - abseil/log/internal/check_op + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/internal/check_op (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/nullguard + - abseil/log/internal/nullstream + - abseil/log/internal/strip + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/conditions (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/voidify + - abseil/xcprivacy + - abseil/log/internal/config (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/log/internal/fnmatch (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/format (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/append_truncated + - abseil/log/internal/config + - abseil/log/internal/globals + - abseil/strings/str_format + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/globals (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/strings/strings + - abseil/time/time + - abseil/xcprivacy + - abseil/log/internal/log_impl (1.20240722.0): + - abseil/log/absl_vlog_is_on + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/internal/log_message (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/base/strerror + - abseil/container/inlined_vector + - abseil/debugging/examine_stack + - abseil/log/globals + - abseil/log/internal/append_truncated + - abseil/log/internal/format + - abseil/log/internal/globals + - abseil/log/internal/log_sink_set + - abseil/log/internal/nullguard + - abseil/log/internal/proto + - abseil/log/log_entry + - abseil/log/log_sink + - abseil/log/log_sink_registry + - abseil/memory/memory + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/log_sink_set (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/cleanup/cleanup + - abseil/log/globals + - abseil/log/internal/config + - abseil/log/internal/globals + - abseil/log/log_entry + - abseil/log/log_sink + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/nullguard (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/log/internal/nullstream (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/proto (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/strip (1.20240722.0): + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/log_message + - abseil/log/internal/nullstream + - abseil/xcprivacy + - abseil/log/internal/vlog_config (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/log/internal/fnmatch + - abseil/memory/memory + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/types/optional + - abseil/xcprivacy + - abseil/log/internal/voidify (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/log/log (1.20240722.0): + - abseil/log/internal/log_impl + - abseil/log/vlog_is_on + - abseil/xcprivacy + - abseil/log/log_entry (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/config + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/log_sink (1.20240722.0): + - abseil/base/config + - abseil/log/log_entry + - abseil/xcprivacy + - abseil/log/log_sink_registry (1.20240722.0): + - abseil/base/config + - abseil/log/internal/log_sink_set + - abseil/log/log_sink + - abseil/xcprivacy + - abseil/log/vlog_is_on (1.20240722.0): + - abseil/log/absl_vlog_is_on + - abseil/xcprivacy + - abseil/memory (1.20240722.0): + - abseil/memory/memory (= 1.20240722.0) + - abseil/memory/memory (1.20240722.0): + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/meta (1.20240722.0): + - abseil/meta/type_traits (= 1.20240722.0) + - abseil/meta/type_traits (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/numeric/bits (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/numeric/int128 (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/numeric/bits + - abseil/types/compare + - abseil/xcprivacy + - abseil/numeric/representation (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/profiling/exponential_biased (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/profiling/sample_recorder (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/xcprivacy + - abseil/random/bit_gen_ref (1.20240722.0): + - abseil/base/core_headers + - abseil/base/fast_type_id + - abseil/meta/type_traits + - abseil/random/internal/distribution_caller + - abseil/random/internal/fast_uniform_bits + - abseil/random/random + - abseil/xcprivacy + - abseil/random/distributions (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/random/internal/distribution_caller + - abseil/random/internal/fast_uniform_bits + - abseil/random/internal/fastmath + - abseil/random/internal/generate_real + - abseil/random/internal/iostream_state_saver + - abseil/random/internal/traits + - abseil/random/internal/uniform_helper + - abseil/random/internal/wide_multiply + - abseil/strings/strings + - abseil/xcprivacy + - abseil/random/internal/distribution_caller (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/utility/utility + - abseil/xcprivacy + - abseil/random/internal/fast_uniform_bits (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/fastmath (1.20240722.0): + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/random/internal/generate_real (1.20240722.0): + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/random/internal/fastmath + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/iostream_state_saver (1.20240722.0): + - abseil/meta/type_traits + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/random/internal/nonsecure_base (1.20240722.0): + - abseil/base/core_headers + - abseil/container/inlined_vector + - abseil/meta/type_traits + - abseil/random/internal/pool_urbg + - abseil/random/internal/salted_seed_seq + - abseil/random/internal/seed_material + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/pcg_engine (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/random/internal/fastmath + - abseil/random/internal/iostream_state_saver + - abseil/xcprivacy + - abseil/random/internal/platform (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/random/internal/pool_urbg (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/random/internal/randen + - abseil/random/internal/seed_material + - abseil/random/internal/traits + - abseil/random/seed_gen_exception + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/randen (1.20240722.0): + - abseil/base/raw_logging_internal + - abseil/random/internal/platform + - abseil/random/internal/randen_hwaes + - abseil/random/internal/randen_slow + - abseil/xcprivacy + - abseil/random/internal/randen_engine (1.20240722.0): + - abseil/base/endian + - abseil/meta/type_traits + - abseil/random/internal/iostream_state_saver + - abseil/random/internal/randen + - abseil/xcprivacy + - abseil/random/internal/randen_hwaes (1.20240722.0): + - abseil/base/config + - abseil/random/internal/platform + - abseil/random/internal/randen_hwaes_impl + - abseil/xcprivacy + - abseil/random/internal/randen_hwaes_impl (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/numeric/int128 + - abseil/random/internal/platform + - abseil/xcprivacy + - abseil/random/internal/randen_slow (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/numeric/int128 + - abseil/random/internal/platform + - abseil/xcprivacy + - abseil/random/internal/salted_seed_seq (1.20240722.0): + - abseil/container/inlined_vector + - abseil/meta/type_traits + - abseil/random/internal/seed_material + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/seed_material (1.20240722.0): + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/random/internal/fast_uniform_bits + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/traits (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/random/internal/uniform_helper (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/wide_multiply (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/random (1.20240722.0): + - abseil/random/distributions + - abseil/random/internal/nonsecure_base + - abseil/random/internal/pcg_engine + - abseil/random/internal/pool_urbg + - abseil/random/internal/randen_engine + - abseil/random/seed_sequences + - abseil/xcprivacy + - abseil/random/seed_gen_exception (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/random/seed_sequences (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/random/internal/pool_urbg + - abseil/random/internal/salted_seed_seq + - abseil/random/internal/seed_material + - abseil/random/seed_gen_exception + - abseil/strings/string_view + - abseil/types/span + - abseil/xcprivacy + - abseil/status/status (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/strerror + - abseil/container/inlined_vector + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/functional/function_ref + - abseil/memory/memory + - abseil/strings/cord + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/status/statusor (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/meta/type_traits + - abseil/status/status + - abseil/strings/has_ostream_operator + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/variant + - abseil/utility/utility + - abseil/xcprivacy + - abseil/strings/charset (1.20240722.0): + - abseil/base/core_headers + - abseil/strings/string_view + - abseil/xcprivacy + - abseil/strings/cord (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/container/inlined_vector + - abseil/crc/crc32c + - abseil/crc/crc_cord_state + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/strings/cord_internal + - abseil/strings/cordz_functions + - abseil/strings/cordz_info + - abseil/strings/cordz_statistics + - abseil/strings/cordz_update_scope + - abseil/strings/cordz_update_tracker + - abseil/strings/internal + - abseil/strings/strings + - abseil/types/compare + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cord_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/base/throw_delegate + - abseil/container/compressed_tuple + - abseil/container/container_memory + - abseil/container/inlined_vector + - abseil/container/layout + - abseil/crc/crc_cord_state + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cordz_functions (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/profiling/exponential_biased + - abseil/xcprivacy + - abseil/strings/cordz_handle (1.20240722.0): + - abseil/base/config + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/strings/cordz_info (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/container/inlined_vector + - abseil/debugging/stacktrace + - abseil/strings/cord_internal + - abseil/strings/cordz_functions + - abseil/strings/cordz_handle + - abseil/strings/cordz_statistics + - abseil/strings/cordz_update_tracker + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cordz_statistics (1.20240722.0): + - abseil/base/config + - abseil/strings/cordz_update_tracker + - abseil/xcprivacy + - abseil/strings/cordz_update_scope (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/strings/cord_internal + - abseil/strings/cordz_info + - abseil/strings/cordz_update_tracker + - abseil/xcprivacy + - abseil/strings/cordz_update_tracker (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/strings/has_ostream_operator (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/strings/internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/strings/str_format (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/strings/str_format_internal + - abseil/strings/string_view + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/str_format_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/container/fixed_array + - abseil/container/inlined_vector + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/numeric/representation + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/utility/utility + - abseil/xcprivacy + - abseil/strings/string_view (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/throw_delegate + - abseil/xcprivacy + - abseil/strings/strings (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/throw_delegate + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/strings/charset + - abseil/strings/internal + - abseil/strings/string_view + - abseil/xcprivacy + - abseil/synchronization/graphcycles_internal (1.20240722.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/synchronization/kernel_timeout_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/time/time + - abseil/xcprivacy + - abseil/synchronization/synchronization (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/synchronization/graphcycles_internal + - abseil/synchronization/kernel_timeout_internal + - abseil/time/time + - abseil/xcprivacy + - abseil/time (1.20240722.0): + - abseil/time/internal (= 1.20240722.0) + - abseil/time/time (= 1.20240722.0) + - abseil/time/internal (1.20240722.0): + - abseil/time/internal/cctz (= 1.20240722.0) + - abseil/time/internal/cctz (1.20240722.0): + - abseil/time/internal/cctz/civil_time (= 1.20240722.0) + - abseil/time/internal/cctz/time_zone (= 1.20240722.0) + - abseil/time/internal/cctz/civil_time (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/time/internal/cctz/time_zone (1.20240722.0): + - abseil/base/config + - abseil/time/internal/cctz/civil_time + - abseil/xcprivacy + - abseil/time/time (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/time/internal/cctz/civil_time + - abseil/time/internal/cctz/time_zone + - abseil/types/optional + - abseil/xcprivacy + - abseil/types (1.20240722.0): + - abseil/types/any (= 1.20240722.0) + - abseil/types/bad_any_cast (= 1.20240722.0) + - abseil/types/bad_any_cast_impl (= 1.20240722.0) + - abseil/types/bad_optional_access (= 1.20240722.0) + - abseil/types/bad_variant_access (= 1.20240722.0) + - abseil/types/compare (= 1.20240722.0) + - abseil/types/optional (= 1.20240722.0) + - abseil/types/span (= 1.20240722.0) + - abseil/types/variant (= 1.20240722.0) + - abseil/types/any (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/fast_type_id + - abseil/meta/type_traits + - abseil/types/bad_any_cast + - abseil/utility/utility + - abseil/xcprivacy + - abseil/types/bad_any_cast (1.20240722.0): + - abseil/base/config + - abseil/types/bad_any_cast_impl + - abseil/xcprivacy + - abseil/types/bad_any_cast_impl (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/bad_optional_access (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/bad_variant_access (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/compare (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/types/optional (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/bad_optional_access + - abseil/utility/utility + - abseil/xcprivacy + - abseil/types/span (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/throw_delegate + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/types/variant (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/types/bad_variant_access + - abseil/utility/utility + - abseil/xcprivacy + - abseil/utility/utility (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/xcprivacy (1.20240722.0) + - awesome_notifications (0.10.0): + - Flutter + - IosAwnCore (~> 0.10.0) + - awesome_notifications_core (0.0.1): + - Flutter + - BoringSSL-GRPC (0.0.37): + - BoringSSL-GRPC/Implementation (= 0.0.37) + - BoringSSL-GRPC/Interface (= 0.0.37) + - BoringSSL-GRPC/Implementation (0.0.37): + - BoringSSL-GRPC/Interface (= 0.0.37) + - BoringSSL-GRPC/Interface (0.0.37) + - cloud_firestore (6.1.2): + - Firebase/Firestore (= 12.8.0) + - firebase_core + - Flutter + - file_saver (0.0.1): + - Flutter + - Firebase/CoreOnly (12.8.0): + - FirebaseCore (~> 12.8.0) + - Firebase/Firestore (12.8.0): + - Firebase/CoreOnly + - FirebaseFirestore (~> 12.8.0) + - Firebase/RemoteConfig (12.8.0): + - Firebase/CoreOnly + - FirebaseRemoteConfig (~> 12.8.0) + - firebase_analytics (12.1.2): + - firebase_core + - FirebaseAnalytics (= 12.8.0) + - Flutter + - firebase_core (4.4.0): + - Firebase/CoreOnly (= 12.8.0) + - Flutter + - firebase_remote_config (6.1.4): + - Firebase/RemoteConfig (= 12.8.0) + - firebase_core + - Flutter + - FirebaseABTesting (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseAnalytics (12.8.0): + - FirebaseAnalytics/Default (= 12.8.0) + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - GoogleAppMeasurement/Default (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppCheckInterop (12.8.0) + - FirebaseCore (12.8.0): + - FirebaseCoreInternal (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseCoreInternal (12.8.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseFirestore (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseCoreExtension (~> 12.8.0) + - FirebaseFirestoreInternal (~> 12.8.0) + - FirebaseSharedSwift (~> 12.8.0) + - FirebaseFirestoreInternal (12.8.0): + - abseil/algorithm (~> 1.20240722.0) + - abseil/base (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/memory (~> 1.20240722.0) + - abseil/meta (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/time (~> 1.20240722.0) + - abseil/types (~> 1.20240722.0) + - FirebaseAppCheckInterop (~> 12.8.0) + - FirebaseCore (~> 12.8.0) + - "gRPC-C++ (~> 1.69.0)" + - gRPC-Core (~> 1.69.0) + - leveldb-library (~> 1.22) + - nanopb (~> 3.30910.0) + - FirebaseInstallations (12.8.0): + - FirebaseCore (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (12.8.0): + - FirebaseABTesting (~> 12.8.0) + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - FirebaseRemoteConfigInterop (~> 12.8.0) + - FirebaseSharedSwift (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.8.0) + - FirebaseSharedSwift (12.8.0) + - Flutter (1.0.0) + - flutter_native_splash (2.4.3): + - Flutter + - flutter_secure_storage (6.0.0): + - Flutter + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.8.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.8.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.8.0) + - GoogleAppMeasurement/IdentitySupport (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.8.0): + - GoogleAppMeasurement/Core (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - "gRPC-C++ (1.69.0)": + - "gRPC-C++/Implementation (= 1.69.0)" + - "gRPC-C++/Interface (= 1.69.0)" + - "gRPC-C++/Implementation (1.69.0)": + - abseil/algorithm/container (~> 1.20240722.0) + - abseil/base/base (~> 1.20240722.0) + - abseil/base/config (~> 1.20240722.0) + - abseil/base/core_headers (~> 1.20240722.0) + - abseil/base/log_severity (~> 1.20240722.0) + - abseil/base/no_destructor (~> 1.20240722.0) + - abseil/cleanup/cleanup (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/container/flat_hash_set (~> 1.20240722.0) + - abseil/container/inlined_vector (~> 1.20240722.0) + - abseil/flags/flag (~> 1.20240722.0) + - abseil/flags/marshalling (~> 1.20240722.0) + - abseil/functional/any_invocable (~> 1.20240722.0) + - abseil/functional/bind_front (~> 1.20240722.0) + - abseil/functional/function_ref (~> 1.20240722.0) + - abseil/hash/hash (~> 1.20240722.0) + - abseil/log/absl_check (~> 1.20240722.0) + - abseil/log/absl_log (~> 1.20240722.0) + - abseil/log/check (~> 1.20240722.0) + - abseil/log/globals (~> 1.20240722.0) + - abseil/log/log (~> 1.20240722.0) + - abseil/memory/memory (~> 1.20240722.0) + - abseil/meta/type_traits (~> 1.20240722.0) + - abseil/numeric/bits (~> 1.20240722.0) + - abseil/random/bit_gen_ref (~> 1.20240722.0) + - abseil/random/distributions (~> 1.20240722.0) + - abseil/random/random (~> 1.20240722.0) + - abseil/status/status (~> 1.20240722.0) + - abseil/status/statusor (~> 1.20240722.0) + - abseil/strings/cord (~> 1.20240722.0) + - abseil/strings/str_format (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/synchronization/synchronization (~> 1.20240722.0) + - abseil/time/time (~> 1.20240722.0) + - abseil/types/optional (~> 1.20240722.0) + - abseil/types/span (~> 1.20240722.0) + - abseil/types/variant (~> 1.20240722.0) + - abseil/utility/utility (~> 1.20240722.0) + - "gRPC-C++/Interface (= 1.69.0)" + - "gRPC-C++/Privacy (= 1.69.0)" + - gRPC-Core (= 1.69.0) + - "gRPC-C++/Interface (1.69.0)" + - "gRPC-C++/Privacy (1.69.0)" + - gRPC-Core (1.69.0): + - gRPC-Core/Implementation (= 1.69.0) + - gRPC-Core/Interface (= 1.69.0) + - gRPC-Core/Implementation (1.69.0): + - abseil/algorithm/container (~> 1.20240722.0) + - abseil/base/base (~> 1.20240722.0) + - abseil/base/config (~> 1.20240722.0) + - abseil/base/core_headers (~> 1.20240722.0) + - abseil/base/log_severity (~> 1.20240722.0) + - abseil/base/no_destructor (~> 1.20240722.0) + - abseil/cleanup/cleanup (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/container/flat_hash_set (~> 1.20240722.0) + - abseil/container/inlined_vector (~> 1.20240722.0) + - abseil/flags/flag (~> 1.20240722.0) + - abseil/flags/marshalling (~> 1.20240722.0) + - abseil/functional/any_invocable (~> 1.20240722.0) + - abseil/functional/bind_front (~> 1.20240722.0) + - abseil/functional/function_ref (~> 1.20240722.0) + - abseil/hash/hash (~> 1.20240722.0) + - abseil/log/check (~> 1.20240722.0) + - abseil/log/globals (~> 1.20240722.0) + - abseil/log/log (~> 1.20240722.0) + - abseil/memory/memory (~> 1.20240722.0) + - abseil/meta/type_traits (~> 1.20240722.0) + - abseil/numeric/bits (~> 1.20240722.0) + - abseil/random/bit_gen_ref (~> 1.20240722.0) + - abseil/random/distributions (~> 1.20240722.0) + - abseil/random/random (~> 1.20240722.0) + - abseil/status/status (~> 1.20240722.0) + - abseil/status/statusor (~> 1.20240722.0) + - abseil/strings/cord (~> 1.20240722.0) + - abseil/strings/str_format (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/synchronization/synchronization (~> 1.20240722.0) + - abseil/time/time (~> 1.20240722.0) + - abseil/types/optional (~> 1.20240722.0) + - abseil/types/span (~> 1.20240722.0) + - abseil/types/variant (~> 1.20240722.0) + - abseil/utility/utility (~> 1.20240722.0) + - BoringSSL-GRPC (= 0.0.37) + - gRPC-Core/Interface (= 1.69.0) + - gRPC-Core/Privacy (= 1.69.0) + - gRPC-Core/Interface (1.69.0) + - gRPC-Core/Privacy (1.69.0) + - IosAwnCore (0.10.0) + - leveldb-library (1.22.6) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - package_info_plus (0.4.5): + - Flutter + - PromisesObjC (2.4.0) + - share_plus (0.0.1): + - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS + - url_launcher_ios (0.0.1): + - Flutter + - video_player_avfoundation (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`) + - awesome_notifications_core (from `.symlinks/plugins/awesome_notifications_core/ios`) + - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) + - file_saver (from `.symlinks/plugins/file_saver/ios`) + - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`) + - Flutter (from `Flutter`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) + +SPEC REPOS: + trunk: + - abseil + - BoringSSL-GRPC + - Firebase + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseFirestore + - FirebaseFirestoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - "gRPC-C++" + - gRPC-Core + - IosAwnCore + - leveldb-library + - nanopb + - PromisesObjC + +EXTERNAL SOURCES: + awesome_notifications: + :path: ".symlinks/plugins/awesome_notifications/ios" + awesome_notifications_core: + :path: ".symlinks/plugins/awesome_notifications_core/ios" + cloud_firestore: + :path: ".symlinks/plugins/cloud_firestore/ios" + file_saver: + :path: ".symlinks/plugins/file_saver/ios" + firebase_analytics: + :path: ".symlinks/plugins/firebase_analytics/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_remote_config: + :path: ".symlinks/plugins/firebase_remote_config/ios" + Flutter: + :path: Flutter + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" + flutter_secure_storage: + :path: ".symlinks/plugins/flutter_secure_storage/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sqflite_darwin: + :path: ".symlinks/plugins/sqflite_darwin/darwin" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + video_player_avfoundation: + :path: ".symlinks/plugins/video_player_avfoundation/darwin" + +SPEC CHECKSUMS: + abseil: a05cc83bf02079535e17169a73c5be5ba47f714b + awesome_notifications: 0f432b28098d193920b11a44cfa9d2d9313a3888 + awesome_notifications_core: 429c28df8746780a474de177e5acde33af87da63 + BoringSSL-GRPC: dded2a44897e45f28f08ae87a55ee4bcd19bc508 + cloud_firestore: 4bd00c3464706d9e09dabac0bb8e9610456109f5 + file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6 + Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d + firebase_analytics: a3285a9ab410456957496cdb659f00c1cf19a95f + firebase_core: ee30637e6744af8e0c12a6a1e8a9718506ec2398 + firebase_remote_config: 3a5639062e130c4d4b7c4bae347cc3bac90f5a1e + FirebaseABTesting: 31266c7845f9adde0f2e8a59267e9c82e4050898 + FirebaseAnalytics: f20bbad8cb7f65d8a5eaefeb424ae8800a31bdfc + FirebaseAppCheckInterop: ba3dc604a89815379e61ec2365101608d365cf7d + FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c + FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2 + FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21 + FirebaseFirestore: 67f23000ca238ccbab79127ed59636a9a2689e74 + FirebaseFirestoreInternal: a0e7382af3d208898dcd1d4d52d8a7870632e881 + FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0 + FirebaseRemoteConfig: e9e3909162a05bc0e796326255fd43250783a2a9 + FirebaseRemoteConfigInterop: 869ddca16614f979e5c931ece11fbb0b8729ed41 + FirebaseSharedSwift: f57ed48f4542b2d7eb4738f4f23ba443f78b3780 + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf + flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 72c9a682fec6290327ea5e3c4b829b247fcb2c17 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + "gRPC-C++": cc207623316fb041a7a3e774c252cf68a058b9e8 + gRPC-Core: 860978b7db482de8b4f5e10677216309b5ff6330 + IosAwnCore: 653786a911089012092ce831f2945cd339855a89 + leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a + +PODFILE CHECKSUM: f977ce8683a6959e3ca3adeb5684867ade520617 + +COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 25b4ecc..9e3a02c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -202,7 +202,6 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 8BD6B19860638C874518D2B3 /* [CP] Embed Pods Frameworks */, - C33FEF1B88310600974EB117 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -367,23 +366,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - C33FEF1B88310600974EB117 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -477,7 +459,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -609,7 +591,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -660,7 +642,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 15cada4..e3773d4 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> (json['profesor'] ?? json['docente'], (String? docente) { - final partes = (docente ?? '').split("-").map((it) => it.trim()); - if(partes.isEmpty) { + if(docente == null || docente.isEmpty) { return null; } - if(partes.length == 1) { + final partes = docente.split(RegExp(r'\s*-\s*')).map((it) => it.trim()).toList(); + if(partes.length <= 1) { return Persona(nombreCompleto: capitalize(partes.first)); } diff --git a/lib/core/models/asignaturas/asignatura_malla.dart b/lib/core/models/asignaturas/asignatura_malla.dart index 1567aab..1ed95dd 100644 --- a/lib/core/models/asignaturas/asignatura_malla.dart +++ b/lib/core/models/asignaturas/asignatura_malla.dart @@ -13,6 +13,19 @@ class AsignaturaMalla { required this.nota, }); + factory AsignaturaMalla.fromJson(Map json) => AsignaturaMalla( + nivel: json['nivel'] as int, + intentos: json['intentos'] as int, + nombre: json['nombre'] as String, + tipo: json['tipo'] as String, + estado: json['estado'] as String, + nota: json['nota'] as String, + ); + + static List fromJsonList(dynamic json) => json != null + ? (json as List).map((it) => AsignaturaMalla.fromJson(it as Map)).toList() + : []; + toJson() => { 'nivel': nivel, 'intentos': intentos, diff --git a/lib/core/models/horario.dart b/lib/core/models/horario.dart index 645ec5a..b5f2a83 100644 --- a/lib/core/models/horario.dart +++ b/lib/core/models/horario.dart @@ -167,4 +167,10 @@ class BloqueHorario { ) : BloqueHorario(); static List>? fromJsonMatrix(dynamic json) => json == null ? null : (json as List? ?? []).map((bloque) => (bloque as List? ?? []).map((dia) => BloqueHorario.fromJson(dia)).toList()).toList(); + + toJson() => { + 'asignatura': asignatura?.toJson(), + 'sala': sala, + 'codigo': codigo, + }; } diff --git a/lib/core/models/navigation/navigation_item.dart b/lib/core/models/navigation/navigation_item.dart index 03bd242..879ef68 100644 --- a/lib/core/models/navigation/navigation_item.dart +++ b/lib/core/models/navigation/navigation_item.dart @@ -4,7 +4,8 @@ class NavigationItem { final Widget destination; final String label; + final String featureFlag; final IconData icon; - NavigationItem({required this.destination, required this.label, required this.icon}); + NavigationItem({required this.destination, required this.label, required this.featureFlag, required this.icon}); } \ No newline at end of file diff --git a/lib/core/models/tokenized_object.dart b/lib/core/models/tokenized_object.dart index 5a3c713..c635435 100644 --- a/lib/core/models/tokenized_object.dart +++ b/lib/core/models/tokenized_object.dart @@ -3,6 +3,7 @@ import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; mixin TokenizedObject { String get token; + bool get ignoreTokenExpiration; JWT? decodeToken() => JWT.tryDecode(token); diff --git a/lib/core/models/user/estudiante.dart b/lib/core/models/user/estudiante.dart index 156b873..173f1be 100644 --- a/lib/core/models/user/estudiante.dart +++ b/lib/core/models/user/estudiante.dart @@ -10,6 +10,9 @@ class Estudiante extends PersonaUtem with TokenizedObject { @override final String token; + @override + final bool ignoreTokenExpiration; + final String correoPersonal; final List perfiles; @@ -21,6 +24,7 @@ class Estudiante extends PersonaUtem with TokenizedObject { required this.correoPersonal, required super.fotoUrl, required this.perfiles, + this.ignoreTokenExpiration = false, }); factory Estudiante.fromJson(Map json) { @@ -34,6 +38,7 @@ class Estudiante extends PersonaUtem with TokenizedObject { correoUtem: datosPersona['correo_utem'], fotoUrl: datosPersona['foto'], perfiles: Perfil.values.where((perfil) => (datosPersona['perfiles'] as List).map((perfil) => (perfil as String).toLowerCase()).contains(perfil.name)).toList(), + ignoreTokenExpiration: json['ignore_token_expiration'] ?? false, ); } diff --git a/lib/core/services/controllers/horario_controller.dart b/lib/core/services/controllers/horario_controller.dart index 0761bb0..6cc786d 100644 --- a/lib/core/services/controllers/horario_controller.dart +++ b/lib/core/services/controllers/horario_controller.dart @@ -11,7 +11,51 @@ import 'package:vector_math/vector_math_64.dart' as vector; class HorarioController { final _storage = GetStorage(); - final _randomColors = Colors.primaries.toList()..shuffle(); + + /// Lista de colores pastel de Material Design para las tarjetas de clases + static final List _pastelColors = [ + // Material 100 + const Color(0xFFB3E5FC), // Light Blue 100 + const Color(0xFFC8E6C9), // Green 100 + const Color(0xFFF8BBD9), // Pink 100 + const Color(0xFFFFE0B2), // Orange 100 + const Color(0xFFD1C4E9), // Deep Purple 100 + const Color(0xFFB2EBF2), // Cyan 100 + const Color(0xFFFFF9C4), // Yellow 100 + const Color(0xFFFFCCBC), // Deep Orange 100 + const Color(0xFFC5CAE9), // Indigo 100 + const Color(0xFFDCEDC8), // Light Green 100 + const Color(0xFFF0F4C3), // Lime 100 + const Color(0xFFE1BEE7), // Purple 100 + // Material 200 + const Color(0xFFFFE082), // Amber 200 + const Color(0xFF80DEEA), // Cyan 200 + const Color(0xFFCE93D8), // Purple 200 + const Color(0xFFA5D6A7), // Green 200 + const Color(0xFFEF9A9A), // Red 200 + const Color(0xFF90CAF9), // Blue 200 + const Color(0xFFBCAAA4), // Brown 200 + const Color(0xFFB0BEC5), // Blue Grey 200 + // Material 50 (más claros) + const Color(0xFFE3F2FD), // Blue 50 + const Color(0xFFE8F5E9), // Green 50 + const Color(0xFFFCE4EC), // Pink 50 + const Color(0xFFFFF3E0), // Orange 50 + const Color(0xFFEDE7F6), // Deep Purple 50 + const Color(0xFFE0F7FA), // Cyan 50 + const Color(0xFFFFFDE7), // Yellow 50 + const Color(0xFFFBE9E7), // Deep Orange 50 + // Material 300 (un poco más saturados) + const Color(0xFF81D4FA), // Light Blue 300 + const Color(0xFFF48FB1), // Pink 300 + const Color(0xFFFFB74D), // Orange 300 + const Color(0xFFB39DDB), // Deep Purple 300 + const Color(0xFF4DD0E1), // Cyan 300 + const Color(0xFFAED581), // Light Green 300 + const Color(0xFFBA68C8), // Purple 300 + ]; + + final _randomColors = List.from(_pastelColors)..shuffle(); final _now = DateTime.now(); num daysCount = 6; @@ -90,7 +134,7 @@ class HorarioController { final newColor = color ?? unusedColors.first; final key = '${asignatura.codigo}_${asignatura.tipoHora}'; usedColors.add(newColor); - _storage.write(key, newColor.value); + _storage.write(key, newColor.toARGB32()); } Color? getColor(Asignatura? asignatura){ @@ -98,6 +142,29 @@ class HorarioController { return let(_storage.read('${asignatura.codigo}_${asignatura.tipoHora}'), (dynamic element)=> Color(element)); } + /// Obtiene el color de fondo y el color de texto con contraste para una asignatura + ({Color background, Color text})? getColorWithContrast(Asignatura? asignatura) { + final backgroundColor = getColor(asignatura); + if (backgroundColor == null) return null; + return (background: backgroundColor, text: _getContrastTextColor(backgroundColor)); + } + + /// Calcula el color de texto ideal (claro u oscuro) para un color de fondo dado + /// usando el algoritmo de luminancia relativa de WCAG + static Color _getContrastTextColor(Color backgroundColor) { + // Calcular luminancia relativa según WCAG 2.0 + final double luminance = backgroundColor.computeLuminance(); + + // Si el fondo es claro (luminancia > 0.5), usar texto oscuro + // Si el fondo es oscuro, usar texto claro + // Usamos 0.5 como umbral pero ajustado a 0.45 para mejor contraste en colores pastel + if (luminance > 0.45) { + return const Color(0xFF1A1A1A); // Gris muy oscuro para mejor legibilidad + } else { + return const Color(0xFFFFFFFF); // Blanco + } + } + /// /// Funciones para mover dentro del horario /// diff --git a/lib/core/services/mi_utem/miutem_malla_service.dart b/lib/core/services/mi_utem/miutem_malla_service.dart index c651141..76b1465 100644 --- a/lib/core/services/mi_utem/miutem_malla_service.dart +++ b/lib/core/services/mi_utem/miutem_malla_service.dart @@ -1,47 +1,52 @@ -import 'package:dio/dio.dart'; import 'package:get/get.dart'; import 'package:html/parser.dart' show parse; import 'package:miutem/core/models/asignaturas/asignatura_malla.dart'; import 'package:miutem/core/models/exceptions/custom_exception.dart'; import 'package:miutem/core/services/mi_utem/miutem_auth_service.dart'; -import 'package:miutem/core/utils/http/http_client.dart'; +import 'package:miutem/core/utils/constants.dart'; +import 'package:miutem/core/utils/http/functions.dart'; import 'package:miutem/core/utils/utils.dart'; class MiUTEMMallaService { - static MiUTEMMallaService get get => Get.find(); - Future> getMalla() async { + /// Obtiene la malla, usando caché si está disponible y no ha expirado. + /// [forceRefresh] fuerza una actualización desde el servidor. + Future> getMalla({bool forceRefresh = false}) async { final cookie = await MiUTEMAuthService.get.login(); - final response = await HttpClient.httpClient.get("$miUtemHost/academicos/mi-malla", - options: Options( - headers: { - 'Cookie': cookie, - 'User-Agent': genericUserAgent, - } - ) + final response = await httpClientRequest("$miUtemHost/academicos/mi-malla", + forceRefresh: forceRefresh, + headers: { + 'Cookie': cookie ?? '', + 'User-Agent': genericUserAgent, + }, ); final html = "${response.data}"; - if(!html.contains("La información proporcionada en el módulo debe ser validada por la Dirección General de Docencia.")) { + if (!html.contains("La información proporcionada en el módulo debe ser validada por la Dirección General de Docencia.")) { throw CustomException(message: "No se pudo obtener la malla. Por favor intenta más tarde.", internalCode: 1); } final htmlDoc = parse(html).documentElement; - if(htmlDoc == null) { + if (htmlDoc == null) { throw CustomException(message: "No se pudo obtener la malla. Por favor intenta más tarde.", internalCode: 2); } - return (htmlDoc.querySelectorAll("div[id=collapseTwo][class*=show] > div > div > div > #table-avance").first).querySelectorAll("table > tbody > tr").map((it) { + return (htmlDoc.querySelectorAll("#avance-malla").first.querySelectorAll("#table-avance").first).querySelectorAll("tbody > tr").map((it) { final parts = it.children; + var nota = parts[5].text.trim(); + if (nota.isEmpty) { + nota = "-"; + } + return AsignaturaMalla( nivel: int.tryParse(parts[0].text.trim()) ?? 0, nombre: parts[1].text.trim(), tipo: parts[2].text.trim(), intentos: int.tryParse(parts[3].text.trim()) ?? 0, estado: parts[4].text.trim(), - nota: parts[5].text.trim(), + nota: nota, ); }).toList(); } -} \ No newline at end of file +} diff --git a/lib/core/services/service_manager.dart b/lib/core/services/service_manager.dart index 47a78ca..048eddc 100644 --- a/lib/core/services/service_manager.dart +++ b/lib/core/services/service_manager.dart @@ -19,7 +19,10 @@ import 'package:miutem/core/services/controllers/horario_controller.dart'; /// Inicializa los servicios y los registra en GetX Future initServices() async { // Inicializar Firebase - await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + name: 'miutem-app', + ); Get.lazyPut(() => RemoteConfigService()); await Get.find().initialize(); diff --git a/lib/core/utils/constants.dart b/lib/core/utils/constants.dart index 1b0c2d5..7d0b06c 100644 --- a/lib/core/utils/constants.dart +++ b/lib/core/utils/constants.dart @@ -5,10 +5,10 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; -final apiUrl = !kDebugMode ? 'https://api.exdev.cl' : (dotenv.env['MI_UTEM_API_DEBUG'] ?? 'https://api.exdev.cl'); -const sigaHost = 'https://siga.utem.cl'; +final apiUrl = dotenv.env['EXDEV_API_ENDPOINT'] ?? 'https://api.exdev.cl'; +final sigaHost = dotenv.env['SIGA_ENDPOINT'] ?? 'https://siga.utem.cl'; const miUtemHost = 'https://mi.utem.cl'; -const sigaServiceUri = '$sigaHost/servicios'; // UTEM SIGA API URL +final sigaServiceUri = '$sigaHost/servicios'; // UTEM SIGA API URL const genericUserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15'; diff --git a/lib/core/utils/horario_data.dart b/lib/core/utils/horario_data.dart new file mode 100644 index 0000000..4d73465 --- /dev/null +++ b/lib/core/utils/horario_data.dart @@ -0,0 +1,74 @@ +const List diasHorario = [ + 'Lunes', + 'Martes', + 'Miércoles', + 'Jueves', + 'Viernes', + 'Sábado', + 'Domingo', +]; + +const bloquesHorario = [ + '8:00 - 8:45', + '8:45 - 9:30', + + '9:40 - 10:25', + '10:25 - 11:10', + + '11:20 - 12:05', + '12:05 - 12:50', + + '13:00 - 13:45', + '13:45 - 14:30', + + '14:40 - 15:25', + '15:25 - 16:10', + + '16:20 - 17:05', + '17:05 - 17:50', + + '18:00 - 18:45', + '18:45 - 19:30', + + '19:40 - 20:25', + '20:25 - 21:10', + + '21:20 - 22:05', + '22:05 - 22:50', +]; + +const List horasInicio = [ + "08:00", + "09:40", + "11:20", + "13:00", + "14:40", + "16:20", + "18:00", + "19:40", + "21:20" +]; + +const List horasIntermedio = [ + "08:45", + "10:25", + "12:05", + "13:45", + "15:25", + "17:05", + "18:45", + "20:25", + "22:05" +]; + +const List horasTermino = [ + "09:30", + "11:10", + "12:50", + "14:30", + "16:10", + "17:50", + "19:30", + "21:10", + "22:50" +]; \ No newline at end of file diff --git a/lib/core/utils/http/functions.dart b/lib/core/utils/http/functions.dart index 3989287..720c89b 100644 --- a/lib/core/utils/http/functions.dart +++ b/lib/core/utils/http/functions.dart @@ -66,6 +66,43 @@ Future sigaClientRequest(String path, { } } +Future httpClientRequest(String uri, { + String method = "GET", + Map? headers, + dynamic data, + String? contentType, + ResponseType? responseType, + Options? options, + bool forceRefresh = false, + Duration ttl = const Duration(days: 7), + Map? extra, + Map? queryParameters, +}) async { + try { + return await HttpClient.httpCachedClient.request(uri, + data: data, + queryParameters: queryParameters, + options: options ?? buildCacheOptions(ttl, + forceRefresh: forceRefresh, + primaryKey: 'api.miutem', + subKey: base64Encode(utf8.encode("$uri/${queryParameters?.entries.map((e) => "${e.key}=${Uri.encodeComponent(e.value)}").join("&")}")), + maxStale: const Duration(days: 14), + options: (options ?? Options()).copyWith( + method: method, + headers: headers, + contentType: contentType, + responseType: responseType, + extra: extra, + ), + ), + ); + } on SocketException { + throw CustomException(message: 'Error al conectar con la API. Por favor intenta más tarde.'); + } catch (e) { + rethrow; + } +} + Future isOffline() async { bool offlineMode = (await Preferencia.isOffline.getAsBool(defaultValue: false, guardar: true)); diff --git a/lib/core/utils/http/http_client.dart b/lib/core/utils/http/http_client.dart index f6c1d89..5231ad5 100644 --- a/lib/core/utils/http/http_client.dart +++ b/lib/core/utils/http/http_client.dart @@ -8,6 +8,11 @@ import 'package:miutem/core/utils/http/interceptors/offline_mode_interceptor.dar class HttpClient { + static final DioCacheManager cacheManager = DioCacheManager(CacheConfig( + defaultMaxAge: const Duration(days: 7), + defaultMaxStale: const Duration(days: 14), + )); + static final DioCacheManager cacheManagerSiga = DioCacheManager(CacheConfig( baseUrl: sigaServiceUri, defaultMaxAge: const Duration(days: 7), @@ -24,11 +29,16 @@ class HttpClient { errorInterceptor, ]); + static final httpCachedClient = httpClient..interceptors.addAll([ + cacheManager.interceptor, + ]); + static final Dio authClientSiga = httpClient..interceptors.addAll([ cacheManagerSiga.interceptor, ]); static Future clearCache() async { await cacheManagerSiga.clearAll(); + await cacheManager.clearAll(); } } \ No newline at end of file diff --git a/lib/core/utils/utilities.dart b/lib/core/utils/utilities.dart index 61c3864..587e742 100644 --- a/lib/core/utils/utilities.dart +++ b/lib/core/utils/utilities.dart @@ -68,7 +68,14 @@ String getToday() { /// Devuelve un color dependiendo si es modo oscuro o no. Color themedColor(BuildContext context, {required Color light, required Color dark}) { - final mode = AdaptiveTheme.of(context).mode; + final adaptiveTheme = AdaptiveTheme.maybeOf(context); + + // Si AdaptiveTheme no está disponible, usar el brillo del sistema + if (adaptiveTheme == null) { + return WidgetsBinding.instance.platformDispatcher.platformBrightness == Brightness.dark ? dark : light; + } + + final mode = adaptiveTheme.mode; if(mode.isSystem) { return WidgetsBinding.instance.platformDispatcher.platformBrightness == Brightness.dark ? dark : light; } diff --git a/lib/main.dart b/lib/main.dart index f4323c5..0a5635a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,7 @@ import 'package:adaptive_theme/adaptive_theme.dart'; -import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:get/get.dart'; -import 'package:miutem/core/models/config/user_config.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:miutem/core/models/preferencia.dart'; import 'package:miutem/core/services/controllers/local_notifications_controller.dart'; import 'package:miutem/core/services/service_manager.dart'; @@ -11,6 +9,7 @@ import 'package:miutem/core/utils/http/functions.dart'; import 'package:miutem/styles/styles.dart'; void main() async { + await dotenv.load(); WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( @@ -19,7 +18,7 @@ void main() async { statusBarIconBrightness: Brightness.dark, ), ); - + WidgetsFlutterBinding.ensureInitialized(); await initServices(); runApp(const MiUTEMApp()); @@ -38,7 +37,7 @@ class _MiUTEMAppState extends State { void initState() { isOffline().then((isOffline) => Preferencia.isOffline.set(isOffline ? 'true' : 'false'), onError: (err) => Preferencia.isOffline.set('true')); NotificationController.checkAndRequestNotificationPermissions(); - + super.initState(); } diff --git a/lib/screens/asignaturas/widgets/actions/acceso_rapido.dart b/lib/screens/asignaturas/actions/acceso_rapido.dart similarity index 65% rename from lib/screens/asignaturas/widgets/actions/acceso_rapido.dart rename to lib/screens/asignaturas/actions/acceso_rapido.dart index e976c6f..9e0716d 100644 --- a/lib/screens/asignaturas/widgets/actions/acceso_rapido.dart +++ b/lib/screens/asignaturas/actions/acceso_rapido.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:miutem/screens/horario/horario_screen.dart'; +import 'package:miutem/screens/malla_historica/malla_historica_screen.dart'; import 'package:miutem/screens/notas/notas_screen.dart'; void visitarCalculadoraNotas(BuildContext context) => Navigator.push(context, MaterialPageRoute(builder: (ctx) => const NotasScreen())); -void visitarHorario(BuildContext context) => Navigator.push(context, MaterialPageRoute(builder: (ctx) => const HorarioScreen())); \ No newline at end of file +void visitarHorario(BuildContext context) => Navigator.push(context, MaterialPageRoute(builder: (ctx) => const HorarioScreen())); + +void visitarMallaHistorica(BuildContext context) => Navigator.push(context, MaterialPageRoute(builder: (ctx) => const MallaHistoricaScreen())); diff --git a/lib/screens/asignaturas/asignaturas_screen.dart b/lib/screens/asignaturas/asignaturas_screen.dart deleted file mode 100644 index e9cbcfd..0000000 --- a/lib/screens/asignaturas/asignaturas_screen.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:miutem/core/models/asignaturas/asignatura.dart'; -import 'package:miutem/core/models/user/estudiante.dart'; -import 'package:miutem/core/services/asignaturas_service.dart'; -import 'package:miutem/core/services/auth_service.dart'; -import 'package:miutem/core/utils/utils.dart'; -import 'package:miutem/screens/asignaturas/widgets/acceso_rapido.dart'; -import 'package:miutem/screens/asignaturas/widgets/asignaturas_en_curso.dart'; -import 'package:miutem/screens/auth/login/login_screen.dart'; -import 'package:miutem/styles/styles.dart'; - -class AsignaturasScreen extends StatefulWidget { - const AsignaturasScreen({super.key}); - - @override - State createState() => _AsignaturasScreenState(); -} - -class _AsignaturasScreenState extends State { - Estudiante? estudiante; - List? asignaturas; - - @override - void initState() { - super.initState(); - Get.find().login() - .then((estudiante) => setState(() => this.estudiante = estudiante), onError: (err) { - if(mounted) { - Navigator.popUntil(context, (route) => route.isFirst); - Navigator.pushReplacement(context, MaterialPageRoute(builder: (ctx) => const LoginScreen())); - } - }); - Get.find() - .getAsignaturas() - .then((asignaturas) => setState(() => this.asignaturas = asignaturas), - onError: (err) { - logger.e('Error al cargar asignaturas', error: err); - }); - } - - - @override - Widget build(BuildContext context) => Padding( - padding: const EdgeInsets.all(16), - child: RefreshIndicator( - onRefresh: () async { - setState(() { - this.estudiante = null; - this.asignaturas = null; - }); - - final estudiante = await Get.find().login(forceRefresh: true); - final asignaturas = await Get.find().getAsignaturas(forceRefresh: true); - setState(() { - this.estudiante = estudiante; - this.asignaturas = asignaturas; - }); - }, - child: SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - clipBehavior: Clip.none, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 20), - Text("Asignaturas", style: Theme.of(context).textTheme.headlineMedium), - const SizedBox(height: 20), - const AccesoRapido(), - const SizedBox(height: 20), - AsignaturasEnCurso(asignaturas: asignaturas), - ], - ),),) - ); -} diff --git a/lib/screens/asignaturas/detalle_asignatura/actions/cargar_notas_asignatura.dart b/lib/screens/asignaturas/detalle_asignatura/actions/cargar_notas_asignatura.dart new file mode 100644 index 0000000..e9ac319 --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/actions/cargar_notas_asignatura.dart @@ -0,0 +1,40 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:miutem/core/models/asignaturas/asignatura.dart'; +import 'package:miutem/core/services/grades_service.dart'; +import 'package:miutem/core/services/horario_service.dart'; +import 'package:miutem/core/utils/constants.dart'; +import 'package:miutem/core/utils/horario_data.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart'; + +Future cargarAsignaturaConNotas({required Asignatura asignatura, bool forceRefresh = false}) async { + final grades = await Get.find().getGrades(asignatura, forceRefresh: forceRefresh); + return asignatura.copyWith(grades: grades); +} + +Future> cargarHorarioBloque({required Asignatura asignatura}) async { + try { + final horario = await Get.find().getHorario(); + Map> bloquesPorDia = {}; + for(final (idx, filaBloques) in (horario.horario ?? []).indexed) { + if(filaBloques.isEmpty) continue; // Skip empty rows + for(final (idxDia, bloque) in filaBloques.indexed) { + if(bloque.asignatura == null || bloque.asignatura?.nombre.toUpperCase() != asignatura.nombre.toUpperCase() || bloque.asignatura?.codigo.toUpperCase() != asignatura.codigo.toUpperCase()) continue; // Skip empty blocks + bloquesPorDia[idxDia] ??= {}; + bloquesPorDia[idxDia]![idx] = HorarioBloque( + dia: diasHorario[idxDia], + nombreAsignatura: bloque.asignatura?.nombre ?? 'N/A', + sala: bloque.sala ?? 'N/A', + horaInicio: bloquesHorario[idx].split('-')[0].trim(), + horaFin: bloquesHorario[idx].split('-')[1].trim(), + ); + } + } + + return bloquesPorDia.values.expand((diaBloques) => diaBloques.values).toList(); + } catch (error) { + logger.e('Error al cargar horario bloque', error: error); + return []; + } +} \ No newline at end of file diff --git a/lib/screens/asignaturas/detalle_asignatura/asignatura_screen.dart b/lib/screens/asignaturas/detalle_asignatura/asignatura_screen.dart new file mode 100644 index 0000000..2276249 --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/asignatura_screen.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/asignaturas/asignatura.dart'; +import 'package:miutem/core/utils/constants.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/actions/cargar_notas_asignatura.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/widgets/promedio.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/widgets/seccion_horario.dart'; +import 'package:miutem/screens/notas/notas_screen.dart'; +import 'package:miutem/styles/styles.dart'; + +class AsignaturaScreen extends StatefulWidget { + + final Asignatura asignatura; + + const AsignaturaScreen({ + super.key, + required this.asignatura, + }); + + @override + State createState() => _AsignaturaScreenState(); +} + +class _AsignaturaScreenState extends State { + + late Asignatura asignatura; + List bloquesHorario = []; + + @override + void initState() { + asignatura = widget.asignatura; + super.initState(); + cargarAsignaturaConNotas(asignatura: widget.asignatura).then((loadedAsignatura) => setState(() => asignatura = loadedAsignatura)).catchError((error) { + if (mounted) showErrorSnackbar(context, "Error al cargar las notas"); + }); + + cargarHorarioBloque(asignatura: asignatura).then((bloques) => setState(() => bloquesHorario = bloques)); + } + + @override + Widget build(BuildContext context) => Scaffold( + appBar: AppBar(title: Text(asignatura.nombre)), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: RefreshIndicator( + onRefresh: () async { + List tmp = bloquesHorario; + try { + setState(() { + bloquesHorario.clear(); + }); + + final updatedAsignatura = await cargarAsignaturaConNotas(asignatura: widget.asignatura); + final updatedBloquesHorario = await cargarHorarioBloque(asignatura: updatedAsignatura); + if (context.mounted) { + setState(() { + asignatura = updatedAsignatura; + bloquesHorario = updatedBloquesHorario; + }); + } + } catch (error) { + setState(() { + bloquesHorario = tmp; // Revertir a los bloques anteriores en caso de error + }); + logger.e('Error al recargar vista asignatura', error: error); + if (context.mounted) showErrorSnackbar(context, "Error al recargar las notas"); + } + }, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 12), + GestureDetector( + child: Promedio(grades: asignatura.grades), + onTap: () => Navigator.push(context, MaterialPageRoute(builder: (ctx) => NotasScreen(asignatura: asignatura))), + ), + const SizedBox(height: 12), + SeccionHorario(bloques: bloquesHorario), + const SizedBox(height: 12), + ], + ), + ), + ), + ), + ); +} diff --git a/lib/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart b/lib/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart new file mode 100644 index 0000000..8a6f57e --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart @@ -0,0 +1,26 @@ +import 'dart:convert'; + +class HorarioBloque { + final String dia; + final String horaInicio; + final String horaFin; + final String nombreAsignatura; + final String sala; + + HorarioBloque({ + required this.dia, + required this.horaInicio, + required this.horaFin, + required this.nombreAsignatura, + required this.sala, + }); + + toJson() => { + 'dia': dia, + 'horaInicio': horaInicio, + 'horaFin': horaFin, + 'nombreAsignatura': nombreAsignatura, + 'sala': sala, + }; + +} diff --git a/lib/screens/asignaturas/detalle_asignatura/widgets/card_horario.dart b/lib/screens/asignaturas/detalle_asignatura/widgets/card_horario.dart new file mode 100644 index 0000000..487bf8f --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/widgets/card_horario.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart'; + +class CardHorario extends StatelessWidget { + final HorarioBloque bloque; + + const CardHorario({ + super.key, + required this.bloque, + }); + + String _capitalizeDia(String dia) => dia[0].toUpperCase() + dia.substring(1).toLowerCase(); + + @override + Widget build(BuildContext context) => Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: BorderSide(color: Theme.of(context).dividerColor), + ), + margin: const EdgeInsets.only(bottom: 10), + child: IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + DecoratedBox( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + bottomLeft: Radius.circular(16), + ), + border: Border( + right: BorderSide( + color: Theme.of(context).dividerColor, + ), + ), + ), + child: SizedBox( + width: 85, + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(bloque.horaInicio.trim(), + style: const TextStyle( + fontWeight: FontWeight.w900, + fontSize: 18, + ), + ), + Text(bloque.horaFin.trim(), + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 14, + ), + ), + ], + ), + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + _capitalizeDia(bloque.nombreAsignatura), + style: const TextStyle( + fontWeight: FontWeight.w900, + fontSize: 18, + ), + overflow: TextOverflow.ellipsis, + ), + Text( + bloque.dia, + style: const TextStyle( + fontWeight: FontWeight.w300, + fontSize: 14, + ), + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon(Icons.location_on_outlined, size: 16), + const SizedBox(width: 5), + Expanded( + child: Text( + bloque.sala, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ); +} diff --git a/lib/screens/asignaturas/detalle_asignatura/widgets/promedio.dart b/lib/screens/asignaturas/detalle_asignatura/widgets/promedio.dart new file mode 100644 index 0000000..008d502 --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/widgets/promedio.dart @@ -0,0 +1,107 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/evaluacion/grades.dart'; +import 'package:miutem/styles/styles.dart'; +import 'package:miutem/core/utils/utils.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +class Promedio extends StatelessWidget { + + final Grades? grades; + + const Promedio({ + super.key, + required this.grades, + }); + + @override + Widget build(BuildContext context) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text("Promedio", style: Theme.of(context).textTheme.bodyMedium), + const SizedBox(height: 5), + SizedBox( + child: Skeletonizer( + enabled: grades == null, + child: Card( + margin: EdgeInsets.zero, + color: Theme.of(context).scaffoldBackgroundColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10), side: BorderSide(color: AppTheme.lightGrey)), + child: Padding( + padding: const EdgeInsets.only(top: 20, bottom: 20, left: 40, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(formatoNota(grades?.notaFinal) ?? "--", style: TextStyle(fontSize: 32, fontWeight: FontWeight.w700, color: AppTheme.colorScheme.primary)), + const Spacer(), + DecoratedBox(decoration: BoxDecoration(color: AppTheme.lightGrey), child: const SizedBox(width: 1, height: 80)), + const Spacer(), // Spacer agregado + Flexible( + flex: 6, + fit: FlexFit.tight, + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Skeleton.keep(child: Text("Presentación", style: Theme.of(context).textTheme.bodyMedium)), + const Spacer(), + Container( + width: 80, + height: 40, + decoration: BoxDecoration( + color: Colors.grey.withValues(alpha: 0.2), + border: Border.all(color: Theme.of(context).dividerColor), + borderRadius: BorderRadius.circular(4), + ), + child: Center( + child: Text( + formatoNota(grades?.notaPresentacion) ?? '--', + style: Theme.of(context).textTheme.bodyMedium, + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + const SizedBox(height: 10), + Row( + children: [ + Skeleton.keep(child: Text("Examen", style: Theme.of(context).textTheme.bodyMedium)), + const Spacer(), + Container( + width: 80, + height: 40, + decoration: BoxDecoration( + color: Colors.grey.withValues(alpha: 0.2), + border: Border.all(color: Theme.of(context).dividerColor), + borderRadius: BorderRadius.circular(4), + ), + child: Center( + child: Text( + formatoNota(grades?.notaExamen) ?? "--", + style: Theme.of(context).textTheme.bodyMedium, + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + const SizedBox(height: 12), + Text( + "El promedio se calcula con las notas de presentación y examen. Presiona sobre el promedio para ver más detalles.", + style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.grey), + ), + ], + ); +} \ No newline at end of file diff --git a/lib/screens/asignaturas/detalle_asignatura/widgets/seccion_horario.dart b/lib/screens/asignaturas/detalle_asignatura/widgets/seccion_horario.dart new file mode 100644 index 0000000..e6fafba --- /dev/null +++ b/lib/screens/asignaturas/detalle_asignatura/widgets/seccion_horario.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/models/horario_bloque.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/widgets/card_horario.dart'; +import 'package:miutem/screens/horario/horario_screen.dart'; +import 'package:miutem/styles/styles.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +final dummyBloques = [ + HorarioBloque(dia: 'Lunes', horaInicio: '8:00', horaFin: '20:00', nombreAsignatura: 'Club de Desarrollo Experimental', sala: 'M8-103'), + HorarioBloque(dia: 'Martes', horaInicio: '8:00', horaFin: '20:00', nombreAsignatura: 'Club de Desarrollo Experimental', sala: 'M8-103'), + HorarioBloque(dia: 'Miércoles', horaInicio: '8:00', horaFin: '20:00', nombreAsignatura: 'Club de Desarrollo Experimental', sala: 'M8-103'), + HorarioBloque(dia: 'Jueves', horaInicio: '8:00', horaFin: '20:00', nombreAsignatura: 'Club de Desarrollo Experimental', sala: 'M8-103'), +]; + +class SeccionHorario extends StatelessWidget { + + final List bloques; + + const SeccionHorario({ + super.key, + required this.bloques, + }); + + @override + Widget build(BuildContext context) => Skeletonizer( + enabled: bloques.isEmpty, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Skeleton.keep(child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Horario', + style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w800), + ), + GestureDetector( + child: Text( + 'Ver más', + style: Theme.of(context).textTheme.bodySmall?.copyWith(fontWeight: FontWeight.w500), + ), + onTap: () => Navigator.push(context, MaterialPageRoute(builder: (ctx) => const HorarioScreen())), + ), + ], + )), + const Skeleton.keep(child: Space.xSmall), + ...(bloques.isEmpty ? dummyBloques : bloques).map((bloque) => CardHorario(bloque: bloque)) + ], + ), + ); +} + diff --git a/lib/screens/asignaturas/lista_asignaturas_screen.dart b/lib/screens/asignaturas/lista_asignaturas_screen.dart new file mode 100644 index 0000000..e524ee1 --- /dev/null +++ b/lib/screens/asignaturas/lista_asignaturas_screen.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:miutem/core/models/asignaturas/asignatura.dart'; +import 'package:miutem/core/models/user/estudiante.dart'; +import 'package:miutem/core/services/asignaturas_service.dart'; +import 'package:miutem/core/services/auth_service.dart'; +import 'package:miutem/core/utils/utils.dart'; +import 'package:miutem/screens/asignaturas/widgets/acceso_rapido.dart'; +import 'package:miutem/screens/asignaturas/widgets/asignaturas_en_curso.dart'; +import 'package:miutem/screens/auth/login/login_screen.dart'; +import 'package:miutem/styles/styles.dart'; + +class AsignaturasScreen extends StatefulWidget { + const AsignaturasScreen({super.key}); + + @override + State createState() => _AsignaturasScreenState(); +} + +class _AsignaturasScreenState extends State { + Estudiante? estudiante; + List? asignaturas; + + @override + void initState() { + super.initState(); + Get.find() + .login() + .then((estudiante) => setState(() => this.estudiante = estudiante), + onError: (err) { + if (mounted) { + Navigator.popUntil(context, (route) => route.isFirst); + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (ctx) => const LoginScreen())); + } + }); + Get.find() + .getAsignaturas() + .then((asignaturas) => setState(() => this.asignaturas = asignaturas), + onError: (err) { + logger.e('Error al cargar asignaturas', error: err); + }); + } + + @override + Widget build(BuildContext context) => Scaffold( + body: Padding( + padding: const EdgeInsets.all(16), + child: RefreshIndicator( + onRefresh: () async { + setState(() { + this.estudiante = null; + this.asignaturas = null; + }); + final estudiante = await Get.find().login(forceRefresh: true); + final asignaturas = await Get.find() + .getAsignaturas(forceRefresh: true); + setState(() { + this.estudiante = estudiante; + this.asignaturas = asignaturas; + }); + }, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + clipBehavior: Clip.none, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Text("Asignaturas", style: Theme.of(context).textTheme.headlineMedium), + const SizedBox(height: 20), + const AccesoRapido(), + const SizedBox(height: 20), + AsignaturasEnCurso(asignaturas: asignaturas), + ], + ), + ), + ), + ), + ); +} diff --git a/lib/screens/asignaturas/widgets/acceso_rapido.dart b/lib/screens/asignaturas/widgets/acceso_rapido.dart index 5ed7004..750df71 100644 --- a/lib/screens/asignaturas/widgets/acceso_rapido.dart +++ b/lib/screens/asignaturas/widgets/acceso_rapido.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:miutem/styles/styles.dart'; -import 'package:miutem/screens/asignaturas/widgets/actions/acceso_rapido.dart'; +import 'package:miutem/screens/asignaturas/actions/acceso_rapido.dart'; class AccesoRapido extends StatelessWidget { const AccesoRapido({super.key}); @@ -31,7 +31,7 @@ class AccesoRapido extends StatelessWidget { label: 'Malla Histórica', icon: AppIcons.historicTimetable, fill: 0, - onTap: () => {}, + onTap: () => visitarMallaHistorica(context), ), const SizedBox(width: 10), CardAccesoRapido( diff --git a/lib/screens/asignaturas/widgets/asignaturas_inscritas/lista_asignaturas.dart b/lib/screens/asignaturas/widgets/asignaturas_inscritas/lista_asignaturas.dart index 497bfb1..9c93964 100644 --- a/lib/screens/asignaturas/widgets/asignaturas_inscritas/lista_asignaturas.dart +++ b/lib/screens/asignaturas/widgets/asignaturas_inscritas/lista_asignaturas.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:miutem/core/models/asignaturas/asignatura.dart'; +import 'package:miutem/screens/asignaturas/detalle_asignatura/asignatura_screen.dart'; import 'package:miutem/screens/asignaturas/widgets/asignaturas_inscritas/card_asignatura.dart'; import 'package:skeletonizer/skeletonizer.dart'; @@ -26,6 +27,7 @@ class ListaAsignaturas extends StatelessWidget { tipo: asignatura.tipoHora, nombre: asignatura.nombre, codigo: asignatura.codigo, + onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => AsignaturaScreen(asignatura: asignatura))), )).toList() ?? List.filled(6, defaultCard), ), ); diff --git a/lib/screens/auth/login/widgets/login_form.dart b/lib/screens/auth/login/widgets/login_form.dart index 29164b2..4ae4819 100644 --- a/lib/screens/auth/login/widgets/login_form.dart +++ b/lib/screens/auth/login/widgets/login_form.dart @@ -1,4 +1,6 @@ +import 'package:adaptive_theme/adaptive_theme.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:miutem/core/models/exceptions/custom_exception.dart'; import 'package:miutem/screens/auth/login/actions/login_action.dart'; import 'package:miutem/screens/auth/login/widgets/login_form_fields.dart'; @@ -50,7 +52,10 @@ class _LoginFormState extends State with WidgetsBindingObserver { children: [ Padding( padding: const EdgeInsets.all(15), - child: Image.asset(MediaQuery.of(context).platformBrightness == Brightness.light ? 'assets/images/miutem_oscuro.png' : 'assets/images/miutem_claro.png', height: 80, fit: BoxFit.fitWidth), + child: ValueListenableBuilder( + valueListenable: AdaptiveTheme.of(context).modeChangeNotifier, + builder: (ctx, mode, child) => Image.asset(mode == AdaptiveThemeMode.light ? 'assets/images/miutem_oscuro.png' : 'assets/images/miutem_claro.png', height: 80, fit: BoxFit.fitWidth), + ), ), const Padding( padding: EdgeInsets.only(bottom: 15), @@ -68,6 +73,7 @@ class _LoginFormState extends State with WidgetsBindingObserver { passwordFocus: _passwordFocus, usernameFocus: _usernameFocus, onLogin: () async { + TextInput.finishAutofillContext(shouldSave: true); showLoadingDialog(context); try { await loginAction( diff --git a/lib/screens/auth/login/widgets/login_form_fields.dart b/lib/screens/auth/login/widgets/login_form_fields.dart index e37e4e7..70971e7 100644 --- a/lib/screens/auth/login/widgets/login_form_fields.dart +++ b/lib/screens/auth/login/widgets/login_form_fields.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:miutem/screens/auth/login/widgets/utem_email_input_formatter.dart'; class LoginFormFields extends StatelessWidget { final TextEditingController usernameController, passwordController; @@ -7,23 +8,30 @@ class LoginFormFields extends StatelessWidget { const LoginFormFields({super.key, required this.usernameController, required this.passwordController, required this.passwordFocus, required this.onLogin, required this.usernameFocus}); + String get fullEmail => '${usernameController.text}@utem.cl'; + @override - Widget build(BuildContext context) => Column( + Widget build(BuildContext context) => AutofillGroup( + onDisposeAction: AutofillContextAction.commit, + child: Column( children: [ TextField( decoration: const InputDecoration( labelText: 'Usuario/Correo', - hintText: 'usuario@utem.cl', + hintText: 'usuario', border: OutlineInputBorder(), prefixIcon: Icon(Icons.alternate_email), + suffixText: '@utem.cl', ), controller: usernameController, autocorrect: false, keyboardType: TextInputType.emailAddress, - autofillHints: const [AutofillHints.email], + autofillHints: const [AutofillHints.username, AutofillHints.email], autofocus: true, onSubmitted: (_) => passwordFocus.requestFocus(), focusNode: usernameFocus, + textInputAction: TextInputAction.next, + inputFormatters: [UtemEmailInputFormatter()], ), const SizedBox(height: 10), TextField( @@ -33,6 +41,9 @@ class LoginFormFields extends StatelessWidget { border: OutlineInputBorder(), prefixIcon: Icon(Icons.password), ), + autofillHints: const [AutofillHints.password], + keyboardType: TextInputType.visiblePassword, + textInputAction: TextInputAction.go, focusNode: passwordFocus, obscureText: true, obscuringCharacter: '•', @@ -50,5 +61,5 @@ class LoginFormFields extends StatelessWidget { ), const SizedBox(height: 10) ], - ); + )); } diff --git a/lib/screens/auth/login/widgets/utem_email_input_formatter.dart b/lib/screens/auth/login/widgets/utem_email_input_formatter.dart new file mode 100644 index 0000000..9e301f3 --- /dev/null +++ b/lib/screens/auth/login/widgets/utem_email_input_formatter.dart @@ -0,0 +1,29 @@ +import 'package:flutter/services.dart'; + +/// Custom TextInputFormatter that blocks @ symbol input +/// to restrict users to only @utem.cl domain +class UtemEmailInputFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + // Remove any @ symbols from the new text + final filteredText = newValue.text.replaceAll('@utem.cl', '').replaceAll('@', ''); + + if (filteredText == newValue.text) { + return newValue; + } + + // Adjust cursor position if @ was removed + final cursorOffset = newValue.text.length - filteredText.length; + final newCursorPosition = (newValue.selection.baseOffset - cursorOffset) + .clamp(0, filteredText.length); + + return TextEditingValue( + text: filteredText, + selection: TextSelection.collapsed(offset: newCursorPosition), + ); + } +} + diff --git a/lib/screens/horario/horario_screen.dart b/lib/screens/horario/horario_screen.dart index 37f86ae..b34e734 100644 --- a/lib/screens/horario/horario_screen.dart +++ b/lib/screens/horario/horario_screen.dart @@ -155,8 +155,11 @@ class _HorarioScreenState extends State { ext: 'png', mimeType: MimeType.png, ); - if(context.mounted) Navigator.pop(context); - + // Mostrar toast de éxito + if(context.mounted) { + Navigator.pop(context); + showTextSnackbar(context, title: "Horario guardado", message: "El horario se ha guardado correctamente en tu carpeta de descargas."); + } } else { final directory = await getApplicationDocumentsDirectory(); final imagePath = await File('${directory.path}/horario.png').create(); diff --git a/lib/screens/horario/widgets/components/bloque_clase.dart b/lib/screens/horario/widgets/components/bloque_clase.dart index 0a96fef..215602b 100644 --- a/lib/screens/horario/widgets/components/bloque_clase.dart +++ b/lib/screens/horario/widgets/components/bloque_clase.dart @@ -8,7 +8,7 @@ class BloqueClase extends StatelessWidget { final BloqueHorario block; final double width; final double height; - final Color textColor; + final Color? textColor; final Color? color; final void Function(BloqueHorario)? onTap; final void Function(BloqueHorario)? onLongPress; @@ -18,41 +18,47 @@ class BloqueClase extends StatelessWidget { required this.block, required this.width, required this.height, - required this.textColor, + this.textColor, this.color = Colors.teal, this.onTap, this.onLongPress, }); @override - Widget build(BuildContext context) => DecoratedBox( - decoration: BoxDecoration( - color: Get.find().getColor(block.asignatura) ?? this.color, - borderRadius: BorderRadius.circular(15), - ), - child: Material( - color: Colors.transparent, - child: InkWell( + Widget build(BuildContext context) { + final colorData = Get.find().getColorWithContrast(block.asignatura); + final backgroundColor = colorData?.background ?? this.color ?? Colors.teal; + final effectiveTextColor = this.textColor ?? colorData?.text ?? Colors.white; + + return DecoratedBox( + decoration: BoxDecoration( + color: backgroundColor, borderRadius: BorderRadius.circular(15), - onTap: () => onTap?.call(block), - onLongPress: () => onLongPress?.call(block), - child: Column( - children: [ - HorarioText.classCode("${block.codigo}", - color: textColor, - ), - HorarioText.className("${block.asignatura?.nombre.toUpperCase()}", - color: textColor, - ), - HorarioText.classLocation(block.sala ?? "Sin sala", - color: textColor, - ), - ], - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(15), + onTap: () => onTap?.call(block), + onLongPress: () => onLongPress?.call(block), + child: Column( + children: [ + HorarioText.classCode("${block.codigo}", + color: effectiveTextColor, + ), + HorarioText.className("${block.asignatura?.nombre.toUpperCase()}", + color: effectiveTextColor, + ), + HorarioText.classLocation(block.sala ?? "Sin sala", + color: effectiveTextColor, + ), + ], + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + ), ), ), - ), - ); + ); + } } diff --git a/lib/screens/horario/widgets/components/bloque_ramo_card.dart b/lib/screens/horario/widgets/components/bloque_ramo_card.dart index 8638e58..5d641e2 100644 --- a/lib/screens/horario/widgets/components/bloque_ramo_card.dart +++ b/lib/screens/horario/widgets/components/bloque_ramo_card.dart @@ -3,13 +3,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:miutem/core/models/horario.dart'; import 'package:miutem/core/services/asignaturas_service.dart'; -import 'package:miutem/core/services/carrera_service.dart'; -import 'package:miutem/core/services/grades_service.dart'; +import 'package:miutem/core/services/controllers/horario_controller.dart'; import 'package:miutem/core/utils/utilities.dart'; -import 'package:miutem/screens/asignaturas/asignaturas_screen.dart'; import 'package:miutem/screens/horario/widgets/modals/vista_previa_asignatura_modal.dart'; -import 'package:miutem/screens/tasklist/task_list_screen.dart'; -import 'package:miutem/styles/loading/loading_dialog.dart'; import 'package:miutem/styles/styles.dart'; class ClassBlockCard extends StatelessWidget { @@ -38,45 +34,61 @@ class ClassBlockCard extends StatelessWidget { child: SizedBox( width: width, height: height, - child: ValueListenableBuilder( - valueListenable: AdaptiveTheme.of(context).modeChangeNotifier, - builder: (ctx, mode, child) => DecoratedBox( - decoration: BoxDecoration( - color: themedColor(context, light: AppTheme.lightBlueCard, dark: AppTheme.darkBlueCard), - borderRadius: BorderRadius.circular(10), - ), - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text('${block!.asignatura!.codigo}/${block!.asignatura!.seccion}', style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.normal)), - Space.medium, - Text(block!.asignatura!.nombre, style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w700)), - Space.medium, - Text(block!.sala ?? 'SIN SALA', style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.normal)), - ], - ), - ), - ), - ), + child: _buildBlockContent(context), ), ), ), ); + Widget _buildBlockContent(BuildContext context) { + final adaptiveTheme = AdaptiveTheme.maybeOf(context); + final colorData = Get.find().getColorWithContrast(block?.asignatura); + final backgroundColor = colorData?.background ?? themedColor(context, light: AppTheme.lightBlueCard, dark: AppTheme.darkBlueCard); + final textColor = colorData?.text ?? Theme.of(context).textTheme.bodyMedium?.color; + + final content = DecoratedBox( + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(10), + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text('${block!.asignatura!.codigo}/${block!.asignatura!.seccion}', style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.normal, color: textColor)), + Space.medium, + Text(block!.asignatura!.nombre, style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w700, color: textColor), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis), + Space.medium, + Text(block!.sala ?? 'SIN SALA', style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.normal, color: textColor)), + ], + ), + ), + ); + + // Si AdaptiveTheme está disponible, escucha los cambios de tema + if (adaptiveTheme != null) { + return ValueListenableBuilder( + valueListenable: adaptiveTheme.modeChangeNotifier, + builder: (ctx, mode, child) => content, + ); + } + + // Si no está disponible (ej: durante captureFromWidget), retorna el contenido directamente + return content; + } + _onTap(BloqueHorario block, BuildContext context) async { showLoadingDialog(context); - final carrera = await Get.find().getCarrera(); final asignatura = (await Get.find() .getAsignaturas(forceRefresh: true)) .firstWhereOrNull((asignatura) => asignatura.id == block.asignatura?.id || asignatura.codigo == block.asignatura?.codigo); - final grades = await Get.find().getGrades(asignatura!); - if (carrera == null || asignatura == null) { + if (asignatura == null) { if(context.mounted) Navigator.pop(context); return; } + // final grades = await Get.find().getGrades(asignatura); if(context.mounted) Navigator.pop(context); // if(context.mounted) Navigator.push(context, MaterialPageRoute(builder: (ctx) => AsignaturaScreen(asignatura))); // Navigator.push(context, MaterialPageRoute(builder: (ctx) => AsignaturaDetalleScreen( @@ -87,11 +99,10 @@ class ClassBlockCard extends StatelessWidget { _onLongPress(BloqueHorario block, BuildContext context) async { showLoadingDialog(context); - final carrera = await Get.find().getCarrera(); final asignatura = (await Get.find() .getAsignaturas(forceRefresh: true)) .firstWhereOrNull((asignatura) => asignatura.id == block.asignatura?.id || asignatura.codigo == block.asignatura?.codigo); - if (carrera == null || asignatura == null) { + if (asignatura == null) { if(context.mounted) Navigator.pop(context); return; } diff --git a/lib/screens/malla_historica/malla_historica_screen.dart b/lib/screens/malla_historica/malla_historica_screen.dart new file mode 100644 index 0000000..ef02b54 --- /dev/null +++ b/lib/screens/malla_historica/malla_historica_screen.dart @@ -0,0 +1,114 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/asignaturas/asignatura_malla.dart'; +import 'package:miutem/core/models/exceptions/custom_exception.dart'; +import 'package:miutem/core/services/mi_utem/miutem_malla_service.dart'; +import 'package:miutem/screens/malla_historica/widgets/widgets.dart'; +import 'package:miutem/styles/styles.dart'; + +class MallaHistoricaScreen extends StatefulWidget { + const MallaHistoricaScreen({super.key}); + + @override + State createState() => _MallaHistoricaScreenState(); +} + +class _MallaHistoricaScreenState extends State { + Future>? _mallaFuture; + + @override + void initState() { + super.initState(); + _mallaFuture = _getMalla(); + } + + Future> _getMalla({bool forceRefresh = false}) async { + return await MiUTEMMallaService.get.getMalla(forceRefresh: forceRefresh); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder>( + future: _mallaFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Scaffold( + appBar: AppBar( + title: const Text("Malla Histórica"), + ), + body: LoadingIndicator.centeredDefault(), + ); + } + + final esErrorOffline = snapshot.hasError && + snapshot.error is DioError && + (snapshot.error as DioError).type == DioErrorType.cancel && + (snapshot.error as DioError).response?.extra["offline"] == true; + + if ((snapshot.hasError && !esErrorOffline) || !snapshot.hasData || snapshot.data == null) { + String errorMessage = "Ocurrió un error al cargar la malla. Por favor intenta más tarde."; + final error = snapshot.error; + if (error != null) { + errorMessage = error is CustomException + ? error.message + : "Ocurrió un error al cargar la malla. Por favor intenta más tarde."; + } + + return Scaffold( + appBar: AppBar( + title: const Text("Malla Histórica"), + actions: [ + IconButton( + onPressed: _reloadData, + icon: const Icon(Icons.refresh_sharp), + tooltip: "Forzar actualización de la malla", + ) + ], + ), + body: Center( + child: CustomErrorWidget( + title: "Error al cargar la malla", + error: errorMessage, + ), + ), + ); + } + + final asignaturas = snapshot.data!; + + return Scaffold( + appBar: AppBar( + title: const Text("Malla Histórica"), + actions: [ + PopupMenuButton( + position: PopupMenuPosition.under, + icon: const Icon(Icons.more_vert), + itemBuilder: (ctx) => [ + PopupMenuItem( + onTap: _reloadData, + child: const ListTile( + leading: Icon(Icons.refresh_sharp), + title: Text("Recargar"), + ), + ), + ], + ), + ], + ), + body: SafeArea( + child: MallaMainScroller( + asignaturas: asignaturas, + ), + ), + ); + }, + ); + } + + void _reloadData() { + setState(() { + _mallaFuture = _getMalla(forceRefresh: true); + }); + } +} + diff --git a/lib/screens/malla_historica/widgets/components/asignatura_malla_card.dart b/lib/screens/malla_historica/widgets/components/asignatura_malla_card.dart new file mode 100644 index 0000000..eaa1765 --- /dev/null +++ b/lib/screens/malla_historica/widgets/components/asignatura_malla_card.dart @@ -0,0 +1,197 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/asignaturas/asignatura_malla.dart'; +import 'package:miutem/core/utils/utilities.dart'; +import 'package:miutem/styles/styles.dart'; + +class AsignaturaMallaCard extends StatelessWidget { + final AsignaturaMalla asignatura; + + const AsignaturaMallaCard({ + super.key, + required this.asignatura, + }); + + Color _getBackgroundColor(BuildContext context) { + final estado = asignatura.estado.toLowerCase(); + if (estado.contains('aprobado') || estado.contains('aprobada')) { + return themedColor(context, + light: AppTheme.lightGreenCard, + dark: AppTheme.darkGreenCard, + ); + } else if (estado.contains('reprobado') || estado.contains('reprobada')) { + return themedColor(context, + light: AppTheme.lightSalmonCard, + dark: AppTheme.darkSalmonCard, + ); + } else if (estado.contains('cursando') || estado.contains('inscrit')) { + return themedColor(context, + light: AppTheme.lightBlueCard, + dark: AppTheme.darkBlueCard, + ); + } + return themedColor(context, + light: AppTheme.lightYellowCard, + dark: AppTheme.darkYellowCard, + ); + } + + Color _getTextColor(BuildContext context) { + final backgroundColor = _getBackgroundColor(context); + final brightness = ThemeData.estimateBrightnessForColor(backgroundColor); + return brightness == Brightness.light ? Colors.black87 : Colors.white; + } + + @override + Widget build(BuildContext context) { + final backgroundColor = _getBackgroundColor(context); + final textColor = _getTextColor(context); + + return Padding( + padding: const EdgeInsets.all(6), + child: GestureDetector( + onTap: () => _showAsignaturaDetail(context), + child: Container( + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(10), + ), + padding: const EdgeInsets.all(12), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Flexible( + child: Text( + asignatura.nombre, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w600, + color: textColor, + ), + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + Space.xSmall, + Text( + asignatura.tipo, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: textColor.withValues(alpha: 0.8), + ), + textAlign: TextAlign.center, + ), + Space.xSmall, + Wrap( + alignment: WrapAlignment.center, + spacing: 4, + runSpacing: 4, + children: [ + _buildChip(context, asignatura.nota, textColor), + _buildChip(context, asignatura.estado, textColor), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _buildChip(BuildContext context, String label, Color textColor) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + decoration: BoxDecoration( + color: textColor.withValues(alpha: 0.15), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + label, + style: Theme.of(context).textTheme.labelSmall?.copyWith( + color: textColor, + fontWeight: FontWeight.w500, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ); + } + + void _showAsignaturaDetail(BuildContext context) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + ), + builder: (ctx) => DraggableScrollableSheet( + expand: false, + initialChildSize: 0.5, + minChildSize: 0.3, + maxChildSize: 0.9, + builder: (context, scrollController) => SingleChildScrollView( + controller: scrollController, + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Center( + child: Container( + width: 40, + height: 4, + decoration: BoxDecoration( + color: Theme.of(context).dividerColor, + borderRadius: BorderRadius.circular(2), + ), + ), + ), + Space.medium, + Text( + asignatura.nombre, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + Space.medium, + _buildDetailRow(context, 'Tipo', asignatura.tipo), + _buildDetailRow(context, 'Estado', asignatura.estado), + _buildDetailRow(context, 'Nota', asignatura.nota), + _buildDetailRow(context, 'Nivel', asignatura.nivel.toString()), + _buildDetailRow(context, 'Intentos', asignatura.intentos.toString()), + Space.large, + ], + ), + ), + ), + ); + } + + Widget _buildDetailRow(BuildContext context, String label, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Text( + label, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Theme.of(context).textTheme.bodySmall?.color, + ), + ), + ), + Flexible( + child: Text( + value, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.end, + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/malla_historica/widgets/components/semestre_header_card.dart b/lib/screens/malla_historica/widgets/components/semestre_header_card.dart new file mode 100644 index 0000000..b3cf035 --- /dev/null +++ b/lib/screens/malla_historica/widgets/components/semestre_header_card.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +class SemestreHeaderCard extends StatelessWidget { + final int semestre; + + const SemestreHeaderCard({ + super.key, + required this.semestre, + }); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: Theme.of(context).scaffoldBackgroundColor, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Sem.', + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.normal, + ), + ), + Text( + '$semestre', + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/malla_historica/widgets/screens/malla_blocks_content.dart b/lib/screens/malla_historica/widgets/screens/malla_blocks_content.dart new file mode 100644 index 0000000..c1a7a30 --- /dev/null +++ b/lib/screens/malla_historica/widgets/screens/malla_blocks_content.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/asignaturas/asignatura_malla.dart'; +import 'package:miutem/screens/malla_historica/widgets/components/asignatura_malla_card.dart'; + +class MallaBlocksContent extends StatelessWidget { + final List> asignaturasPorSemestre; + + const MallaBlocksContent({ + super.key, + required this.asignaturasPorSemestre, + }); + + int get _maxAsignaturasPorSemestre { + if (asignaturasPorSemestre.isEmpty) return 0; + return asignaturasPorSemestre.map((s) => s.length).reduce((a, b) => a > b ? a : b); + } + + @override + Widget build(BuildContext context) { + final maxRows = _maxAsignaturasPorSemestre; + + if (asignaturasPorSemestre.isEmpty) { + return const SizedBox.shrink(); + } + + return Column( + mainAxisSize: MainAxisSize.min, + children: List.generate(maxRows, (rowIndex) { + return IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: List.generate(asignaturasPorSemestre.length, (semestreIndex) { + final asignaturas = asignaturasPorSemestre[semestreIndex]; + final hasAsignatura = rowIndex < asignaturas.length; + + return Expanded( + child: Container( + decoration: BoxDecoration( + border: Border( + right: semestreIndex < asignaturasPorSemestre.length - 1 + ? BorderSide(color: Theme.of(context).dividerColor) + : BorderSide.none, + bottom: BorderSide(color: Theme.of(context).dividerColor), + ), + ), + child: hasAsignatura + ? AsignaturaMallaCard(asignatura: asignaturas[rowIndex]) + : const SizedBox.shrink(), + ), + ); + }), + ), + ); + }), + ); + } +} + diff --git a/lib/screens/malla_historica/widgets/screens/malla_main_scroller.dart b/lib/screens/malla_historica/widgets/screens/malla_main_scroller.dart new file mode 100644 index 0000000..e4c89b8 --- /dev/null +++ b/lib/screens/malla_historica/widgets/screens/malla_main_scroller.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/core/models/asignaturas/asignatura_malla.dart'; +import 'package:miutem/screens/malla_historica/widgets/components/asignatura_malla_card.dart'; +import 'package:miutem/screens/malla_historica/widgets/components/semestre_header_card.dart'; + +class MallaMainScroller extends StatelessWidget { + final List asignaturas; + + const MallaMainScroller({ + super.key, + required this.asignaturas, + }); + + /// Agrupa las asignaturas por nivel (semestre) + List> get _asignaturasPorSemestre { + if (asignaturas.isEmpty) return []; + + final maxNivel = asignaturas.map((a) => a.nivel).reduce((a, b) => a > b ? a : b); + final result = List>.generate(maxNivel, (_) => []); + + for (final asignatura in asignaturas) { + if (asignatura.nivel > 0 && asignatura.nivel <= maxNivel) { + result[asignatura.nivel - 1].add(asignatura); + } + } + + return result; + } + + @override + Widget build(BuildContext context) { + if (asignaturas.isEmpty) { + return const Center( + child: Text('No hay asignaturas para mostrar'), + ); + } + + final semestres = _asignaturasPorSemestre; + + return LayoutBuilder( + builder: (context, constraints) { + final isLandscape = constraints.maxWidth > constraints.maxHeight; + final isLargeScreen = constraints.maxWidth > 600; + + // En pantallas grandes o landscape, mostrar vista de tabla scrolleable + if (isLargeScreen || isLandscape) { + return _buildTableView(context, semestres); + } + + // En pantallas pequeñas, mostrar vista de lista vertical por semestre + return _buildListView(context, semestres); + }, + ); + } + + /// Vista de tabla horizontal para pantallas grandes + Widget _buildTableView(BuildContext context, List> semestres) { + return InteractiveViewer( + constrained: false, + minScale: 0.5, + maxScale: 2.0, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: MediaQuery.of(context).size.width, + ), + child: IntrinsicWidth( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + // Header de semestres + Row( + children: List.generate( + semestres.length, + (index) => Expanded( + child: SemestreHeaderCard(semestre: index + 1), + ), + ), + ), + const Divider(height: 1), + // Contenido de asignaturas + _buildAsignaturasTable(context, semestres), + ], + ), + ), + ), + ), + ), + ); + } + + Widget _buildAsignaturasTable(BuildContext context, List> semestres) { + final maxRows = semestres.map((s) => s.length).reduce((a, b) => a > b ? a : b); + + return Column( + mainAxisSize: MainAxisSize.min, + children: List.generate(maxRows, (rowIndex) { + return IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: List.generate(semestres.length, (semestreIndex) { + final asignaturas = semestres[semestreIndex]; + final hasAsignatura = rowIndex < asignaturas.length; + + return Expanded( + child: Container( + decoration: BoxDecoration( + border: Border( + right: semestreIndex < semestres.length - 1 + ? BorderSide(color: Theme.of(context).dividerColor) + : BorderSide.none, + bottom: BorderSide(color: Theme.of(context).dividerColor), + ), + ), + child: hasAsignatura + ? AsignaturaMallaCard(asignatura: asignaturas[rowIndex]) + : const SizedBox.shrink(), + ), + ); + }), + ), + ); + }), + ); + } + + /// Vista de lista vertical para pantallas pequeñas + Widget _buildListView(BuildContext context, List> semestres) { + return ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: semestres.length, + itemBuilder: (context, semestreIndex) { + final asignaturasSemestre = semestres[semestreIndex]; + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Header del semestre + Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text( + 'Semestre ${semestreIndex + 1}', + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ), + // Asignaturas del semestre usando GridView flexible + LayoutBuilder( + builder: (context, constraints) { + // Calcular cuántas columnas caben basándose en el ancho disponible + final crossAxisCount = (constraints.maxWidth / 160).floor().clamp(1, 4); + + return GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: crossAxisCount, + childAspectRatio: 1.2, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemCount: asignaturasSemestre.length, + itemBuilder: (context, index) { + return AsignaturaMallaCard(asignatura: asignaturasSemestre[index]); + }, + ); + }, + ), + if (semestreIndex < semestres.length - 1) + const Divider(height: 32), + ], + ); + }, + ); + } +} diff --git a/lib/screens/malla_historica/widgets/screens/malla_semestres_header.dart b/lib/screens/malla_historica/widgets/screens/malla_semestres_header.dart new file mode 100644 index 0000000..8fc059b --- /dev/null +++ b/lib/screens/malla_historica/widgets/screens/malla_semestres_header.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:miutem/screens/malla_historica/widgets/components/semestre_header_card.dart'; + +class MallaSemestresHeader extends StatelessWidget { + final int cantidadSemestres; + + const MallaSemestresHeader({ + super.key, + required this.cantidadSemestres, + }); + + @override + Widget build(BuildContext context) { + return Row( + children: List.generate( + cantidadSemestres, + (index) => Expanded( + child: Container( + decoration: BoxDecoration( + border: Border( + right: index < cantidadSemestres - 1 + ? BorderSide(color: Theme.of(context).dividerColor) + : BorderSide.none, + bottom: BorderSide(color: Theme.of(context).dividerColor), + ), + ), + child: SemestreHeaderCard(semestre: index + 1), + ), + ), + ), + ); + } +} diff --git a/lib/screens/malla_historica/widgets/widgets.dart b/lib/screens/malla_historica/widgets/widgets.dart new file mode 100644 index 0000000..2a39710 --- /dev/null +++ b/lib/screens/malla_historica/widgets/widgets.dart @@ -0,0 +1,11 @@ +/// Components +library; + +export 'components/asignatura_malla_card.dart'; +export 'components/semestre_header_card.dart'; + +/// Screens +export 'screens/malla_blocks_content.dart'; +export 'screens/malla_semestres_header.dart'; +export 'screens/malla_main_scroller.dart'; + diff --git a/lib/screens/notas/notas_screen.dart b/lib/screens/notas/notas_screen.dart index 336c3d3..246250f 100644 --- a/lib/screens/notas/notas_screen.dart +++ b/lib/screens/notas/notas_screen.dart @@ -5,6 +5,7 @@ import 'package:miutem/core/models/evaluacion/evaluacion.dart'; import 'package:miutem/core/models/evaluacion/grades.dart'; import 'package:miutem/core/models/user/persona/persona.dart'; import 'package:miutem/core/services/controllers/notas_controller.dart'; +import 'package:miutem/core/utils/constants.dart'; import 'package:miutem/screens/notas/actions/cargar_asignaturas_con_notas.dart'; import 'package:miutem/screens/notas/widgets/notas.dart'; import 'package:miutem/screens/notas/widgets/promedio.dart'; @@ -13,7 +14,13 @@ import 'package:miutem/screens/notas/widgets/selector_asignatura.dart'; final emptyAsignatura = Asignatura(id: "id", nombre: "Calcular Notas", codigo: "--", tipoHora: "--", estado: "--", seccion: "--", docente: Persona(nombreCompleto: "--"), grades: Grades(notasParciales: [IEvaluacion()])); class NotasScreen extends StatefulWidget { - const NotasScreen({super.key}); + + final Asignatura? asignatura; + + const NotasScreen({ + super.key, + this.asignatura, + }); @override State createState() => _NotasScreenState(); @@ -29,6 +36,16 @@ class _NotasScreenState extends State { @override void initState() { super.initState(); + + if (widget.asignatura != null) { + if (!mounted) return; + setState(() { + asignatura = widget.asignatura; + notasController.updateWithGrades(asignatura?.grades); + }); + return; + } + cargarAsignaturasConNotas().then((asignaturas) { asignaturas = [ emptyAsignatura, @@ -55,20 +72,22 @@ class _NotasScreenState extends State { appBar: AppBar(title: const Text('Notas')), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 25), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SelectorAsignatura(asignatura: asignatura, asignaturas: asignaturas, onChanged: (Asignatura? asignatura) { - notasController.updateWithGrades(asignatura?.grades); - setState(() => this.asignatura = asignatura); - }), - const SizedBox(height: 12), - Promedio(notasController: notasController), - const SizedBox(height: 12), - Notas(notasController: notasController, canAddNotas: asignaturas != null), - const SizedBox(height: 12), - const Center(child: Text("* La función de calculadora sólo funciona para el cálculo del ramo seleccionado, no modificará ninguna nota ingresada al sistema.", style: TextStyle(color: Colors.grey, fontSize: 12))), - ], + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.asignatura == null) SelectorAsignatura(asignatura: asignatura, asignaturas: asignaturas, onChanged: (Asignatura? asignatura) { + notasController.updateWithGrades(asignatura?.grades); + setState(() => this.asignatura = asignatura); + }), + const SizedBox(height: 12), + Promedio(notasController: notasController), + const SizedBox(height: 12), + Notas(notasController: notasController, canAddNotas: asignaturas != null), + const SizedBox(height: 12), + const Center(child: Text("* La función de calculadora sólo funciona para el cálculo del ramo seleccionado, no modificará ninguna nota ingresada al sistema.", style: TextStyle(color: Colors.grey, fontSize: 12))), + ], + ), ), ), ); diff --git a/lib/screens/profile/widgets/profile_header.dart b/lib/screens/profile/widgets/profile_header.dart index 5186c36..7bcf75c 100644 --- a/lib/screens/profile/widgets/profile_header.dart +++ b/lib/screens/profile/widgets/profile_header.dart @@ -25,7 +25,6 @@ class _ProfileHeaderState extends State { @override void initState() { super.initState(); - _logger.d("ProfileHeader initialized"); _loadData(); } @@ -46,7 +45,6 @@ class _ProfileHeaderState extends State { } } catch (e) { _logger.e('Error loading carrera: $e'); - } } } diff --git a/lib/screens/profile/widgets/profile_settings.dart b/lib/screens/profile/widgets/profile_settings.dart index 574f416..4ad27a6 100644 --- a/lib/screens/profile/widgets/profile_settings.dart +++ b/lib/screens/profile/widgets/profile_settings.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:miutem/core/models/config/user_config.dart'; import 'package:miutem/styles/styles.dart'; +import 'package:miutem/widgets/feature_flag.dart'; class ProfileSettings extends StatelessWidget { const ProfileSettings({super.key}); @@ -12,12 +13,19 @@ class ProfileSettings extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Sistema', style: Theme.of(context).textTheme.bodyLarge), - SwitchListTile( + FeatureFlag('perfil.notificaciones', child: SwitchListTile( title: const Text('Habilitar Notificaciones'), subtitle: const Text('Recibir notificaciones de la aplicación'), value: UserConfig.to.notificationsEnabled.value, - onChanged: (value) => UserConfig.to.toggleNotifications(), - ), + onChanged: (value) async { + await UserConfig.to.toggleNotifications(); + + if (value) { + // Se habilitan las notificaciones, si no hay permisos, se solicita + if (context.mounted) showTextSnackbar(context, title: 'Notificaciones', message: 'Se han habilitado las notificaciones de la aplicación'); + } + }, + )), Space.small, Text('Pantalla', style: Theme.of(context).textTheme.bodyLarge), ListTile( @@ -27,27 +35,25 @@ class ProfileSettings extends StatelessWidget { ), Space.small, Text('Feedback', style: Theme.of(context).textTheme.bodyLarge), - ListTile( + FeatureFlag('perfil.bug_report', child: ListTile( title: const Text('Reportar un Bug'), subtitle: const Text('Reportar un bug en la aplicación'), onTap: () { // Implementar lógica para reportar un bug }, - ), - ListTile( + )), + FeatureFlag('perfil.feedback_report', child: ListTile( title: const Text('Sugerencias'), subtitle: const Text('Déjanos tus opiniones sobre la App'), - onTap: () { - // Implementar lógica para sugerencias - }, - ), - ListTile( + onTap: () {}, + )), + FeatureFlag('perfil.desarrolladores', child: ListTile( title: const Text('Desarrolladores de la App'), subtitle: const Text('Vé al equipo que desarrolla Mi UTEM'), onTap: () { // Implementar lógica para ver los desarrolladores de la app }, - ), + )), ], )); diff --git a/lib/screens/widgets_screens.dart b/lib/screens/widgets_screens.dart index e1300ca..6dfc0e6 100644 --- a/lib/screens/widgets_screens.dart +++ b/lib/screens/widgets_screens.dart @@ -3,7 +3,7 @@ export 'home/home_screen.dart'; // ASIGNATURAS -export 'asignaturas/asignaturas_screen.dart'; +export 'asignaturas/lista_asignaturas_screen.dart'; // APUNTES export 'tasklist/task_list_screen.dart'; diff --git a/lib/styles/navigation/bottom_navbar.dart b/lib/styles/navigation/bottom_navbar.dart index 06f16a4..e371d81 100644 --- a/lib/styles/navigation/bottom_navbar.dart +++ b/lib/styles/navigation/bottom_navbar.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:miutem/core/models/navigation/navigation_item.dart'; -import 'package:miutem/screens/asignaturas/asignaturas_screen.dart'; +import 'package:miutem/screens/asignaturas/lista_asignaturas_screen.dart'; import 'package:miutem/screens/home/home_screen.dart'; import 'package:miutem/screens/profile/profile_screen.dart'; -import 'package:miutem/screens/tasklist/task_list_screen.dart'; +import 'package:miutem/screens/tasklist/task_list_screen.dart'; import 'package:miutem/styles/theme/icons.dart'; +import 'package:miutem/widgets/feature_flag.dart'; class BottomNavBar extends StatefulWidget { const BottomNavBar({super.key}); @@ -16,35 +17,78 @@ class BottomNavBar extends StatefulWidget { class _BottomNavBarState extends State { int idx = 0; - final List screens = [ - NavigationItem(destination: const HomeScreen(), label: "Inicio", icon: AppIcons.home), - NavigationItem(destination: const AsignaturasScreen(), label: "Asignaturas", icon: AppIcons.subjects), - NavigationItem(destination: const TaskListScreen(), label: "Apuntes", icon: AppIcons.notes), - NavigationItem(destination: const ProfileScreen(), label: "Perfil", icon: AppIcons.profile), + final List allScreens = [ + NavigationItem(destination: const HomeScreen(), label: "Inicio", featureFlag: "bottom_navigation.home", icon: AppIcons.home), + NavigationItem(destination: const AsignaturasScreen(), label: "Asignaturas", featureFlag: "bottom_navigation.asignaturas", icon: AppIcons.subjects), + NavigationItem(destination: const TaskListScreen(), label: "Apuntes", featureFlag: "bottom_navigation.apuntes", icon: AppIcons.notes), + NavigationItem(destination: const ProfileScreen(), label: "Perfil", featureFlag: "bottom_navigation.perfil", icon: AppIcons.profile), ]; + List get enabledScreens { + return allScreens.where((screen) => FeatureFlag.evaluateSync(screen.featureFlag)).toList(); + } + + @override + void initState() { + super.initState(); + // Ensure the initial index is valid for enabled screens + WidgetsBinding.instance.addPostFrameCallback((_) { + final enabled = enabledScreens; + if (enabled.isNotEmpty && idx >= enabled.length) { + setState(() { + idx = 0; // Reset to first available screen + }); + } + }); + } + + void _onDestinationSelected(int selectedIdx) { + final enabled = enabledScreens; + if (selectedIdx >= 0 && selectedIdx < enabled.length) { + setState(() { + idx = selectedIdx; + }); + } + } + @override - Widget build(BuildContext context) => Scaffold( - extendBody: true, - bottomNavigationBar: NavigationBar( - height: 65, - elevation: 0, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - labelBehavior: NavigationDestinationLabelBehavior.alwaysShow, - onDestinationSelected: (idx) => setState(() => this.idx = idx), - selectedIndex: idx, - destinations: screens.map((e) => NavigationDestination( - selectedIcon: Icon(e.icon, fill: 1), - icon: Icon(e.icon, weight: 600), - label: e.label, - )).toList(), - ), - body: IndexedStack( - index: idx, - children: screens.map((e) => SafeArea( - minimum: const EdgeInsets.symmetric(vertical: 20), - child: e.destination, - )).toList(), - ), - ); + Widget build(BuildContext context) { + final enabled = enabledScreens; + + // If no screens are enabled, show a fallback (this shouldn't happen in practice) + if (enabled.isEmpty) { + return const Scaffold( + body: Center( + child: Text('No navigation items available'), + ), + ); + } + + // Ensure current index is valid + final currentIdx = idx >= enabled.length ? 0 : idx; + + return Scaffold( + extendBody: true, + bottomNavigationBar: NavigationBar( + height: 65, + elevation: 0, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + labelBehavior: NavigationDestinationLabelBehavior.alwaysShow, + onDestinationSelected: _onDestinationSelected, + selectedIndex: currentIdx, + destinations: enabled.map((e) => NavigationDestination( + selectedIcon: Icon(e.icon, fill: 1), + icon: Icon(e.icon, weight: 600), + label: e.label, + )).toList(), + ), + body: IndexedStack( + index: currentIdx, + children: enabled.map((e) => SafeArea( + minimum: const EdgeInsets.symmetric(vertical: 20), + child: e.destination, + )).toList(), + ), + ); + } } \ No newline at end of file diff --git a/lib/styles/theme/space.dart b/lib/styles/theme/space.dart index ec5255e..1c259d9 100644 --- a/lib/styles/theme/space.dart +++ b/lib/styles/theme/space.dart @@ -9,4 +9,15 @@ class Space { static const Widget small = SizedBox(height: 12); /// 8 PX para separar elementos muy similares static const Widget xSmall = SizedBox(height: 8); +} + +class HorizontalSpace { + /// 20 PX para separar elementos muy distintos o secciones + static const Widget large = SizedBox(width: 20); + /// 16 PX para separar elementos similares con bordes + static const Widget medium = SizedBox(width: 16); + /// 12 PX para separar elementos similares pequeños + static const Widget small = SizedBox(width: 12); + /// 8 PX para separar elementos muy similares + static const Widget xSmall = SizedBox(width: 8); } \ No newline at end of file diff --git a/lib/styles/theme/theme.dart b/lib/styles/theme/theme.dart index 46d5a04..f6cad5b 100644 --- a/lib/styles/theme/theme.dart +++ b/lib/styles/theme/theme.dart @@ -88,7 +88,7 @@ class AppTheme { scaffoldBackgroundColor: scaffoldBackgroundColor, /// Tema de las tarjetas - cardTheme: CardTheme( + cardTheme: CardThemeData( color: scaffoldBackgroundColor, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10), side: BorderSide(color: Theme.of(context).dividerColor)), ), @@ -171,7 +171,7 @@ class AppTheme { scaffoldBackgroundColor: scaffoldBackgroundColorDark, /// Tema de las tarjetas - cardTheme: CardTheme( + cardTheme: CardThemeData( color: scaffoldBackgroundColorDark, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10), side: BorderSide(color: Theme.of(context).dividerColor)), ), @@ -238,7 +238,7 @@ class AppTheme { ), /// Tema del dialogo - dialogTheme: DialogTheme( + dialogTheme: DialogThemeData( backgroundColor: scaffoldBackgroundColorDark, titleTextStyle: GoogleFonts.inter( color: white, diff --git a/lib/widgets/feature_flag.dart b/lib/widgets/feature_flag.dart new file mode 100644 index 0000000..3fbcfd7 --- /dev/null +++ b/lib/widgets/feature_flag.dart @@ -0,0 +1,326 @@ +import 'dart:convert'; +import 'package:firebase_remote_config/firebase_remote_config.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:logger/logger.dart'; +import 'package:miutem/core/services/firebase/remote_config_service.dart'; + +/// A widget that conditionally renders its child based on a feature flag value from Firebase Remote Config. +/// +/// Usage: +/// ```dart +/// FeatureFlag('bottom_navigation.novedades', child: const Text('This text will be shown if the feature flag is true')) +/// ``` +class FeatureFlag extends StatelessWidget { + /// The feature flag key to evaluate (supports dot notation for nested flags) + final String flagKey; + + /// The child widget to render if the feature flag is enabled + final Widget child; + + /// The fallback widget to render if the feature flag is disabled (optional) + final Widget? fallback; + + /// Whether to show debug information in development mode + final bool showDebugInfo; + + const FeatureFlag( + this.flagKey, { + super.key, + required this.child, + this.fallback, + this.showDebugInfo = false, + }); + + /// Evaluates a feature flag and returns its boolean value + /// + /// Usage: + /// ```dart + /// const featureFlagValue = await FeatureFlag.evaluate('bottom_navigation.novedades'); + /// ``` + static Future evaluate(String flagKey) async { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + + // Ensure remote config is initialized + if (Get.isRegistered()) { + // Remote config should already be initialized via the service + } else { + // Fallback initialization if service is not available + await remoteConfig.setConfigSettings(RemoteConfigSettings( + fetchTimeout: const Duration(minutes: 1), + minimumFetchInterval: const Duration(hours: 12), + )); + await remoteConfig.fetchAndActivate(); + } + + return _evaluateNestedFlag(remoteConfig, flagKey); + } catch (e) { + // Return false by default if there's an error + debugPrint('FeatureFlag: Error evaluating flag "$flagKey": $e'); + return false; + } + } + + /// Evaluates a feature flag synchronously (uses cached values) + /// + /// Usage: + /// ```dart + /// final isEnabled = FeatureFlag.evaluateSync('bottom_navigation.novedades'); + /// ``` + static bool evaluateSync(String flagKey) { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + return _evaluateNestedFlag(remoteConfig, flagKey); + } catch (e) { + debugPrint('FeatureFlag: Error evaluating flag "$flagKey" synchronously: $e'); + return false; + } + } + + /// Internal method to evaluate nested feature flags from the JSON structure + static bool _evaluateNestedFlag(FirebaseRemoteConfig remoteConfig, String flagKey) { + try { + // Get the feature_flags JSON from Remote Config + final featureFlagsJson = remoteConfig.getString('feature_flags'); + + if (featureFlagsJson.isEmpty) { + Logger().w('FeatureFlag: No feature_flags parameter found in Remote Config'); + return false; + } + + // Parse the JSON + final Map featureFlags = jsonDecode(featureFlagsJson); + + // Navigate through the nested structure using dot notation + final keyParts = flagKey.split('.'); + dynamic currentLevel = featureFlags; + + for (final part in keyParts) { + if (currentLevel is Map && currentLevel.containsKey(part)) { + currentLevel = currentLevel[part]; + } else { + Logger().w('FeatureFlag: Feature flag "$flagKey" not found in remote config, defaulting to false'); + return false; + } + } + + // Return the boolean value, defaulting to false if it's not a boolean + if (currentLevel is bool) { + return currentLevel; + } else { + Logger().w('FeatureFlag: Value for "$flagKey" is not a boolean: $currentLevel, defaulting to false'); + return false; + } + } catch (e) { + Logger().e('FeatureFlag: Error parsing feature flags JSON for "$flagKey": $e, defaulting to false'); + return false; + } + } + + /// Gets the string value of a nested feature flag + static String getString(String flagKey, {String defaultValue = ''}) { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + final featureFlagsJson = remoteConfig.getString('feature_flags'); + + if (featureFlagsJson.isEmpty) { + return defaultValue; + } + + final Map featureFlags = jsonDecode(featureFlagsJson); + final keyParts = flagKey.split('.'); + dynamic currentLevel = featureFlags; + + for (final part in keyParts) { + if (currentLevel is Map && currentLevel.containsKey(part)) { + currentLevel = currentLevel[part]; + } else { + return defaultValue; + } + } + + return currentLevel?.toString() ?? defaultValue; + } catch (e) { + debugPrint('FeatureFlag: Error getting string value for flag "$flagKey": $e'); + return defaultValue; + } + } + + /// Gets the int value of a nested feature flag + static int getInt(String flagKey, {int defaultValue = 0}) { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + final featureFlagsJson = remoteConfig.getString('feature_flags'); + + if (featureFlagsJson.isEmpty) { + return defaultValue; + } + + final Map featureFlags = jsonDecode(featureFlagsJson); + final keyParts = flagKey.split('.'); + dynamic currentLevel = featureFlags; + + for (final part in keyParts) { + if (currentLevel is Map && currentLevel.containsKey(part)) { + currentLevel = currentLevel[part]; + } else { + return defaultValue; + } + } + + if (currentLevel is int) { + return currentLevel; + } else if (currentLevel is num) { + return currentLevel.toInt(); + } + + return defaultValue; + } catch (e) { + debugPrint('FeatureFlag: Error getting int value for flag "$flagKey": $e'); + return defaultValue; + } + } + + /// Gets the double value of a nested feature flag + static double getDouble(String flagKey, {double defaultValue = 0.0}) { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + final featureFlagsJson = remoteConfig.getString('feature_flags'); + + if (featureFlagsJson.isEmpty) { + return defaultValue; + } + + final Map featureFlags = jsonDecode(featureFlagsJson); + final keyParts = flagKey.split('.'); + dynamic currentLevel = featureFlags; + + for (final part in keyParts) { + if (currentLevel is Map && currentLevel.containsKey(part)) { + currentLevel = currentLevel[part]; + } else { + return defaultValue; + } + } + + if (currentLevel is double) { + return currentLevel; + } else if (currentLevel is num) { + return currentLevel.toDouble(); + } + + return defaultValue; + } catch (e) { + debugPrint('FeatureFlag: Error getting double value for flag "$flagKey": $e'); + return defaultValue; + } + } + + /// Gets the raw value of a nested feature flag (can be any type) + static dynamic getValue(String flagKey, {dynamic defaultValue}) { + try { + final remoteConfig = FirebaseRemoteConfig.instance; + final featureFlagsJson = remoteConfig.getString('feature_flags'); + + if (featureFlagsJson.isEmpty) { + return defaultValue; + } + + final Map featureFlags = jsonDecode(featureFlagsJson); + final keyParts = flagKey.split('.'); + dynamic currentLevel = featureFlags; + + for (final part in keyParts) { + if (currentLevel is Map && currentLevel.containsKey(part)) { + currentLevel = currentLevel[part]; + } else { + return defaultValue; + } + } + + return currentLevel ?? defaultValue; + } catch (e) { + debugPrint('FeatureFlag: Error getting value for flag "$flagKey": $e'); + return defaultValue; + } + } + + @override + Widget build(BuildContext context) { + final isEnabled = evaluateSync(flagKey); + + if (showDebugInfo && kDebugMode) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: isEnabled ? Colors.green.withValues(alpha: 0.2) : Colors.red.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + 'FeatureFlag: $flagKey = $isEnabled', + style: TextStyle( + fontSize: 10, + color: isEnabled ? Colors.green[800] : Colors.red[800], + fontFamily: 'monospace', + ), + ), + ), + const SizedBox(height: 4), + if (isEnabled) child else (fallback ?? const SizedBox.shrink()), + ], + ); + } + + return isEnabled ? child : (fallback ?? const SizedBox.shrink()); + } +} + +/// A builder widget that provides the feature flag value to its builder function +/// +/// Usage: +/// ```dart +/// FeatureFlagBuilder( +/// 'MY_FEATURE_FLAG', +/// builder: (context, isEnabled) { +/// return Text(isEnabled ? 'Feature is ON' : 'Feature is OFF'); +/// }, +/// ) +/// ``` +class FeatureFlagBuilder extends StatelessWidget { + final String flagKey; + final Widget Function(BuildContext context, bool isEnabled) builder; + + const FeatureFlagBuilder( + this.flagKey, { + super.key, + required this.builder, + }); + + @override + Widget build(BuildContext context) { + final isEnabled = FeatureFlag.evaluateSync(flagKey); + return builder(context, isEnabled); + } +} + +/// Extension to add feature flag functionality to any widget +extension FeatureFlagExtension on Widget { + /// Wraps this widget with a feature flag check + /// + /// Usage: + /// ```dart + /// const Text('Hello').withFeatureFlag('MY_FEATURE_FLAG') + /// ``` + Widget withFeatureFlag(String flagKey, {Widget? fallback}) { + return FeatureFlag( + flagKey, + fallback: fallback, + child: this, + ); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..af49e3c --- /dev/null +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,38 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import awesome_notifications +import awesome_notifications_core +import cloud_firestore +import file_saver +import firebase_analytics +import firebase_core +import firebase_remote_config +import flutter_secure_storage_macos +import package_info_plus +import share_plus +import shared_preferences_foundation +import sqflite_darwin +import url_launcher_macos +import video_player_avfoundation + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AwesomeNotificationsPlugin.register(with: registry.registrar(forPlugin: "AwesomeNotificationsPlugin")) + AwesomeNotificationsCorePlugin.register(with: registry.registrar(forPlugin: "AwesomeNotificationsCorePlugin")) + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) + FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin")) + FirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FirebaseAnalyticsPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FirebaseRemoteConfigPlugin.register(with: registry.registrar(forPlugin: "FirebaseRemoteConfigPlugin")) + FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) +} diff --git a/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/macos/Flutter/ephemeral/Flutter-Generated.xcconfig new file mode 100644 index 0000000..dfb069b --- /dev/null +++ b/macos/Flutter/ephemeral/Flutter-Generated.xcconfig @@ -0,0 +1,13 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=/opt/homebrew/share/flutter +FLUTTER_APPLICATION_PATH=/Users/fran/Development/exdevutem/miutem +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_TARGET=/Users/fran/Development/exdevutem/miutem/lib/main.dart +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=3.0.0 +FLUTTER_BUILD_NUMBER=142 +DART_DEFINES=RkxVVFRFUl9WRVJTSU9OPTMuMzguNg==,RkxVVFRFUl9DSEFOTkVMPXN0YWJsZQ==,RkxVVFRFUl9HSVRfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9mbHV0dGVyL2ZsdXR0ZXIuZ2l0,RkxVVFRFUl9GUkFNRVdPUktfUkVWSVNJT049OGI4NzI4Njg0OQ==,RkxVVFRFUl9FTkdJTkVfUkVWSVNJT049NzhmYzMwMTJlNA==,RkxVVFRFUl9EQVJUX1ZFUlNJT049My4xMC43 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=/Users/fran/Development/exdevutem/miutem/.dart_tool/package_config.json diff --git a/macos/Flutter/ephemeral/flutter_export_environment.sh b/macos/Flutter/ephemeral/flutter_export_environment.sh new file mode 100755 index 0000000..a3b63fc --- /dev/null +++ b/macos/Flutter/ephemeral/flutter_export_environment.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/opt/homebrew/share/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/fran/Development/exdevutem/miutem" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=/Users/fran/Development/exdevutem/miutem/lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=3.0.0" +export "FLUTTER_BUILD_NUMBER=142" +export "DART_DEFINES=RkxVVFRFUl9WRVJTSU9OPTMuMzguNg==,RkxVVFRFUl9DSEFOTkVMPXN0YWJsZQ==,RkxVVFRFUl9HSVRfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9mbHV0dGVyL2ZsdXR0ZXIuZ2l0,RkxVVFRFUl9GUkFNRVdPUktfUkVWSVNJT049OGI4NzI4Njg0OQ==,RkxVVFRFUl9FTkdJTkVfUkVWSVNJT049NzhmYzMwMTJlNA==,RkxVVFRFUl9EQVJUX1ZFUlNJT049My4xMC43" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=/Users/fran/Development/exdevutem/miutem/.dart_tool/package_config.json" diff --git a/macos/Podfile b/macos/Podfile index f85f88f..dd57f52 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :macos, '11.5' +platform :osx, '10.15' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -30,10 +30,6 @@ target 'Runner' do use_frameworks! use_modular_headers! - pod 'FirebaseFirestore', - :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', - :tag => '11.4.0' - flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths @@ -43,5 +39,10 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_macos_build_settings(target) + + # Ensure all Pods use a supported macOS deployment target. + target.build_configurations.each do |config| + config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '10.15' + end end end diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..62efac2 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,1574 @@ +PODS: + - abseil/algorithm (1.20240722.0): + - abseil/algorithm/algorithm (= 1.20240722.0) + - abseil/algorithm/container (= 1.20240722.0) + - abseil/algorithm/algorithm (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/algorithm/container (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base (1.20240722.0): + - abseil/base/atomic_hook (= 1.20240722.0) + - abseil/base/base (= 1.20240722.0) + - abseil/base/base_internal (= 1.20240722.0) + - abseil/base/config (= 1.20240722.0) + - abseil/base/core_headers (= 1.20240722.0) + - abseil/base/cycleclock_internal (= 1.20240722.0) + - abseil/base/dynamic_annotations (= 1.20240722.0) + - abseil/base/endian (= 1.20240722.0) + - abseil/base/errno_saver (= 1.20240722.0) + - abseil/base/fast_type_id (= 1.20240722.0) + - abseil/base/log_severity (= 1.20240722.0) + - abseil/base/malloc_internal (= 1.20240722.0) + - abseil/base/no_destructor (= 1.20240722.0) + - abseil/base/nullability (= 1.20240722.0) + - abseil/base/poison (= 1.20240722.0) + - abseil/base/prefetch (= 1.20240722.0) + - abseil/base/pretty_function (= 1.20240722.0) + - abseil/base/raw_logging_internal (= 1.20240722.0) + - abseil/base/spinlock_wait (= 1.20240722.0) + - abseil/base/strerror (= 1.20240722.0) + - abseil/base/throw_delegate (= 1.20240722.0) + - abseil/base/atomic_hook (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/base (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/cycleclock_internal + - abseil/base/dynamic_annotations + - abseil/base/log_severity + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/spinlock_wait + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/base_internal (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/config (1.20240722.0): + - abseil/xcprivacy + - abseil/base/core_headers (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/cycleclock_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/xcprivacy + - abseil/base/dynamic_annotations (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/endian (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/xcprivacy + - abseil/base/errno_saver (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/fast_type_id (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/base/log_severity (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/malloc_internal (1.20240722.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/base/no_destructor (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/xcprivacy + - abseil/base/nullability (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/base/poison (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal + - abseil/xcprivacy + - abseil/base/prefetch (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/base/pretty_function (1.20240722.0): + - abseil/xcprivacy + - abseil/base/raw_logging_internal (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/base/log_severity + - abseil/xcprivacy + - abseil/base/spinlock_wait (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/xcprivacy + - abseil/base/strerror (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/xcprivacy + - abseil/base/throw_delegate (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/cleanup/cleanup (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/cleanup/cleanup_internal + - abseil/xcprivacy + - abseil/cleanup/cleanup_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/common (1.20240722.0): + - abseil/meta/type_traits + - abseil/types/optional + - abseil/xcprivacy + - abseil/container/common_policy_traits (1.20240722.0): + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/compressed_tuple (1.20240722.0): + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/container_memory (1.20240722.0): + - abseil/base/config + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/fixed_array (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/throw_delegate + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/xcprivacy + - abseil/container/flat_hash_map (1.20240722.0): + - abseil/algorithm/container + - abseil/base/core_headers + - abseil/container/container_memory + - abseil/container/hash_container_defaults + - abseil/container/raw_hash_map + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/flat_hash_set (1.20240722.0): + - abseil/algorithm/container + - abseil/base/core_headers + - abseil/container/container_memory + - abseil/container/hash_container_defaults + - abseil/container/raw_hash_set + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/hash_container_defaults (1.20240722.0): + - abseil/base/config + - abseil/container/hash_function_defaults + - abseil/xcprivacy + - abseil/container/hash_function_defaults (1.20240722.0): + - abseil/base/config + - abseil/container/common + - abseil/hash/hash + - abseil/meta/type_traits + - abseil/strings/cord + - abseil/strings/strings + - abseil/xcprivacy + - abseil/container/hash_policy_traits (1.20240722.0): + - abseil/container/common_policy_traits + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/hashtable_debug_hooks (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/container/hashtablez_sampler (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/memory/memory + - abseil/profiling/exponential_biased + - abseil/profiling/sample_recorder + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/inlined_vector (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/container/inlined_vector_internal + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/container/inlined_vector_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/span + - abseil/xcprivacy + - abseil/container/layout (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/demangle_internal + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/types/span + - abseil/utility/utility + - abseil/xcprivacy + - abseil/container/raw_hash_map (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/container/container_memory + - abseil/container/raw_hash_set + - abseil/xcprivacy + - abseil/container/raw_hash_set (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/endian + - abseil/base/prefetch + - abseil/base/raw_logging_internal + - abseil/container/common + - abseil/container/compressed_tuple + - abseil/container/container_memory + - abseil/container/hash_policy_traits + - abseil/container/hashtable_debug_hooks + - abseil/container/hashtablez_sampler + - abseil/hash/hash + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/crc/cpu_detect (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/xcprivacy + - abseil/crc/crc32c (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/prefetch + - abseil/crc/cpu_detect + - abseil/crc/crc_internal + - abseil/crc/non_temporal_memcpy + - abseil/strings/str_format + - abseil/strings/strings + - abseil/xcprivacy + - abseil/crc/crc_cord_state (1.20240722.0): + - abseil/base/config + - abseil/base/no_destructor + - abseil/crc/crc32c + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/crc/crc_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/prefetch + - abseil/base/raw_logging_internal + - abseil/crc/cpu_detect + - abseil/memory/memory + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/crc/non_temporal_arm_intrinsics (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/crc/non_temporal_memcpy (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/crc/non_temporal_arm_intrinsics + - abseil/xcprivacy + - abseil/debugging/bounded_utf8_length_sequence (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/debugging/debugging_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/errno_saver + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/debugging/decode_rust_punycode (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/debugging/bounded_utf8_length_sequence + - abseil/debugging/utf8_for_code_point + - abseil/xcprivacy + - abseil/debugging/demangle_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/debugging/demangle_rust + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/debugging/demangle_rust (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/decode_rust_punycode + - abseil/xcprivacy + - abseil/debugging/examine_stack (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/xcprivacy + - abseil/debugging/stacktrace (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/debugging/debugging_internal + - abseil/xcprivacy + - abseil/debugging/symbolize (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/debugging_internal + - abseil/debugging/demangle_internal + - abseil/strings/strings + - abseil/xcprivacy + - abseil/debugging/utf8_for_code_point (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/flags/commandlineflag (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/flags/commandlineflag_internal + - abseil/strings/strings + - abseil/types/optional + - abseil/xcprivacy + - abseil/flags/commandlineflag_internal (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/xcprivacy + - abseil/flags/config (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/path_util + - abseil/flags/program_name + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/flags/flag (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/commandlineflag + - abseil/flags/config + - abseil/flags/flag_internal + - abseil/flags/reflection + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/flag_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/flags/config + - abseil/flags/marshalling + - abseil/flags/reflection + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/utility/utility + - abseil/xcprivacy + - abseil/flags/marshalling (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/numeric/int128 + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/optional + - abseil/xcprivacy + - abseil/flags/path_util (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/private_handle_accessor (1.20240722.0): + - abseil/base/config + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/strings/strings + - abseil/xcprivacy + - abseil/flags/program_name (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/flags/path_util + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/flags/reflection (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/container/flat_hash_map + - abseil/flags/commandlineflag + - abseil/flags/commandlineflag_internal + - abseil/flags/config + - abseil/flags/private_handle_accessor + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/functional/any_invocable (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/functional/bind_front (1.20240722.0): + - abseil/base/base_internal + - abseil/container/compressed_tuple + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/xcprivacy + - abseil/functional/function_ref (1.20240722.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/functional/any_invocable + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/hash/city (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/xcprivacy + - abseil/hash/hash (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/container/fixed_array + - abseil/functional/function_ref + - abseil/hash/city + - abseil/hash/low_level_hash + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/types/optional + - abseil/types/variant + - abseil/utility/utility + - abseil/xcprivacy + - abseil/hash/low_level_hash (1.20240722.0): + - abseil/base/config + - abseil/base/endian + - abseil/base/prefetch + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/log/absl_check (1.20240722.0): + - abseil/log/internal/check_impl + - abseil/xcprivacy + - abseil/log/absl_log (1.20240722.0): + - abseil/log/internal/log_impl + - abseil/xcprivacy + - abseil/log/absl_vlog_is_on (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/vlog_config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/check (1.20240722.0): + - abseil/log/internal/check_impl + - abseil/log/internal/check_op + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/globals (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/hash/hash + - abseil/log/internal/vlog_config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/append_truncated (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/check_impl (1.20240722.0): + - abseil/base/core_headers + - abseil/log/internal/check_op + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/internal/check_op (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/nullguard + - abseil/log/internal/nullstream + - abseil/log/internal/strip + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/conditions (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/log/internal/voidify + - abseil/xcprivacy + - abseil/log/internal/config (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/log/internal/fnmatch (1.20240722.0): + - abseil/base/config + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/format (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/append_truncated + - abseil/log/internal/config + - abseil/log/internal/globals + - abseil/strings/str_format + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/globals (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/strings/strings + - abseil/time/time + - abseil/xcprivacy + - abseil/log/internal/log_impl (1.20240722.0): + - abseil/log/absl_vlog_is_on + - abseil/log/internal/conditions + - abseil/log/internal/log_message + - abseil/log/internal/strip + - abseil/xcprivacy + - abseil/log/internal/log_message (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/base/strerror + - abseil/container/inlined_vector + - abseil/debugging/examine_stack + - abseil/log/globals + - abseil/log/internal/append_truncated + - abseil/log/internal/format + - abseil/log/internal/globals + - abseil/log/internal/log_sink_set + - abseil/log/internal/nullguard + - abseil/log/internal/proto + - abseil/log/log_entry + - abseil/log/log_sink + - abseil/log/log_sink_registry + - abseil/memory/memory + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/log_sink_set (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/cleanup/cleanup + - abseil/log/globals + - abseil/log/internal/config + - abseil/log/internal/globals + - abseil/log/log_entry + - abseil/log/log_sink + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/nullguard (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/log/internal/nullstream (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/strings/strings + - abseil/xcprivacy + - abseil/log/internal/proto (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/log/internal/strip (1.20240722.0): + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/log_message + - abseil/log/internal/nullstream + - abseil/xcprivacy + - abseil/log/internal/vlog_config (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/log/internal/fnmatch + - abseil/memory/memory + - abseil/strings/strings + - abseil/synchronization/synchronization + - abseil/types/optional + - abseil/xcprivacy + - abseil/log/internal/voidify (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/log/log (1.20240722.0): + - abseil/log/internal/log_impl + - abseil/log/vlog_is_on + - abseil/xcprivacy + - abseil/log/log_entry (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/log/internal/config + - abseil/strings/strings + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/log/log_sink (1.20240722.0): + - abseil/base/config + - abseil/log/log_entry + - abseil/xcprivacy + - abseil/log/log_sink_registry (1.20240722.0): + - abseil/base/config + - abseil/log/internal/log_sink_set + - abseil/log/log_sink + - abseil/xcprivacy + - abseil/log/vlog_is_on (1.20240722.0): + - abseil/log/absl_vlog_is_on + - abseil/xcprivacy + - abseil/memory (1.20240722.0): + - abseil/memory/memory (= 1.20240722.0) + - abseil/memory/memory (1.20240722.0): + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/meta (1.20240722.0): + - abseil/meta/type_traits (= 1.20240722.0) + - abseil/meta/type_traits (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/numeric/bits (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/numeric/int128 (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/numeric/bits + - abseil/types/compare + - abseil/xcprivacy + - abseil/numeric/representation (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/profiling/exponential_biased (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/xcprivacy + - abseil/profiling/sample_recorder (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/xcprivacy + - abseil/random/bit_gen_ref (1.20240722.0): + - abseil/base/core_headers + - abseil/base/fast_type_id + - abseil/meta/type_traits + - abseil/random/internal/distribution_caller + - abseil/random/internal/fast_uniform_bits + - abseil/random/random + - abseil/xcprivacy + - abseil/random/distributions (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/random/internal/distribution_caller + - abseil/random/internal/fast_uniform_bits + - abseil/random/internal/fastmath + - abseil/random/internal/generate_real + - abseil/random/internal/iostream_state_saver + - abseil/random/internal/traits + - abseil/random/internal/uniform_helper + - abseil/random/internal/wide_multiply + - abseil/strings/strings + - abseil/xcprivacy + - abseil/random/internal/distribution_caller (1.20240722.0): + - abseil/base/config + - abseil/base/fast_type_id + - abseil/utility/utility + - abseil/xcprivacy + - abseil/random/internal/fast_uniform_bits (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/fastmath (1.20240722.0): + - abseil/numeric/bits + - abseil/xcprivacy + - abseil/random/internal/generate_real (1.20240722.0): + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/random/internal/fastmath + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/iostream_state_saver (1.20240722.0): + - abseil/meta/type_traits + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/random/internal/nonsecure_base (1.20240722.0): + - abseil/base/core_headers + - abseil/container/inlined_vector + - abseil/meta/type_traits + - abseil/random/internal/pool_urbg + - abseil/random/internal/salted_seed_seq + - abseil/random/internal/seed_material + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/pcg_engine (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/random/internal/fastmath + - abseil/random/internal/iostream_state_saver + - abseil/xcprivacy + - abseil/random/internal/platform (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/random/internal/pool_urbg (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/random/internal/randen + - abseil/random/internal/seed_material + - abseil/random/internal/traits + - abseil/random/seed_gen_exception + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/randen (1.20240722.0): + - abseil/base/raw_logging_internal + - abseil/random/internal/platform + - abseil/random/internal/randen_hwaes + - abseil/random/internal/randen_slow + - abseil/xcprivacy + - abseil/random/internal/randen_engine (1.20240722.0): + - abseil/base/endian + - abseil/meta/type_traits + - abseil/random/internal/iostream_state_saver + - abseil/random/internal/randen + - abseil/xcprivacy + - abseil/random/internal/randen_hwaes (1.20240722.0): + - abseil/base/config + - abseil/random/internal/platform + - abseil/random/internal/randen_hwaes_impl + - abseil/xcprivacy + - abseil/random/internal/randen_hwaes_impl (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/numeric/int128 + - abseil/random/internal/platform + - abseil/xcprivacy + - abseil/random/internal/randen_slow (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/numeric/int128 + - abseil/random/internal/platform + - abseil/xcprivacy + - abseil/random/internal/salted_seed_seq (1.20240722.0): + - abseil/container/inlined_vector + - abseil/meta/type_traits + - abseil/random/internal/seed_material + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/seed_material (1.20240722.0): + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/random/internal/fast_uniform_bits + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/random/internal/traits (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/xcprivacy + - abseil/random/internal/uniform_helper (1.20240722.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/internal/wide_multiply (1.20240722.0): + - abseil/base/config + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/random/internal/traits + - abseil/xcprivacy + - abseil/random/random (1.20240722.0): + - abseil/random/distributions + - abseil/random/internal/nonsecure_base + - abseil/random/internal/pcg_engine + - abseil/random/internal/pool_urbg + - abseil/random/internal/randen_engine + - abseil/random/seed_sequences + - abseil/xcprivacy + - abseil/random/seed_gen_exception (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/random/seed_sequences (1.20240722.0): + - abseil/base/config + - abseil/base/nullability + - abseil/random/internal/pool_urbg + - abseil/random/internal/salted_seed_seq + - abseil/random/internal/seed_material + - abseil/random/seed_gen_exception + - abseil/strings/string_view + - abseil/types/span + - abseil/xcprivacy + - abseil/status/status (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/no_destructor + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/strerror + - abseil/container/inlined_vector + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/functional/function_ref + - abseil/memory/memory + - abseil/strings/cord + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/status/statusor (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/meta/type_traits + - abseil/status/status + - abseil/strings/has_ostream_operator + - abseil/strings/str_format + - abseil/strings/strings + - abseil/types/variant + - abseil/utility/utility + - abseil/xcprivacy + - abseil/strings/charset (1.20240722.0): + - abseil/base/core_headers + - abseil/strings/string_view + - abseil/xcprivacy + - abseil/strings/cord (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/container/inlined_vector + - abseil/crc/crc32c + - abseil/crc/crc_cord_state + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/strings/cord_internal + - abseil/strings/cordz_functions + - abseil/strings/cordz_info + - abseil/strings/cordz_statistics + - abseil/strings/cordz_update_scope + - abseil/strings/cordz_update_tracker + - abseil/strings/internal + - abseil/strings/strings + - abseil/types/compare + - abseil/types/optional + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cord_internal (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/base/throw_delegate + - abseil/container/compressed_tuple + - abseil/container/container_memory + - abseil/container/inlined_vector + - abseil/container/layout + - abseil/crc/crc_cord_state + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cordz_functions (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/profiling/exponential_biased + - abseil/xcprivacy + - abseil/strings/cordz_handle (1.20240722.0): + - abseil/base/config + - abseil/base/no_destructor + - abseil/base/raw_logging_internal + - abseil/synchronization/synchronization + - abseil/xcprivacy + - abseil/strings/cordz_info (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/container/inlined_vector + - abseil/debugging/stacktrace + - abseil/strings/cord_internal + - abseil/strings/cordz_functions + - abseil/strings/cordz_handle + - abseil/strings/cordz_statistics + - abseil/strings/cordz_update_tracker + - abseil/synchronization/synchronization + - abseil/time/time + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/cordz_statistics (1.20240722.0): + - abseil/base/config + - abseil/strings/cordz_update_tracker + - abseil/xcprivacy + - abseil/strings/cordz_update_scope (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/strings/cord_internal + - abseil/strings/cordz_info + - abseil/strings/cordz_update_tracker + - abseil/xcprivacy + - abseil/strings/cordz_update_tracker (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/strings/has_ostream_operator (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/strings/internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/strings/str_format (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/strings/str_format_internal + - abseil/strings/string_view + - abseil/types/span + - abseil/xcprivacy + - abseil/strings/str_format_internal (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/container/fixed_array + - abseil/container/inlined_vector + - abseil/functional/function_ref + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/numeric/representation + - abseil/strings/strings + - abseil/types/optional + - abseil/types/span + - abseil/utility/utility + - abseil/xcprivacy + - abseil/strings/string_view (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/throw_delegate + - abseil/xcprivacy + - abseil/strings/strings (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/nullability + - abseil/base/raw_logging_internal + - abseil/base/throw_delegate + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/numeric/bits + - abseil/numeric/int128 + - abseil/strings/charset + - abseil/strings/internal + - abseil/strings/string_view + - abseil/xcprivacy + - abseil/synchronization/graphcycles_internal (1.20240722.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/synchronization/kernel_timeout_internal (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/time/time + - abseil/xcprivacy + - abseil/synchronization/synchronization (1.20240722.0): + - abseil/base/atomic_hook + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/synchronization/graphcycles_internal + - abseil/synchronization/kernel_timeout_internal + - abseil/time/time + - abseil/xcprivacy + - abseil/time (1.20240722.0): + - abseil/time/internal (= 1.20240722.0) + - abseil/time/time (= 1.20240722.0) + - abseil/time/internal (1.20240722.0): + - abseil/time/internal/cctz (= 1.20240722.0) + - abseil/time/internal/cctz (1.20240722.0): + - abseil/time/internal/cctz/civil_time (= 1.20240722.0) + - abseil/time/internal/cctz/time_zone (= 1.20240722.0) + - abseil/time/internal/cctz/civil_time (1.20240722.0): + - abseil/base/config + - abseil/xcprivacy + - abseil/time/internal/cctz/time_zone (1.20240722.0): + - abseil/base/config + - abseil/time/internal/cctz/civil_time + - abseil/xcprivacy + - abseil/time/time (1.20240722.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/time/internal/cctz/civil_time + - abseil/time/internal/cctz/time_zone + - abseil/types/optional + - abseil/xcprivacy + - abseil/types (1.20240722.0): + - abseil/types/any (= 1.20240722.0) + - abseil/types/bad_any_cast (= 1.20240722.0) + - abseil/types/bad_any_cast_impl (= 1.20240722.0) + - abseil/types/bad_optional_access (= 1.20240722.0) + - abseil/types/bad_variant_access (= 1.20240722.0) + - abseil/types/compare (= 1.20240722.0) + - abseil/types/optional (= 1.20240722.0) + - abseil/types/span (= 1.20240722.0) + - abseil/types/variant (= 1.20240722.0) + - abseil/types/any (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/fast_type_id + - abseil/meta/type_traits + - abseil/types/bad_any_cast + - abseil/utility/utility + - abseil/xcprivacy + - abseil/types/bad_any_cast (1.20240722.0): + - abseil/base/config + - abseil/types/bad_any_cast_impl + - abseil/xcprivacy + - abseil/types/bad_any_cast_impl (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/bad_optional_access (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/bad_variant_access (1.20240722.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/xcprivacy + - abseil/types/compare (1.20240722.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/types/optional (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/nullability + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/bad_optional_access + - abseil/utility/utility + - abseil/xcprivacy + - abseil/types/span (1.20240722.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/nullability + - abseil/base/throw_delegate + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/types/variant (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/types/bad_variant_access + - abseil/utility/utility + - abseil/xcprivacy + - abseil/utility/utility (1.20240722.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/meta/type_traits + - abseil/xcprivacy + - abseil/xcprivacy (1.20240722.0) + - awesome_notifications (0.0.1): + - FlutterMacOS + - awesome_notifications_core (0.0.1): + - FlutterMacOS + - BoringSSL-GRPC (0.0.37): + - BoringSSL-GRPC/Implementation (= 0.0.37) + - BoringSSL-GRPC/Interface (= 0.0.37) + - BoringSSL-GRPC/Implementation (0.0.37): + - BoringSSL-GRPC/Interface (= 0.0.37) + - BoringSSL-GRPC/Interface (0.0.37) + - cloud_firestore (6.1.2): + - Firebase/CoreOnly (~> 12.8.0) + - Firebase/Firestore (~> 12.8.0) + - firebase_core + - FlutterMacOS + - file_saver (0.0.1): + - FlutterMacOS + - Firebase/CoreOnly (12.8.0): + - FirebaseCore (~> 12.8.0) + - Firebase/Firestore (12.8.0): + - Firebase/CoreOnly + - FirebaseFirestore (~> 12.8.0) + - Firebase/RemoteConfig (12.8.0): + - Firebase/CoreOnly + - FirebaseRemoteConfig (~> 12.8.0) + - firebase_analytics (12.1.2): + - firebase_core + - FirebaseAnalytics (= 12.8.0) + - FlutterMacOS + - firebase_core (4.4.0): + - Firebase/CoreOnly (~> 12.8.0) + - FlutterMacOS + - firebase_remote_config (6.1.4): + - Firebase/CoreOnly (~> 12.8.0) + - Firebase/RemoteConfig (~> 12.8.0) + - firebase_core + - FlutterMacOS + - FirebaseABTesting (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseAnalytics (12.8.0): + - FirebaseAnalytics/Default (= 12.8.0) + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - GoogleAppMeasurement/Default (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppCheckInterop (12.8.0) + - FirebaseCore (12.8.0): + - FirebaseCoreInternal (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseCoreInternal (12.8.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseFirestore (12.8.0): + - FirebaseCore (~> 12.8.0) + - FirebaseCoreExtension (~> 12.8.0) + - FirebaseFirestoreInternal (~> 12.8.0) + - FirebaseSharedSwift (~> 12.8.0) + - FirebaseFirestoreInternal (12.8.0): + - abseil/algorithm (~> 1.20240722.0) + - abseil/base (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/memory (~> 1.20240722.0) + - abseil/meta (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/time (~> 1.20240722.0) + - abseil/types (~> 1.20240722.0) + - FirebaseAppCheckInterop (~> 12.8.0) + - FirebaseCore (~> 12.8.0) + - "gRPC-C++ (~> 1.69.0)" + - gRPC-Core (~> 1.69.0) + - leveldb-library (~> 1.22) + - nanopb (~> 3.30910.0) + - FirebaseInstallations (12.8.0): + - FirebaseCore (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (12.8.0): + - FirebaseABTesting (~> 12.8.0) + - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (~> 12.8.0) + - FirebaseRemoteConfigInterop (~> 12.8.0) + - FirebaseSharedSwift (~> 12.8.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.8.0) + - FirebaseSharedSwift (12.8.0) + - flutter_secure_storage_macos (6.1.3): + - FlutterMacOS + - FlutterMacOS (1.0.0) + - GoogleAppMeasurement/Core (12.8.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.8.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.8.0) + - GoogleAppMeasurement/IdentitySupport (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.8.0): + - GoogleAppMeasurement/Core (= 12.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - "gRPC-C++ (1.69.0)": + - "gRPC-C++/Implementation (= 1.69.0)" + - "gRPC-C++/Interface (= 1.69.0)" + - "gRPC-C++/Implementation (1.69.0)": + - abseil/algorithm/container (~> 1.20240722.0) + - abseil/base/base (~> 1.20240722.0) + - abseil/base/config (~> 1.20240722.0) + - abseil/base/core_headers (~> 1.20240722.0) + - abseil/base/log_severity (~> 1.20240722.0) + - abseil/base/no_destructor (~> 1.20240722.0) + - abseil/cleanup/cleanup (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/container/flat_hash_set (~> 1.20240722.0) + - abseil/container/inlined_vector (~> 1.20240722.0) + - abseil/flags/flag (~> 1.20240722.0) + - abseil/flags/marshalling (~> 1.20240722.0) + - abseil/functional/any_invocable (~> 1.20240722.0) + - abseil/functional/bind_front (~> 1.20240722.0) + - abseil/functional/function_ref (~> 1.20240722.0) + - abseil/hash/hash (~> 1.20240722.0) + - abseil/log/absl_check (~> 1.20240722.0) + - abseil/log/absl_log (~> 1.20240722.0) + - abseil/log/check (~> 1.20240722.0) + - abseil/log/globals (~> 1.20240722.0) + - abseil/log/log (~> 1.20240722.0) + - abseil/memory/memory (~> 1.20240722.0) + - abseil/meta/type_traits (~> 1.20240722.0) + - abseil/numeric/bits (~> 1.20240722.0) + - abseil/random/bit_gen_ref (~> 1.20240722.0) + - abseil/random/distributions (~> 1.20240722.0) + - abseil/random/random (~> 1.20240722.0) + - abseil/status/status (~> 1.20240722.0) + - abseil/status/statusor (~> 1.20240722.0) + - abseil/strings/cord (~> 1.20240722.0) + - abseil/strings/str_format (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/synchronization/synchronization (~> 1.20240722.0) + - abseil/time/time (~> 1.20240722.0) + - abseil/types/optional (~> 1.20240722.0) + - abseil/types/span (~> 1.20240722.0) + - abseil/types/variant (~> 1.20240722.0) + - abseil/utility/utility (~> 1.20240722.0) + - "gRPC-C++/Interface (= 1.69.0)" + - "gRPC-C++/Privacy (= 1.69.0)" + - gRPC-Core (= 1.69.0) + - "gRPC-C++/Interface (1.69.0)" + - "gRPC-C++/Privacy (1.69.0)" + - gRPC-Core (1.69.0): + - gRPC-Core/Implementation (= 1.69.0) + - gRPC-Core/Interface (= 1.69.0) + - gRPC-Core/Implementation (1.69.0): + - abseil/algorithm/container (~> 1.20240722.0) + - abseil/base/base (~> 1.20240722.0) + - abseil/base/config (~> 1.20240722.0) + - abseil/base/core_headers (~> 1.20240722.0) + - abseil/base/log_severity (~> 1.20240722.0) + - abseil/base/no_destructor (~> 1.20240722.0) + - abseil/cleanup/cleanup (~> 1.20240722.0) + - abseil/container/flat_hash_map (~> 1.20240722.0) + - abseil/container/flat_hash_set (~> 1.20240722.0) + - abseil/container/inlined_vector (~> 1.20240722.0) + - abseil/flags/flag (~> 1.20240722.0) + - abseil/flags/marshalling (~> 1.20240722.0) + - abseil/functional/any_invocable (~> 1.20240722.0) + - abseil/functional/bind_front (~> 1.20240722.0) + - abseil/functional/function_ref (~> 1.20240722.0) + - abseil/hash/hash (~> 1.20240722.0) + - abseil/log/check (~> 1.20240722.0) + - abseil/log/globals (~> 1.20240722.0) + - abseil/log/log (~> 1.20240722.0) + - abseil/memory/memory (~> 1.20240722.0) + - abseil/meta/type_traits (~> 1.20240722.0) + - abseil/numeric/bits (~> 1.20240722.0) + - abseil/random/bit_gen_ref (~> 1.20240722.0) + - abseil/random/distributions (~> 1.20240722.0) + - abseil/random/random (~> 1.20240722.0) + - abseil/status/status (~> 1.20240722.0) + - abseil/status/statusor (~> 1.20240722.0) + - abseil/strings/cord (~> 1.20240722.0) + - abseil/strings/str_format (~> 1.20240722.0) + - abseil/strings/strings (~> 1.20240722.0) + - abseil/synchronization/synchronization (~> 1.20240722.0) + - abseil/time/time (~> 1.20240722.0) + - abseil/types/optional (~> 1.20240722.0) + - abseil/types/span (~> 1.20240722.0) + - abseil/types/variant (~> 1.20240722.0) + - abseil/utility/utility (~> 1.20240722.0) + - BoringSSL-GRPC (= 0.0.37) + - gRPC-Core/Interface (= 1.69.0) + - gRPC-Core/Privacy (= 1.69.0) + - gRPC-Core/Interface (1.69.0) + - gRPC-Core/Privacy (1.69.0) + - leveldb-library (1.22.6) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - package_info_plus (0.0.1): + - FlutterMacOS + - PromisesObjC (2.4.0) + - share_plus (0.0.1): + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS + - video_player_avfoundation (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - awesome_notifications (from `Flutter/ephemeral/.symlinks/plugins/awesome_notifications/macos`) + - awesome_notifications_core (from `Flutter/ephemeral/.symlinks/plugins/awesome_notifications_core/macos`) + - cloud_firestore (from `Flutter/ephemeral/.symlinks/plugins/cloud_firestore/macos`) + - file_saver (from `Flutter/ephemeral/.symlinks/plugins/file_saver/macos`) + - firebase_analytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos`) + - firebase_core (from `Flutter/ephemeral/.symlinks/plugins/firebase_core/macos`) + - firebase_remote_config (from `Flutter/ephemeral/.symlinks/plugins/firebase_remote_config/macos`) + - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) + - FlutterMacOS (from `Flutter/ephemeral`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + - video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`) + +SPEC REPOS: + trunk: + - abseil + - BoringSSL-GRPC + - Firebase + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseFirestore + - FirebaseFirestoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleAppMeasurement + - GoogleUtilities + - "gRPC-C++" + - gRPC-Core + - leveldb-library + - nanopb + - PromisesObjC + +EXTERNAL SOURCES: + awesome_notifications: + :path: Flutter/ephemeral/.symlinks/plugins/awesome_notifications/macos + awesome_notifications_core: + :path: Flutter/ephemeral/.symlinks/plugins/awesome_notifications_core/macos + cloud_firestore: + :path: Flutter/ephemeral/.symlinks/plugins/cloud_firestore/macos + file_saver: + :path: Flutter/ephemeral/.symlinks/plugins/file_saver/macos + firebase_analytics: + :path: Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos + firebase_core: + :path: Flutter/ephemeral/.symlinks/plugins/firebase_core/macos + firebase_remote_config: + :path: Flutter/ephemeral/.symlinks/plugins/firebase_remote_config/macos + flutter_secure_storage_macos: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos + FlutterMacOS: + :path: Flutter/ephemeral + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + share_plus: + :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + sqflite_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + video_player_avfoundation: + :path: Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin + +SPEC CHECKSUMS: + abseil: a05cc83bf02079535e17169a73c5be5ba47f714b + awesome_notifications: 7818a3dbad4836238a68df439c06981d9f0b276c + awesome_notifications_core: 1c16f7521b1757f6d39121289573aa3801ba0299 + BoringSSL-GRPC: dded2a44897e45f28f08ae87a55ee4bcd19bc508 + cloud_firestore: 71947b640bd24f6f849d9d185e5d0a619fa6b93b + file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f + Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d + firebase_analytics: baaf472ae2221d731cf1ec69b3e360bd1bbf40c5 + firebase_core: b1697fb64ff2b9ca16baaa821205f8b0c058e5d2 + firebase_remote_config: e77e7e12127f6043b14aa2e1949d7af3218c94e0 + FirebaseABTesting: 31266c7845f9adde0f2e8a59267e9c82e4050898 + FirebaseAnalytics: f20bbad8cb7f65d8a5eaefeb424ae8800a31bdfc + FirebaseAppCheckInterop: ba3dc604a89815379e61ec2365101608d365cf7d + FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c + FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2 + FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21 + FirebaseFirestore: 67f23000ca238ccbab79127ed59636a9a2689e74 + FirebaseFirestoreInternal: a0e7382af3d208898dcd1d4d52d8a7870632e881 + FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0 + FirebaseRemoteConfig: e9e3909162a05bc0e796326255fd43250783a2a9 + FirebaseRemoteConfigInterop: 869ddca16614f979e5c931ece11fbb0b8729ed41 + FirebaseSharedSwift: f57ed48f4542b2d7eb4738f4f23ba443f78b3780 + flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54 + FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 + GoogleAppMeasurement: 72c9a682fec6290327ea5e3c4b829b247fcb2c17 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + "gRPC-C++": cc207623316fb041a7a3e774c252cf68a058b9e8 + gRPC-Core: 860978b7db482de8b4f5e10677216309b5ff6330 + leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + package_info_plus: f0052d280d17aa382b932f399edf32507174e870 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 + url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd + video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a + +PODFILE CHECKSUM: 2bbaaa1752f97db94da363e30654aa60e20fb3a0 + +COCOAPODS: 1.16.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 6a27ce1..ab3da6e 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -243,7 +243,6 @@ 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, BE6752570711DC323B9D7F70 /* [CP] Embed Pods Frameworks */, - 1C68EA7950BA34CCD3081D74 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -327,23 +326,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1C68EA7950BA34CCD3081D74 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -578,7 +560,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -606,6 +588,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.5; MARKETING_VERSION = 3.0.0; + PRODUCT_BUNDLE_IDENTIFIER = cl.utem.miutem; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; @@ -666,7 +649,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -716,7 +699,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -744,6 +727,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.5; MARKETING_VERSION = 3.0.0; + PRODUCT_BUNDLE_IDENTIFIER = cl.utem.miutem; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -770,6 +754,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.5; MARKETING_VERSION = 3.0.0; + PRODUCT_BUNDLE_IDENTIFIER = cl.utem.miutem; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements index 8002590..b8cd5c2 100644 --- a/macos/Runner/DebugProfile.entitlements +++ b/macos/Runner/DebugProfile.entitlements @@ -2,17 +2,19 @@ + com.apple.developer.authentication-services.autofill-credential-provider + com.apple.security.app-sandbox com.apple.security.cs.allow-jit - com.apple.security.network.server + com.apple.security.files.downloads.read-write com.apple.security.network.client - - com.apple.security.files.downloads.read-write - - keychain-access-groups - + + com.apple.security.network.server + + keychain-access-groups + diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index 8db76e4..d0df91a 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -2,15 +2,17 @@ + com.apple.developer.authentication-services.autofill-credential-provider + com.apple.security.app-sandbox + com.apple.security.files.downloads.read-write + com.apple.security.network.client com.apple.security.network.server - com.apple.security.files.downloads.read-write - - keychain-access-groups - + keychain-access-groups + diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..aeb17ad --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,1306 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: d93b0378aadce9c1388108067946276582c2ae89426c64c17920c74988508fed + url: "https://pub.dev" + source: hosted + version: "22.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: cd83f7d6bd4e4c0b0b4fef802e8796784032e1cc23d7b0e982cf5d05d9bbe182 + url: "https://pub.dev" + source: hosted + version: "1.3.66" + adaptive_number: + dependency: transitive + description: + name: adaptive_number + sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + adaptive_theme: + dependency: "direct main" + description: + name: adaptive_theme + sha256: "5caccff82e40ef6d3ebb28caaa091ab1865b0e35bd2ab2ddccf49cd336331012" + url: "https://pub.dev" + source: hosted + version: "3.7.2" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "581a0281129283e75d4d67d6ac6e391c0515cdce37eb6eb4bc8a52e65d2b16b6" + url: "https://pub.dev" + source: hosted + version: "1.7.2" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" + url: "https://pub.dev" + source: hosted + version: "2.0.3" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + awesome_notifications: + dependency: "direct main" + description: + name: awesome_notifications + sha256: "0d5fa4457f2ba4e536adc3ef6af709cdcecf4a05a1f3035981e9afa2f899b2a8" + url: "https://pub.dev" + source: hosted + version: "0.10.1" + awesome_notifications_core: + dependency: "direct main" + description: + name: awesome_notifications_core + sha256: f8a227159f70e30d0f4c1d8996cf7e3865fec7c9030df752dfa51d177dc08b38 + url: "https://pub.dev" + source: hosted + version: "0.10.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: ad77deb6e9c143a3f550fbb4c5c1e0c6aadabe24274898d06b9526c61b9cf4fb + url: "https://pub.dev" + source: hosted + version: "1.0.0" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + url: "https://pub.dev" + source: hosted + version: "0.3.5" + clipboard: + dependency: "direct main" + description: + name: clipboard + sha256: "2ec38f0e59878008ceca0ab122e4bfde98847f88ef0f83331362ba4521f565a9" + url: "https://pub.dev" + source: hosted + version: "0.1.3" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "54484b2fc49f41b46f35b60a54b12351181eeaad22c0e3def276a81e17ae7c9b" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: dfaa8b2c0d0a824af289d4159816a5c78417feec264c2194081d645687195158 + url: "https://pub.dev" + source: hosted + version: "7.0.6" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: "35d01f502b3b701d700470d32a8f82704dac8341a66e86c074900cde5bab343d" + url: "https://pub.dev" + source: hosted + version: "5.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + collection: + dependency: "direct main" + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + dart_jsonwebtoken: + dependency: "direct main" + description: + name: dart_jsonwebtoken + sha256: "00a0812d2aeaeb0d30bcbc4dd3cee57971dbc0ab2216adf4f0247f37793f15ef" + url: "https://pub.dev" + source: hosted + version: "2.17.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "7f5b48e6a448c4b46250a6113857a00eaa82821ef5a3d7f42e68eb69d1283fa3" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + dio: + dependency: "direct main" + description: + name: dio + sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" + url: "https://pub.dev" + source: hosted + version: "4.0.6" + dio_http_cache: + dependency: "direct main" + description: + name: dio_http_cache + sha256: ced385a6fcf7f9fd238cc9b866a75583ee309d97bf1ceccaa00bb978b1d00db4 + url: "https://pub.dev" + source: hosted + version: "0.3.0" + dotted_border: + dependency: "direct main" + description: + name: dotted_border + sha256: "108837e11848ca776c53b30bc870086f84b62ed6e01c503ed976e8f8c7df9c04" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + ed25519_edwards: + dependency: transitive + description: + name: ed25519_edwards + sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + expressions: + dependency: transitive + description: + name: expressions + sha256: f3b0e99563a9a1bde1138e728eb722f292cc7d2aec55d28136c49b1a370306c5 + url: "https://pub.dev" + source: hosted + version: "0.2.5+3" + extended_masked_text: + dependency: "direct main" + description: + name: extended_masked_text + sha256: "1599e6c2cea0b24214114c92679cf2c56cd9c8c1cac5dfc65c292bf3373b4b33" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + file_saver: + dependency: "direct main" + description: + name: file_saver + sha256: "8ffd91ae9f543c5ebbfec71a814ee5aa9e21176d31335133308abf63f4c42e8a" + url: "https://pub.dev" + source: hosted + version: "0.2.9" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + sha256: "07e0a82e9b045dbd14522a0b23764e2dbcc269720e785d63c6a021133ebb766a" + url: "https://pub.dev" + source: hosted + version: "12.1.2" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + sha256: "62fd3f27f342c898bd819fb97fa87c0b971e9fbe03357477282c0e14e1a40c3c" + url: "https://pub.dev" + source: hosted + version: "5.0.6" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + sha256: "8fc488bb008439fc3b850cfac892dec1ff4cd438eee44438919a14c5e61b9828" + url: "https://pub.dev" + source: hosted + version: "0.6.1+2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "923085c881663ef685269b013e241b428e1fb03cdd0ebde265d9b40ff18abf80" + url: "https://pub.dev" + source: hosted + version: "4.4.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 + url: "https://pub.dev" + source: hosted + version: "6.0.2" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "83e7356c704131ca4d8d8dd57e360d8acecbca38b1a3705c7ae46cc34c708084" + url: "https://pub.dev" + source: hosted + version: "3.4.0" + firebase_remote_config: + dependency: "direct main" + description: + name: firebase_remote_config + sha256: "6d7be334b726537b3aa3a3ef1db9782951cd93c2b996eebc33f64a9f140e0409" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + firebase_remote_config_platform_interface: + dependency: transitive + description: + name: firebase_remote_config_platform_interface + sha256: f895915923bebb9e8b36a6387fac31a9dd36fbb63fa2ee1ea2cbe309634eecdf + url: "https://pub.dev" + source: hosted + version: "2.0.7" + firebase_remote_config_web: + dependency: transitive + description: + name: firebase_remote_config_web + sha256: a4de6b86e5eb0416a46948dcb1fa9fce6a71d41f80fa107f6e202ae579ec81b2 + url: "https://pub.dev" + source: hosted + version: "1.10.3" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_carousel_widget: + dependency: "direct main" + description: + name: flutter_carousel_widget + sha256: "6473e6df04bfafea70efd58251fe5945d5aa8d19461575c1b9d83643f08e0c77" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b + url: "https://pub.dev" + source: hosted + version: "5.2.1" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + flutter_native_splash: + dependency: "direct main" + description: + name: flutter_native_splash + sha256: "4fb9f4113350d3a80841ce05ebf1976a36de622af7d19aca0ca9a9911c7ff002" + url: "https://pub.dev" + source: hosted + version: "2.4.7" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + url: "https://pub.dev" + source: hosted + version: "9.2.4" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + 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" + get: + dependency: "direct main" + description: + name: get + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" + url: "https://pub.dev" + source: hosted + version: "4.7.3" + 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: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055 + url: "https://pub.dev" + source: hosted + version: "6.3.3" + hooks: + dependency: transitive + description: + name: hooks + sha256: "7a08a0d684cb3b8fb604b78455d5d352f502b68079f7b80b831c62220ab0a4f6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + html: + dependency: "direct main" + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.dev" + source: hosted + version: "0.15.6" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "492bd52f6c4fbb6ee41f781ff27765ce5f627910e1e0cbecfa3d9add5562604c" + url: "https://pub.dev" + source: hosted + version: "4.7.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "0aa7409f6c82acfab96853b8b0c7503de49918cbe705a57cfdeb477756b4521b" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + json_serializable: + dependency: transitive + description: + name: json_serializable + sha256: "86d3edf6914d6562ed4c7d9288239fbf1a9ee3c498ed0089a535c0d3703bb323" + url: "https://pub.dev" + source: hosted + version: "4.1.4" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + logger: + dependency: "direct main" + description: + name: logger + sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 + url: "https://pub.dev" + source: hosted + version: "2.6.2" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + material_symbols_icons: + dependency: "direct main" + description: + name: material_symbols_icons + sha256: c62b15f2b3de98d72cbff0148812f5ef5159f05e61fc9f9a089ec2bb234df082 + url: "https://pub.dev" + source: hosted + version: "4.2906.0" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac" + url: "https://pub.dev" + source: hosted + version: "0.17.4" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" + url: "https://pub.dev" + source: hosted + version: "8.3.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + 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: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e + url: "https://pub.dev" + source: hosted + version: "2.2.22" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + pedantic: + dependency: transitive + description: + name: pedantic + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0e01f805457ef610ccaf8d18067596afc34107a27149778b06b2083edbc140c1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + quiver: + dependency: transitive + description: + name: quiver + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" + screenshot: + dependency: "direct main" + description: + name: screenshot + sha256: "63817697a7835e6ce82add4228e15d233b74d42975c143ad8cfe07009fab866b" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: fce43200aa03ea87b91ce4c3ac79f0cecd52e2a7a56c7a4185023c271fbfa6da + url: "https://pub.dev" + source: hosted + version: "10.1.4" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b + url: "https://pub.dev" + source: hosted + version: "5.0.2" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f + url: "https://pub.dev" + source: hosted + version: "2.4.20" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + skeletonizer: + dependency: "direct main" + description: + name: skeletonizer + sha256: "83157d8e2e41f0252079cfec496281c16e4c63660052dab8d4cd72a206bb7109" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: ffb7124eb6752de71e87a122cc50a8a191044add69fd990d76958bc38ee552fd + url: "https://pub.dev" + source: hosted + version: "1.0.3" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + sqflite: + dependency: "direct main" + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 + url: "https://pub.dev" + source: hosted + version: "2.4.2+2" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.dev" + source: hosted + version: "3.4.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + universal_io: + dependency: transitive + description: + name: universal_io + sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2 + url: "https://pub.dev" + source: hosted + version: "2.3.1" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" + url: "https://pub.dev" + source: hosted + version: "6.3.28" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: b1aca26728b7cc7a3af971bb6f601554a8ae9df2e0a006de8450ba06a17ad36a + url: "https://pub.dev" + source: hosted + version: "6.4.0" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" + source: hosted + version: "2.4.2" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + uuid: + dependency: transitive + description: + name: uuid + sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 + url: "https://pub.dev" + source: hosted + version: "4.5.2" + vector_math: + dependency: "direct main" + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + video_player: + dependency: "direct main" + description: + name: video_player + sha256: "096bc28ce10d131be80dfb00c223024eb0fba301315a406728ab43dd99c45bdf" + url: "https://pub.dev" + source: hosted + version: "2.10.1" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: ee4fd520b0cafa02e4a867a0f882092e727cdaa1a2d24762171e787f8a502b0a + url: "https://pub.dev" + source: hosted + version: "2.9.1" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: "0d753e1d6bcc741a9c182a689434a9f22041f8a2cf5b3bd3b46ae51f057947a3" + url: "https://pub.dev" + source: hosted + version: "2.9.2" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: "57c5d73173f76d801129d0531c2774052c5a7c11ccb962f1830630decd9f24ec" + url: "https://pub.dev" + source: hosted + version: "6.6.0" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + xpath_selector: + dependency: transitive + description: + name: xpath_selector + sha256: "6d8295565a34a6e2821a0721592e584c70421e52a0f54955e0c8e41963db7c90" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + xpath_selector_html_parser: + dependency: "direct main" + description: + name: xpath_selector_html_parser + sha256: ebc562a07832a4062a2bc1c238fd59a81d31d841f15460caeed412ce078af9e0 + url: "https://pub.dev" + source: hosted + version: "3.0.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.10.3 <4.0.0" + flutter: ">=3.38.4" diff --git a/pubspec.yaml b/pubspec.yaml index 4af61e9..305803e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,12 +19,11 @@ dependencies: package_info_plus: ^8.0.2 shared_preferences: ^2.3.2 dart_jsonwebtoken: ^2.14.1 - cloud_firestore: ^5.4.5 google_fonts: ^6.2.1 flutter_native_splash: ^2.4.1 video_player: ^2.9.2 url_launcher: ^6.3.0 - skeletonizer: ^1.4.2 + skeletonizer: ^2.1.0+1 material_symbols_icons: ^4.2785.1 collection: ^1.18.0 extended_masked_text: ^3.0.1 @@ -35,16 +34,17 @@ dependencies: screenshot: ^3.0.0 share_plus: ^10.1.2 # Firebase - firebase_core: ^3.7.0 - firebase_remote_config: ^5.1.4 - firebase_analytics: ^11.3.4 + firebase_core: ^4.3.0 + firebase_remote_config: ^6.1.3 + firebase_analytics: ^12.1.0 + cloud_firestore: ^6.1.1 # Apuntes sqflite: ^2.4.1 flutter_secure_storage: ^9.2.2 path_provider: ^2.1.5 # Awesome-notifications LOCAL awesome_notifications_core: ^0.10.0 - awesome_notifications: ^0.10.0 + awesome_notifications: ^0.10.1 xpath_selector_html_parser: ^3.0.1 html: ^0.15.5 flutter_carousel_widget: ^3.1.0 @@ -63,6 +63,7 @@ dev_dependencies: flutter: uses-material-design: true assets: + - .env - assets/launcher_icons/prod/icon_splash.png - assets/videos/login_bg.mp4 - assets/images/login_bg.png