Fix/learn guest mode ux and dashboard stability#3720
Conversation
… shimmer - Remove pilot demo seed from production builds; add one-time migration to clear previously seeded fake progress for all users - Stop auto-showing completion sheet when reopening an already-complete lesson; completed lessons now replay from step 0 - Guard getSurveyResponses API sync behind auth check to avoid noisy auth errors and wasted requests for guest users - Reduce country detection location timeout from 10s to 5s - Downgrade nearby-view early-return log from warning to info - Show shimmer placeholders in the country tab row while dashboard data is loading instead of rendering an empty row
Replaces GET /api/v2/devices/kya/lessons with GET /api/v2/devices/learn/catalog. Adds LearnV2CatalogResponse model, LearnRepositoryImpl, and LearnSyncService for guest session management and offline progress buffering. Real lesson activities from the v2 API are now used in the experience widget when available, falling back to the demo script for any lessons without v2 content. Guest progress is reported fire-and- forget and buffered locally when offline for sync on reconnect.
- LSP/DIP: Add getCachedCatalog() to LearnRepository interface so KyaBloc no longer needs a downcast to LearnRepositoryImpl to access it. - DRP: Consolidate LearnQuizFormat <-> API string mapping onto the enum itself (apiKey getter + fromApiKey factory). Removes duplicate switch statements from LearnLessonExperienceService and LearnLessonExperience. - SRP: Extract _ProgressBuffer from LearnSyncService to separate offline buffering from session management and progress reporting.
|
Warning Review limit reached
Next review available in: 57 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (17)
📝 WalkthroughWalkthroughThis PR migrates the Learn (formerly KYA) feature from a legacy lesson-response model to a new "Learn V2" catalog data model, adding ChangesLearn V2 catalog migration
Unrelated dashboard and survey tweaks
Estimated code review effort: 4 (Complex) | ~60 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (5)
src/mobile/lib/src/app/learn/models/learn_v2_catalog.dart (1)
9-173: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winConsider value equality on catalog models.
None of
LearnV2CatalogResponse/LearnV2Course/LearnV2Unit/LearnV2Lesson/LearnV2Activityoverride==/hashCode. These are embedded inKyaStatesubclasses'props(seekya_state.dart), which Equatable-based Bloc states use both for its ownemitdedup and forBlocBuilderrebuild comparisons. Two structurally-identical catalogs from separate JSON decodes will never be==, so every refresh — even a no-op one returning the same data — is treated as a distinct state, causing extra rebuilds/emits.♻️ Add Equatable to reduce redundant rebuilds
+import 'package:equatable/equatable.dart'; + -class LearnV2CatalogResponse { +class LearnV2CatalogResponse extends Equatable { final bool success; final String catalogVersion; final List<LearnV2Course> courses; const LearnV2CatalogResponse({ required this.success, required this.catalogVersion, required this.courses, }); + + `@override` + List<Object?> get props => [success, catalogVersion, courses];(repeat similarly for the nested model classes)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/learn/models/learn_v2_catalog.dart` around lines 9 - 173, The catalog model classes currently rely on reference equality, so identical JSON-decoded data is treated as different by Equatable-based states. Update LearnV2CatalogResponse, LearnV2Course, LearnV2Unit, LearnV2Lesson, and LearnV2Activity to support value equality by extending Equatable or otherwise overriding == and hashCode, and include all of their fields in equality/props. Keep the existing fromJson/toJson behavior unchanged, and ensure nested collections like courses, units, lessons, activities, and payload are part of the equality comparison so KyaState props can dedupe no-op updates correctly.src/mobile/lib/src/app/learn/pages/kya_page.dart (1)
166-168: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueSilent stale-data fallback on error.
When
LessonsLoadingErrorcarries acachedModel, the error UI is skipped entirely and courses render from the stale cache with no indication to the user that the latest refresh failed. Worth a lightweight "showing cached content" affordance, though not blocking.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/learn/pages/kya_page.dart` around lines 166 - 168, The current LessonsLoadingError handling in kya_page.dart silently falls back to cached content whenever cachedModel is present, so users never see that the refresh failed. Update the error-path logic around the LessonsLoadingError check in the KyaPage build flow to keep rendering the cached courses but also surface a lightweight non-blocking affordance/message that fresh loading failed and cached content is being shown. Use the existing _buildErrorState and cachedModel-related state handling in KyaPage to place this notice without replacing the cached UI.src/mobile/lib/src/app/learn/repository/learn_repository.dart (1)
20-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLearn catalog cache reuses the
locationHive box.
_catalogCacheKeyis stored underCacheBoxName.location, which conceptually belongs to geolocation data. This mirrors an existing convention inkya_repository.dart, but a new file is a good opportunity to introduce a dedicatedCacheBoxName(e.g.learn) instead of perpetuating the conflation — reduces risk of confusion if location-specific cache maintenance (eviction, migrations, "clear on logout", etc.) is ever added and inadvertently wipes/affects unrelated Learn catalog data.Also applies to: 28-52, 104-117, 144-151
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/learn/repository/learn_repository.dart` around lines 20 - 21, The Learn catalog cache is being stored in the shared location Hive box, which mixes unrelated concerns and can cause future maintenance to affect Learn data. Update LearnRepository to use a dedicated CacheBoxName for Learn (instead of CacheBoxName.location) and wire _catalogCacheKey through that new box in the cache read/write paths, following the existing CacheManager usage in learn_repository.dart and the related methods that touch the catalog cache. Also align any associated initialization or invalidation logic so Learn catalog data is isolated from geolocation cache handling.src/mobile/lib/src/app/learn/bloc/kya_bloc.dart (1)
32-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnreachable
catchblock around_getCachedCatalog().
_getCachedCatalog()already swallows all errors internally and always returns a value (ornull) — it never throws. Thetry { ... _getCachedCatalog() ... } catch (cacheError)wrapper at lines 32-47 is therefore dead code that can never execute its catch branch.♻️ Simplification
- try { - final LearnV2CatalogResponse? cachedModel = - await _getCachedCatalog(); - - emit(LessonsLoadingError( - message: e.toString(), - cachedModel: cachedModel, - isOffline: !_cacheManager.isConnected, - )); - } catch (cacheError) { - loggy.error('Error fetching cached catalog: $cacheError'); - emit(LessonsLoadingError( - message: e.toString(), - isOffline: !_cacheManager.isConnected, - )); - } + final LearnV2CatalogResponse? cachedModel = await _getCachedCatalog(); + emit(LessonsLoadingError( + message: e.toString(), + cachedModel: cachedModel, + isOffline: !_cacheManager.isConnected, + ));Also applies to: 78-85
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/learn/bloc/kya_bloc.dart` around lines 32 - 47, The try/catch around _getCachedCatalog() in kya_bloc.dart is dead code because _getCachedCatalog() already handles its own failures and only returns a model or null. Remove the unreachable catch branch and keep the error handling in the surrounding bloc flow, using the cachedModel result from _getCachedCatalog() directly when emitting LessonsLoadingError. Apply the same cleanup to the duplicate pattern in the other referenced block so the code paths match and no unreachable cache-error logging remains.src/mobile/lib/src/app/learn/repository/kya_repository.dart (1)
22-23: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the retired KYA repository path
KyaRepository/KyaImplhas no live callers anymore, so keeping the hardcoded/api/v2/devices/kya/lessonshere just leaves dead code and a misleading fallback behind. Remove this file and the retired endpoint constant instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/learn/repository/kya_repository.dart` around lines 22 - 23, The retired KYA repository fallback is dead code and should be removed. Delete the hardcoded _fetchLessonsPath constant from KyaRepository and remove the obsolete kya_repository.dart implementation (including KyaImpl) so there is no lingering /api/v2/devices/kya/lessons endpoint reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/mobile/lib/main.dart`:
- Around line 256-259: The guest Learn sync flow currently only creates the
guest session and syncs pending progress in _initLearnGuestSession, but it never
transfers that progress after sign-in. Update the AuthLoaded handling in the
auth-success path to call LearnSyncService.instance.linkProgressToAccount(...)
so any guest progress is attached to the signed-in account, and keep the
existing guest-session initialization logic separate from the account-linking
step.
In `@src/mobile/lib/src/app/learn/models/learn_course_structure.dart`:
- Around line 22-28: The activityCount getter in learn_course_structure.dart is
falling back to the demo constant for every non-v2 lesson, even when apiLesson
has real tasks. Update activityCount to mirror hasContent’s branching in
LearnCourseStructure: when v2Lesson is null, return apiLesson!.tasks.length if
apiLesson exists, and only use LearnLessonExperienceService.demoActivityCount as
the final fallback when no legacy lesson data is available.
In `@src/mobile/lib/src/app/learn/pages/kya_page.dart`:
- Around line 160-172: The course catalog selection in kya_page.dart does not
preserve data during background refresh, so LessonsRefreshing falls through the
switch and clears the grid. Update the catalog resolution logic in the body that
computes catalog/courses to also map LessonsRefreshing to its currentModel (and
keep the existing LessonsLoaded and LessonsLoadingError handling). Use the
LessonsRefreshing symbol from kya_state.dart and ensure the fallback only
returns null when no cached/current model exists, so the course grid stays
populated while refresh is in progress.
In `@src/mobile/lib/src/app/learn/repository/learn_repository.dart`:
- Around line 59-65: The Learn catalog flow is still calling
ApiUtils.learnCatalog when AIRQO_API_TOKEN is absent, which should be handled as
a configuration problem instead of a generic request failure. Update
LearnRepository.fetchCatalog and the background refresh path in
_refreshInBackground to use the same fail-fast token check pattern as
KyaImpl.fetchLessons, and bail out early with the existing configuration error
when dotenv.env['AIRQO_API_TOKEN'] is missing. Keep the request-building logic
in createGetRequest unchanged for the valid-token path.
In `@src/mobile/lib/src/app/learn/services/learn_lesson_experience_service.dart`:
- Around line 209-213: The quiz payload parsing in
learn_lesson_experience_service is too strict when reading correct_index,
correct_indices, and correct_order from the dynamic map. Update the parsing
logic around the correctIndex/correctIndices/correctOrder extraction to validate
each element type and use int.tryParse for string values instead of direct
casts, so mixed or string-based API values don’t throw during lesson experience
parsing. Keep the fix localized to the quiz parsing branch and preserve the
existing data shape handling.
In `@src/mobile/lib/src/app/learn/services/learn_sync_service.dart`:
- Around line 128-149: In linkProgressToAccount in LearnSyncService, pending
guest progress may still exist when _guestIdKey is removed after a successful
link. Update the flow so buffered local completions are flushed via
syncPendingProgress() before clearing the guest ID, or otherwise keep the guest
identifier until the pending queue is empty. Use the existing _guestIdKey,
syncPendingProgress(), and linkProgressToAccount() flow to place the fix at the
account-link success path.
- Line 120: Keep the success log in LearnSyncService but stop interpolating the
persistent guest/session identifier; update the loggy.info call in the guest
session creation flow to emit a generic success message without guestId. Locate
the logging statement in the method that creates the guest Learn session and
remove the identifier value while preserving the event context.
- Line 178: The LearnSyncService request URL is interpolating lessonId directly
into the path, which can break routing when the ID contains reserved characters.
Update the URL निर्माण in the sync/completion request to encode lessonId before
concatenation, using the existing Uri.parse call in LearnSyncService so the path
remains valid for dynamic catalog IDs.
In
`@src/mobile/lib/src/app/learn/widgets/experience/learn_lesson_experience.dart`:
- Around line 64-84: Guard the empty-script case in LearnLessonExperienceState
before _current is accessed: buildFromV2Lesson in LearnLessonExperienceService
can return an empty list, so in the initialization path that sets _script and
_activityIndex, ensure empty _script is handled by short-circuiting or rendering
a fallback before build() indexes into it. Use the LearnLessonExperienceState
initializer and the _current accessor/build path to locate the fix, and make
sure _activityIndex is never used when _script.isEmpty.
---
Nitpick comments:
In `@src/mobile/lib/src/app/learn/bloc/kya_bloc.dart`:
- Around line 32-47: The try/catch around _getCachedCatalog() in kya_bloc.dart
is dead code because _getCachedCatalog() already handles its own failures and
only returns a model or null. Remove the unreachable catch branch and keep the
error handling in the surrounding bloc flow, using the cachedModel result from
_getCachedCatalog() directly when emitting LessonsLoadingError. Apply the same
cleanup to the duplicate pattern in the other referenced block so the code paths
match and no unreachable cache-error logging remains.
In `@src/mobile/lib/src/app/learn/models/learn_v2_catalog.dart`:
- Around line 9-173: The catalog model classes currently rely on reference
equality, so identical JSON-decoded data is treated as different by
Equatable-based states. Update LearnV2CatalogResponse, LearnV2Course,
LearnV2Unit, LearnV2Lesson, and LearnV2Activity to support value equality by
extending Equatable or otherwise overriding == and hashCode, and include all of
their fields in equality/props. Keep the existing fromJson/toJson behavior
unchanged, and ensure nested collections like courses, units, lessons,
activities, and payload are part of the equality comparison so KyaState props
can dedupe no-op updates correctly.
In `@src/mobile/lib/src/app/learn/pages/kya_page.dart`:
- Around line 166-168: The current LessonsLoadingError handling in kya_page.dart
silently falls back to cached content whenever cachedModel is present, so users
never see that the refresh failed. Update the error-path logic around the
LessonsLoadingError check in the KyaPage build flow to keep rendering the cached
courses but also surface a lightweight non-blocking affordance/message that
fresh loading failed and cached content is being shown. Use the existing
_buildErrorState and cachedModel-related state handling in KyaPage to place this
notice without replacing the cached UI.
In `@src/mobile/lib/src/app/learn/repository/kya_repository.dart`:
- Around line 22-23: The retired KYA repository fallback is dead code and should
be removed. Delete the hardcoded _fetchLessonsPath constant from KyaRepository
and remove the obsolete kya_repository.dart implementation (including KyaImpl)
so there is no lingering /api/v2/devices/kya/lessons endpoint reference.
In `@src/mobile/lib/src/app/learn/repository/learn_repository.dart`:
- Around line 20-21: The Learn catalog cache is being stored in the shared
location Hive box, which mixes unrelated concerns and can cause future
maintenance to affect Learn data. Update LearnRepository to use a dedicated
CacheBoxName for Learn (instead of CacheBoxName.location) and wire
_catalogCacheKey through that new box in the cache read/write paths, following
the existing CacheManager usage in learn_repository.dart and the related methods
that touch the catalog cache. Also align any associated initialization or
invalidation logic so Learn catalog data is isolated from geolocation cache
handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 44023e46-dd68-46d4-90fe-6846ea79ea69
📒 Files selected for processing (20)
src/mobile/lib/main.dartsrc/mobile/lib/src/app/dashboard/services/location_service_mananger.dartsrc/mobile/lib/src/app/dashboard/widgets/nearby_view.dartsrc/mobile/lib/src/app/dashboard/widgets/view_selector.dartsrc/mobile/lib/src/app/learn/bloc/kya_bloc.dartsrc/mobile/lib/src/app/learn/bloc/kya_event.dartsrc/mobile/lib/src/app/learn/bloc/kya_state.dartsrc/mobile/lib/src/app/learn/models/learn_course_structure.dartsrc/mobile/lib/src/app/learn/models/learn_lesson_activity.dartsrc/mobile/lib/src/app/learn/models/learn_lesson_continuation.dartsrc/mobile/lib/src/app/learn/models/learn_v2_catalog.dartsrc/mobile/lib/src/app/learn/pages/kya_page.dartsrc/mobile/lib/src/app/learn/repository/kya_repository.dartsrc/mobile/lib/src/app/learn/repository/learn_repository.dartsrc/mobile/lib/src/app/learn/services/learn_lesson_experience_service.dartsrc/mobile/lib/src/app/learn/services/learn_progress_service.dartsrc/mobile/lib/src/app/learn/services/learn_sync_service.dartsrc/mobile/lib/src/app/learn/widgets/experience/learn_lesson_experience.dartsrc/mobile/lib/src/app/surveys/repository/survey_repository.dartsrc/mobile/lib/src/meta/utils/api_utils.dart
💤 Files with no reviewable changes (1)
- src/mobile/lib/src/app/learn/models/learn_lesson_continuation.dart
- Sign-in: call LearnSyncService.linkProgressToAccount on AuthLoaded so guest progress transfers to the signed-in account. - kya_page: map LessonsRefreshing to its currentModel in catalog switch so the course grid stays populated during background refresh. - LearnRepository: fail-fast when AIRQO_API_TOKEN is absent in both fetchCatalog and _refreshInBackground instead of sending an empty token. - Quiz parsing: use _toInt() helper with int.tryParse fallback for correct_index/correct_indices/correct_order to tolerate string-typed values. - LearnSyncService: redact guest session ID from success log. - LearnSyncService: flush pending buffer before clearing guestId in linkProgressToAccount so offline completions are not orphaned. - LearnSyncService: URI-encode lessonId in the progress PUT path. - LearnLessonExperience: guard empty _script in build() to prevent RangeError when a v2 lesson has no activities.
Delete kya_repository.dart, kya_lesson_container.dart, lesson_response_model.dart. Strip buildFromLessons, buildDemoScript, courseCoverImage, syncLegacyApiProgress, ensurePilotLearnDemosV3, showLesson (legacy), and all apiLesson references. Update bloc tests to use LearnRepository / LearnV2CatalogResponse.
Remove const from non-const ColorFilter.mode in analytics_specifics.dart. Drop redundant null-coalesce on non-nullable return in feature_flag_service.dart.
DIP: add isOffline to LearnRepository interface so KyaBloc no longer instantiates CacheManager directly. DRP: extract _fetchAndCache/_getToken helpers in LearnRepositoryImpl to eliminate duplicated token+request logic between fetchCatalog and _refreshInBackground. DIP: introduce abstract LearnSyncService interface; rename impl to _LearnSyncServiceImpl so callers depend on the abstraction.
There was a problem hiding this comment.
Pull request overview
This PR migrates the mobile “Learn / KYA” experience from the legacy flat lessons API to a v2 catalog structure, adds guest-mode progress syncing/linking, and includes a few dashboard stability/UX improvements (loading placeholders, faster location lookup, and safer survey syncing for guests).
Changes:
- Replace legacy KYA lessons API/repo/models with a Learn v2 catalog model + repository and update bloc/tests accordingly.
- Add Learn guest session + offline progress buffering/syncing, and link guest progress to an authenticated account after login.
- Improve dashboard UX/stability (country shimmer placeholders, faster geolocation timeLimit, less noisy nearby-position logging) and prevent guest survey sync calls.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mobile/test/widget_test.dart | Updates test wiring/types to use LearnRepository instead of legacy KyaRepository. |
| src/mobile/test/app/learn/bloc/kya_bloc_test.dart | Updates bloc tests to mock LearnRepository and v2 catalog responses. |
| src/mobile/lib/src/meta/utils/api_utils.dart | Replaces legacy lessons endpoint with new Learn v2 catalog/sessions/progress endpoints. |
| src/mobile/lib/src/app/surveys/repository/survey_repository.dart | Skips server sync for guests when fetching survey responses. |
| src/mobile/lib/src/app/shared/services/feature_flag_service.dart | Adjusts PostHog flag fetch assignment logic (but currently introduces a null-safety issue). |
| src/mobile/lib/src/app/learn/widgets/learn_bottom_sheets.dart | Removes legacy lesson entry path and legacy API lesson wiring. |
| src/mobile/lib/src/app/learn/widgets/kya_lesson_container.dart | Deletes legacy flat KYA lesson card widget. |
| src/mobile/lib/src/app/learn/widgets/experience/learn_lesson_experience.dart | Builds lesson script from v2 lesson activities and reports completion via sync service. |
| src/mobile/lib/src/app/learn/services/learn_sync_service.dart | Adds guest session creation, offline progress buffer, sync, and account-linking flow. |
| src/mobile/lib/src/app/learn/services/learn_progress_service.dart | Adds one-time cleanup migration for pilot-seeded progress; removes pilot seeding logic. |
| src/mobile/lib/src/app/learn/services/learn_lesson_experience_service.dart | Replaces demo-script generation with v2 activity parsing (article/video/image/quiz). |
| src/mobile/lib/src/app/learn/repository/learn_repository.dart | New repository for fetching/caching v2 catalog and exposing offline status. |
| src/mobile/lib/src/app/learn/repository/kya_repository.dart | Removes legacy KYA repository implementation. |
| src/mobile/lib/src/app/learn/pages/lesson_page.dart | Removes legacy apiLesson plumb-through to lesson experience. |
| src/mobile/lib/src/app/learn/pages/kya_page.dart | Switches KYA page to v2 catalog-driven courses + cover image usage. |
| src/mobile/lib/src/app/learn/models/lesson_response_model.dart | Removes legacy lessons response model. |
| src/mobile/lib/src/app/learn/models/learn_v2_catalog.dart | Adds v2 catalog model (courses/units/lessons/activities). |
| src/mobile/lib/src/app/learn/models/learn_lesson_continuation.dart | Removes legacy nextLesson accessor that depended on old API lesson. |
| src/mobile/lib/src/app/learn/models/learn_lesson_activity.dart | Adds API-key mapping for quiz formats. |
| src/mobile/lib/src/app/learn/models/learn_course_structure.dart | Updates slot/course models for v2 lesson data + cover image URL; builds catalog from v2 courses. |
| src/mobile/lib/src/app/learn/bloc/kya_state.dart | Updates states to hold LearnV2CatalogResponse instead of legacy lessons model. |
| src/mobile/lib/src/app/learn/bloc/kya_event.dart | Updates refresh event to carry LearnV2CatalogResponse. |
| src/mobile/lib/src/app/learn/bloc/kya_bloc.dart | Switches bloc to LearnRepository, uses cached catalog + repository offline flag. |
| src/mobile/lib/src/app/dashboard/widgets/view_selector.dart | Adds shimmer placeholders when active countries haven’t loaded. |
| src/mobile/lib/src/app/dashboard/widgets/nearby_view.dart | Downgrades missing-position log message and clarifies behavior. |
| src/mobile/lib/src/app/dashboard/widgets/analytics_specifics.dart | Minor const removal on ColorFilter.mode. |
| src/mobile/lib/src/app/dashboard/services/location_service_mananger.dart | Reduces geolocation time limit from 10s to 5s. |
| src/mobile/lib/main.dart | Wires LearnRepositoryImpl, initializes Learn guest session/sync at startup, and links progress after login token refresh. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary by CodeRabbit
New Features
Bug Fixes