Skip to content

fix: stabilize discover/likes races and improve location UX - #30

Merged
saksham1991999 merged 6 commits into
mainfrom
fix/discover-likes-and-location-ux
Jul 16, 2026
Merged

fix: stabilize discover/likes races and improve location UX#30
saksham1991999 merged 6 commits into
mainfrom
fix/discover-likes-and-location-ux

Conversation

@RaviSahu1520

@RaviSahu1520 RaviSahu1520 commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Discover deck: session-swiped property filter + no HTTP cache so cards do not reappear after tab switches/refresh races; concurrent loads re-read state and de-dupe
  • Likes tab: optimistic liked/passed segment caches + server merge so just-swiped properties do not flash-disappear before history API catches up
  • Location UX: popular NCR cities (Gurgaon/Noida/Delhi) always available offline, merged ahead of Places results; softer location bias (no strictbounds radius trap); resolve popular place ids without network
  • Discover UI: remove floating Like/Pass/Details action bar (gesture-only deck)
  • Android: NDK/Gradle/Kotlin bumps and conservative JVM heap for low-RAM builds
  • Housekeeping: clear pre-existing analyzer warnings that blocked pre-commit; keep dev_env.g.dart empty (no secrets)

Review fixes applied before PR

  • Did not commit local secrets that were in dev_env.g.dart
  • Tightened PopularCity.mergeWithRemote to exact mainText de-dupe only (avoids dropping Greater Noida / similar areas)
  • Generalized machine-specific Gradle comments

Test plan

  • flutter test for popular_city, page_state_service, page_data_loader, location_search_view, property_swipe_stack, discover_view (133 passed)
  • flutter analyze clean (pre-commit)
  • Manual: swipe like/pass on Discover, open Likes (liked + passed segments) — cards appear without disappearing
  • Manual: switch tabs / pull refresh on Discover — swiped cards stay gone
  • Manual: open location picker with empty query — popular cities visible; pick Gurgaon without network lag
  • Manual: Discover swipe gestures still work without action buttons

Summary by cubic

Stabilizes Discover/Likes so swiped cards don’t reappear and just‑liked items don’t flash. Improves location search with offline NCR cities and a softer Places bias; the deck is gesture‑only with accessible swipe actions, and page loads now drop stale responses via generation guards.

  • Bug Fixes

    • Data loading: per‑page generation counters invalidate stale first‑page/load‑more completions and error paths (no stray isLoadingMore after a superseding refresh); queued force‑reloads when superseded; dispose‑safe microtask skips.
    • Discover: disabled HTTP cache, filtered session‑swiped IDs, de‑duped concurrent loads; preserved only undo‑reinserted cards via a mutation epoch; added a11y swipe actions that animate from the drag threshold.
    • Likes: merged optimistic liked/passed caches with server while ignoring stale opposite rows; passed PropertyModel to recordSwipe; queued a reload when segments switch mid‑flight using the current segment; aligned load‑more with optimistic state.
    • Android builds: aligned AGP 8.11.1 + Kotlin 2.2.20, Gradle 8.14, NDK 28.2; set conservative Gradle/Kotlin daemon memory; removed explicit Impeller meta.
  • New Features

    • Location: always show popular NCR cities (Gurgaon/Noida/Delhi) offline at the top; resolved popular: IDs locally; preferred non‑empty Google results with OSM fallback; restored a softer bias (no strict bounds, capped radius); stopped remote self‑de‑dupe in popular merge to avoid dropping similar areas.
    • Discover UI: removed the floating Like/Pass/Info bar; deck is gesture‑only with semantic actions for like/pass/details.

Written for commit 6b99446. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added “popular cities” quick-pick suggestions (Gurgaon/Noida/Delhi with aliases) to location search and location picker results, merged with remote suggestions.
  • Bug Fixes
    • Improved Discover swipe filtering to prevent session-swiped cards from reappearing and hardened refresh/undo behavior.
    • Strengthened Likes optimistic updates, pagination merging, and concurrent likes refresh handling across segments.
  • UI Updates
    • Removed the pinned like/pass/details button row; like/pass now works via gestures and accessibility actions.
    • Updated popular suggestion tile styling and header behavior.
  • Build & Maintenance
    • Updated Android Gradle/NDK settings and tuning, Gradle wrapper, and Impeller manifest configuration guidance.

Keep swiped cards out of Discover (session filter + no HTTP cache), merge
optimistic likes/passes so the Likes tab does not flash-remove just-swiped
items, and surface popular NCR cities offline while Places is loading.
Also drop the floating like/pass action bar (gesture-only deck), tune
Android Gradle memory for low-RAM builds, and clear pre-existing analyzer
warnings that blocked pre-commit.
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates Android tooling, adds curated popular-city location suggestions, improves swipe and likes state synchronization, replaces discover action buttons with gestures and semantic actions, and adjusts related tests, translations, and generated configuration.

Changes

Android and tooling configuration

Layer / File(s) Summary
Android toolchain and build settings
android/app/build.gradle.kts, android/app/src/main/AndroidManifest.xml, android/gradle.properties, android/gradle/wrapper/gradle-wrapper.properties, android/settings.gradle.kts
Android NDK, Gradle, Kotlin, Impeller metadata, and build resource settings are updated.
Generated development environment map
lib/core/config/dev_env.g.dart
Adds an empty generated kDevEnv map with local tooling markers.

Popular city location search

Layer / File(s) Summary
Popular city model and provider resolution
lib/core/data/models/popular_city.dart, lib/core/services/google_places_service.dart
Adds curated NCR cities, local suggestion merging, popular place-ID parsing, bounded Google autocomplete parameters, and OSM fallback behavior.
Location suggestion presentation
lib/core/widgets/common/location_selector.dart, lib/features/location_search/presentation/views/location_search_view.dart
Merges local and remote suggestions, adds popular-city headers and styling, and updates loading and error states.
Location behavior tests
test/core/data/models/popular_city_test.dart, test/features/location_search/presentation/views/location_search_view_test.dart
Tests city matching, merging, loading, popular results, and query-dependent errors.

Swipe and likes state consistency

Layer / File(s) Summary
Session swipe and likes segment state
lib/core/controllers/page_state_service.dart
Adds session swipe filtering, segment-aware optimistic caches, undo handling, and server-result merging.
Latest-state-aware loading and controller integration
lib/core/controllers/page_data_loader.dart, lib/features/likes/presentation/controllers/likes_controller.dart
Queues overlapping likes refreshes, rereads current state after awaits, filters discover results, deduplicates pages, and routes likes transitions through recordSwipe.
Gesture-only swipe deck
lib/features/discover/presentation/widgets/*
Removes pinned action buttons and supports horizontal swipe plus accessibility semantic actions.
Swipe and loader tests
test/core/controllers/page_data_loader_test.dart, test/core/controllers/page_state_service_test.dart, test/features/likes/presentation/controllers/likes_controller_test.dart, test/features/discover/presentation/views/discover_view_test.dart, test/features/discover/presentation/widgets/property_swipe_stack_test.dart
Verifies segment visibility, session exclusion, optimistic merges, concurrent refreshes, controller calls, and removed action controls.

Maintenance

Layer / File(s) Summary
Translation and test maintenance
lib/core/translations/app_translations.dart, test/core/controllers/page_filter_manager_test.dart, test/core/firebase/*, test/core/utils/error_handler_test.dart, test/features/assistant/*, test/features/auth/*, test/features/explore/*, test/features/property_details/*, test/helpers/*
Removes duplicate translations and updates obsolete test fixtures, assertions, and compatibility annotations.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • 360ghar/360-ghar-app#15: Earlier page and location infrastructure is extended by the popular-city search and updated state flows.
  • 360ghar/360-ghar-app#23: Both changes modify PageStateService around likes segment caching and swipe/undo consistency.
  • 360ghar/360-ghar-app#29: Both changes modify location-search debounce, suggestion rendering, and query-dependent error handling.

Suggested reviewers: saksham1991999

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific, concise, and accurately summarizes the main changes around Discover/Likes race fixes and location UX improvements.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/discover-likes-and-location-ux

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
lib/core/controllers/page_state_service.dart (2)

581-588: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Rollback the optimistic transaction when the swipe write fails.

All local caches and Discover state are mutated before _swipesPort.recordSwipe(). Several supplied callers only log the exception, leaving a failed swipe hidden from Discover and preserved in Likes for the session. Capture a rollback closure/snapshot, restore it in catch, then rethrow the mapped error.

As per coding guidelines, “Wrap async calls in try/catch blocks and map errors via error_mapper.dart and handle with error_handler.dart.”

🤖 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 `@lib/core/controllers/page_state_service.dart` around lines 581 - 588, Update
the swipe flow containing _sessionSwipedPropertyIds, removePropertyFromDiscover,
and _swipesPort.recordSwipe to capture the affected local state and wrap the
network call in try/catch. On failure, restore Discover and cache/session state
from the captured snapshot, map the exception through error_mapper.dart, handle
it with error_handler.dart, and rethrow the mapped error so callers receive the
failure.

Source: Coding guidelines


125-136: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Invalidate in-flight loads when clearing the user session.

clearSessionData() resets state, but an earlier PageDataLoader request can still complete and write the previous user’s properties back into these observables. Add a session/request generation token, invalidate it here, and discard responses from older generations.

🤖 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 `@lib/core/controllers/page_state_service.dart` around lines 125 - 136, Update
PageStateService’s clearSessionData and PageDataLoader response handling to use
a session/request generation token: increment the token when clearing session
data, capture the current generation when starting each load, and ignore
responses whose generation is no longer current before writing to observables.
Preserve the existing state reset and cache-clearing behavior.
lib/core/controllers/page_data_loader.dart (1)

295-316: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep the requested Likes segment attached to its asynchronous response.

The loader captures one segment before awaiting, while both response application and cache synchronization use mutable current state afterward.

  • lib/core/controllers/page_data_loader.dart#L295-L316: verify the requested segment/revision is still active before updating visible state.
  • lib/core/controllers/page_state_service.dart#L751-L760: accept the requested segment explicitly rather than reading currentLikesSegment.
🤖 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 `@lib/core/controllers/page_data_loader.dart` around lines 295 - 316, Keep the
captured Likes segment and request revision tied to the asynchronous response:
in lib/core/controllers/page_data_loader.dart:295-316, verify they are still
active before applying visible state or synchronizing the cache, and pass the
captured segment to the cache-sync call. In
lib/core/controllers/page_state_service.dart:751-760, update
syncLikesSegmentCacheFromVisible to accept the requested segment explicitly and
use it instead of reading mutable currentLikesSegment.
🧹 Nitpick comments (2)
android/gradle/wrapper/gradle-wrapper.properties (1)

5-5: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin the Gradle distribution checksum.

The wrapper now downloads gradle-8.14-all.zip without distributionSha256Sum. Gradle recommends checksum verification; add the official checksum efe9a3d147d948d7528a9887fa35abcf24ca1a43ad06439996490f77569b02d1. (docs.gradle.org)

Proposed fix
 distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
+distributionSha256Sum=efe9a3d147d948d7528a9887fa35abcf24ca1a43ad06439996490f77569b02d1
🤖 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 `@android/gradle/wrapper/gradle-wrapper.properties` at line 5, Add the official
Gradle 8.14 distribution checksum as the distributionSha256Sum property
alongside distributionUrl in the Gradle wrapper configuration, using the
provided SHA-256 value.

Source: MCP tools

lib/core/controllers/page_state_service.dart (1)

544-544: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the changed public mutation APIs and their cache side effects.

Add API documentation for recordSwipe, isSessionSwiped, removePropertyFromLikes, addPropertyToLikes, and addPropertyToPassed.

As per coding guidelines, “Annotate public APIs and exports.”

Also applies to: 629-629, 672-702

🤖 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 `@lib/core/controllers/page_state_service.dart` at line 544, Document the
public mutation and query APIs recordSwipe, isSessionSwiped,
removePropertyFromLikes, addPropertyToLikes, and addPropertyToPassed with Dart
API comments, describing their behavior and relevant cache side effects. Keep
the implementation unchanged and ensure each public method is annotated
consistently with the project’s documentation guidelines.

Source: Coding guidelines

🤖 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 `@android/settings.gradle.kts`:
- Line 22: Align the Kotlin Android plugin declaration in settings.gradle.kts
with a supported Android Gradle Plugin version: either downgrade AGP to 8.11.1
for Kotlin 2.2.20 or update Kotlin to a version officially supporting AGP
8.12.1. Keep the selected Kotlin and AGP versions as a compatible pair across
the Android build configuration.

In `@lib/core/controllers/page_data_loader.dart`:
- Around line 329-348: Update the refresh flow around _pageState.getStateForPage
and reinsertPropertyToDiscover so Discover responses cannot overwrite properties
restored locally while the request is pending. Track the post-request-start
local mutation/revision and merge or reject the stale response, preserving
reinserted cards while still applying valid backend results and session-swiped
filtering.

In `@lib/core/controllers/page_state_service.dart`:
- Around line 545-579: Update recordSwipe and its callers, including
LikesController.removeFromLikes() and moveToLikes(), to preserve and pass the
affected PropertyModel before removing it from the visible segment. Use that
model for optimistic destination-cache insertion and visible-list updates when
_findPropertyInAnyList() returns null, while retaining the existing
source-removal behavior.
- Around line 725-748: Update mergeLikesServerResults so each server item is
skipped when its ID exists in the selected segment’s opposite optimistic map,
preventing a stale result from reintroducing an opposite swipe. Only remove the
ID from optimistic when the server item belongs to the requested segment; do not
clear opposite or add skipped items to merged, while preserving pending
optimistic items and existing merge ordering.

In `@lib/core/services/google_places_service.dart`:
- Around line 218-228: Update the location-bias logic in the currentPosition
query-parameter block to apply location and capped radius whenever
currentPosition is available, removing the placesStrictBounds exclusion so
strict mode does not lose all bias. Preserve the existing radius parsing and
25–200 km clamping behavior.

In `@lib/features/discover/presentation/widgets/property_swipe_stack.dart`:
- Around line 41-46: Preserve an accessible non-drag path for Like and Pass in
the swipe stack described by the widget documentation. Add semantic custom
actions or equivalent accessible controls for both actions without restoring the
removed floating action bar, and connect them to the existing Like/Pass handling
used by the swipe gestures.

---

Outside diff comments:
In `@lib/core/controllers/page_data_loader.dart`:
- Around line 295-316: Keep the captured Likes segment and request revision tied
to the asynchronous response: in
lib/core/controllers/page_data_loader.dart:295-316, verify they are still active
before applying visible state or synchronizing the cache, and pass the captured
segment to the cache-sync call. In
lib/core/controllers/page_state_service.dart:751-760, update
syncLikesSegmentCacheFromVisible to accept the requested segment explicitly and
use it instead of reading mutable currentLikesSegment.

In `@lib/core/controllers/page_state_service.dart`:
- Around line 581-588: Update the swipe flow containing
_sessionSwipedPropertyIds, removePropertyFromDiscover, and
_swipesPort.recordSwipe to capture the affected local state and wrap the network
call in try/catch. On failure, restore Discover and cache/session state from the
captured snapshot, map the exception through error_mapper.dart, handle it with
error_handler.dart, and rethrow the mapped error so callers receive the failure.
- Around line 125-136: Update PageStateService’s clearSessionData and
PageDataLoader response handling to use a session/request generation token:
increment the token when clearing session data, capture the current generation
when starting each load, and ignore responses whose generation is no longer
current before writing to observables. Preserve the existing state reset and
cache-clearing behavior.

---

Nitpick comments:
In `@android/gradle/wrapper/gradle-wrapper.properties`:
- Line 5: Add the official Gradle 8.14 distribution checksum as the
distributionSha256Sum property alongside distributionUrl in the Gradle wrapper
configuration, using the provided SHA-256 value.

In `@lib/core/controllers/page_state_service.dart`:
- Line 544: Document the public mutation and query APIs recordSwipe,
isSessionSwiped, removePropertyFromLikes, addPropertyToLikes, and
addPropertyToPassed with Dart API comments, describing their behavior and
relevant cache side effects. Keep the implementation unchanged and ensure each
public method is annotated consistently with the project’s documentation
guidelines.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0602ecdc-48ba-4cc9-98a5-26725b9f43df

📥 Commits

Reviewing files that changed from the base of the PR and between 8d0e66d and e78bda6.

📒 Files selected for processing (31)
  • android/app/build.gradle.kts
  • android/app/src/main/AndroidManifest.xml
  • android/gradle.properties
  • android/gradle/wrapper/gradle-wrapper.properties
  • android/settings.gradle.kts
  • lib/core/config/dev_env.g.dart
  • lib/core/controllers/page_data_loader.dart
  • lib/core/controllers/page_state_service.dart
  • lib/core/data/models/popular_city.dart
  • lib/core/services/google_places_service.dart
  • lib/core/translations/app_translations.dart
  • lib/core/widgets/common/location_selector.dart
  • lib/features/discover/presentation/widgets/property_swipe_card.dart
  • lib/features/discover/presentation/widgets/property_swipe_stack.dart
  • lib/features/discover/presentation/widgets/swipe_card_action_buttons.dart
  • lib/features/likes/presentation/controllers/likes_controller.dart
  • lib/features/location_search/presentation/views/location_search_view.dart
  • test/core/controllers/page_data_loader_test.dart
  • test/core/controllers/page_filter_manager_test.dart
  • test/core/controllers/page_state_service_test.dart
  • test/core/data/models/popular_city_test.dart
  • test/core/firebase/firebase_initializer_enabled_test.dart
  • test/core/utils/error_handler_test.dart
  • test/features/assistant/presentation/widgets/chat_message_bubble_test.dart
  • test/features/auth/data/auth_repository_test.dart
  • test/features/discover/presentation/views/discover_view_test.dart
  • test/features/discover/presentation/widgets/property_swipe_stack_test.dart
  • test/features/explore/presentation/views/explore_view_test.dart
  • test/features/location_search/presentation/views/location_search_view_test.dart
  • test/features/property_details/presentation/views/property_details_view_test.dart
  • test/helpers/fake_webview_platform.dart
💤 Files with no reviewable changes (6)
  • lib/features/discover/presentation/widgets/swipe_card_action_buttons.dart
  • test/features/explore/presentation/views/explore_view_test.dart
  • test/helpers/fake_webview_platform.dart
  • lib/core/config/dev_env.g.dart
  • test/core/firebase/firebase_initializer_enabled_test.dart
  • lib/core/translations/app_translations.dart

Comment thread android/settings.gradle.kts
Comment thread lib/core/controllers/page_data_loader.dart
Comment thread lib/core/controllers/page_state_service.dart
Comment thread lib/core/controllers/page_state_service.dart
Comment thread lib/core/services/google_places_service.dart Outdated
Comment thread lib/features/discover/presentation/widgets/property_swipe_stack.dart Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 31 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread lib/features/location_search/presentation/views/location_search_view.dart Outdated
Comment thread lib/core/services/google_places_service.dart Outdated
Comment thread lib/core/services/google_places_service.dart Outdated
Comment thread lib/features/discover/presentation/widgets/property_swipe_stack.dart Outdated
Comment thread lib/core/widgets/common/location_selector.dart Outdated
Comment thread lib/core/controllers/page_state_service.dart Outdated
Comment thread lib/core/controllers/page_data_loader.dart
Comment thread lib/core/widgets/common/location_selector.dart Outdated
Comment thread lib/core/controllers/page_state_service.dart
Resolve CodeRabbit and Cubic findings: pass PropertyModel into recordSwipe,
preserve undo reinserts via discover mutation epoch, skip opposite optimistic
likes on server merge, guard likes segment mid-flight switches, restore
Places location bias semantics, extract popular suggestions helper, and add
swipe-stack semantic actions for a11y. Align AGP to 8.11.1 with Kotlin 2.2.20.
@RaviSahu1520

Copy link
Copy Markdown
Collaborator Author

Addressed review comments (f4eeab8)

Fixed CodeRabbit + Cubic findings:

Area Change
recordSwipe property Optional \property\ arg so Likes remove/move still optimistically update segment caches after the card leaves the visible list
Discover undo race Mutation epoch + \mergeDiscoverRefreshResults\ preserves undo-reinserted cards during in-flight refresh
Opposite optimistic wipe Server merge skips rows still in the opposite optimistic map
Likes segment mid-flight \�pplyLikesSegmentFetchResult\ only updates the visible list when the segment still matches; otherwise cache-only
Places bias Always soft-bias with location+radius; \strictbounds\ only when config is true; removed (regions)\ type restriction
Popular cities DRY Shared \PopularCity.buildSuggestionsList\ / \PopularSuggestionsList\
Location error UI Defensive empty-suggestions check (remote + popular)
A11y Semantic custom actions for Like / Pass / View details on swipe stack
AGP/Kotlin AGP \8.11.1\ with Kotlin \2.2.20\

Tests: page_state_service, page_data_loader, popular_city, likes_controller, location_search_view, property_swipe_stack — all passed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/core/controllers/page_data_loader.dart (1)

209-223: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject responses when the request criteria changed in flight.

Both paths apply results fetched with the old location, filters, search query, or cursor to the latest state. A concurrent filter/location change can therefore mix unrelated properties and replace the new cursor with an obsolete one. Capture a request generation/signature and discard the response unless it still matches the latest state.

Also applies to: 331-373

🤖 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 `@lib/core/controllers/page_data_loader.dart` around lines 209 - 223, Update
the pagination response handling around _pageState.getStateForPage and the
corresponding path near the second apply-results block to capture the request’s
location, filters, search query, cursor, or generation before awaiting. After
the response returns, compare that signature with the latest page state and
discard the response when criteria changed; only merge properties and update
nextCursor, hasMore, and isLoadingMore when it still matches.
test/features/likes/presentation/controllers/likes_controller_test.dart (1)

45-51: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Stub the no-property recordSwipe call too. addToFavourites and removeFromFavourites still call recordSwipe with only propertyId and isLiked, so this stub may miss those invocations. Add a second when for the 2-arg shape.

🤖 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 `@test/features/likes/presentation/controllers/likes_controller_test.dart`
around lines 45 - 51, Add a second stub alongside the existing
mockPageStateService.recordSwipe setup for calls from addToFavourites and
removeFromFavourites that provide only propertyId and isLiked, leaving the
current three-argument stub unchanged.

Source: Coding guidelines

🤖 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 `@lib/core/data/models/popular_city.dart`:
- Line 109: Update mergeWithRemote to stop adding remote suggestion keys to the
seen set, so distinct remote places sharing the same mainText are preserved.
Keep deduplication against the appropriate existing suggestions, and leave the
call site assigning mergeWithRemote(query, remote) unchanged.

---

Outside diff comments:
In `@lib/core/controllers/page_data_loader.dart`:
- Around line 209-223: Update the pagination response handling around
_pageState.getStateForPage and the corresponding path near the second
apply-results block to capture the request’s location, filters, search query,
cursor, or generation before awaiting. After the response returns, compare that
signature with the latest page state and discard the response when criteria
changed; only merge properties and update nextCursor, hasMore, and isLoadingMore
when it still matches.

In `@test/features/likes/presentation/controllers/likes_controller_test.dart`:
- Around line 45-51: Add a second stub alongside the existing
mockPageStateService.recordSwipe setup for calls from addToFavourites and
removeFromFavourites that provide only propertyId and isLiked, leaving the
current three-argument stub unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 332e2f0b-776e-45d9-8f21-861046fbec2b

📥 Commits

Reviewing files that changed from the base of the PR and between e78bda6 and f4eeab8.

📒 Files selected for processing (13)
  • android/settings.gradle.kts
  • lib/core/controllers/page_data_loader.dart
  • lib/core/controllers/page_state_service.dart
  • lib/core/data/models/popular_city.dart
  • lib/core/services/google_places_service.dart
  • lib/core/widgets/common/location_selector.dart
  • lib/features/discover/presentation/widgets/property_swipe_stack.dart
  • lib/features/likes/presentation/controllers/likes_controller.dart
  • lib/features/location_search/presentation/views/location_search_view.dart
  • test/core/controllers/page_data_loader_test.dart
  • test/core/controllers/page_state_service_test.dart
  • test/core/data/models/popular_city_test.dart
  • test/features/likes/presentation/controllers/likes_controller_test.dart
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/core/data/models/popular_city_test.dart
  • lib/features/discover/presentation/widgets/property_swipe_stack.dart
  • lib/core/controllers/page_state_service.dart

Comment thread lib/core/data/models/popular_city.dart

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 13 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/core/controllers/page_state_service.dart">

<violation number="1" location="lib/core/controllers/page_state_service.dart:801">
P3: This update leaves the older likes cache sync helper unused and duplicates the fetch/cache responsibility in a second method. Keeping one likes-fetch merge path would make it easier to maintain and reduce the risk of the two helpers drifting apart.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread lib/features/discover/presentation/widgets/property_swipe_stack.dart Outdated
Comment thread lib/core/data/models/popular_city.dart
Comment thread lib/core/controllers/page_data_loader.dart Outdated
Comment thread lib/core/data/models/popular_city.dart Outdated
Comment thread lib/core/controllers/page_state_service.dart
Preserve only undo-reinserted Discover cards across fetches, queue likes
reloads when segment switches mid-flight, and align likes load-more with
optimistic merge. Soften Places radius clamp and document Gradle heap
overrides; add regression tests.
Stop remote self-dedupe in popular city merge, animate a11y swipes from
the drag threshold via a shared exit helper, use currentLikesSegment in
the data loader, and drop the unused popularOnly list field.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@lib/core/controllers/page_data_loader.dart`:
- Around line 146-150: Update the page data loader’s disposal and queued-reload
flow to track disposed state, clear _pendingLikesReload during dispose(), and
prevent _finishActiveLoad from scheduling a reload after disposal. Also guard
the scheduled microtask before calling loadPageData so no repository request
starts once the loader is disposed.
- Around line 68-78: Introduce a per-page/query request generation in the page
data loading flow, incrementing it whenever filters, search, location, or cursor
change or a forced reload supersedes an active request. Capture the generation
when each request starts and validate it before any asynchronous completion
updates results, loading flags, error state, or appends load-more data; stale
completions must be discarded without mutating current state. Update the
active-load guard around _activeLoads and _pendingLikesReload so the newest
forced Explore/Discover/Likes reload is queued instead of dropped, including
while a Likes load-more request is active.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 71d927ce-2082-46a9-b81a-c896ad5e680d

📥 Commits

Reviewing files that changed from the base of the PR and between f4eeab8 and 71ba692.

📒 Files selected for processing (7)
  • android/gradle.properties
  • lib/core/controllers/page_data_loader.dart
  • lib/core/controllers/page_state_service.dart
  • lib/core/services/google_places_service.dart
  • test/core/controllers/page_data_loader_test.dart
  • test/core/controllers/page_state_service_test.dart
  • test/core/data/models/popular_city_test.dart
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/core/data/models/popular_city_test.dart
  • android/gradle.properties
  • lib/core/services/google_places_service.dart
  • lib/core/controllers/page_state_service.dart

Comment thread lib/core/controllers/page_data_loader.dart
Comment thread lib/core/controllers/page_data_loader.dart Outdated
Invalidate in-flight first-page and load-more completions with a per-page
generation counter, queue force reloads for all tabs when superseded, and
skip queued microtasks after dispose.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 9 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread lib/core/controllers/page_data_loader.dart
A failed load-more must not clear isLoadingMore after a force-refresh
has superseded it; match the success-path generation check in catch.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Requires human review: Adjusts Android build operational parameters (JVM heap, workers, AGP/Kotlin versions) which requires operational context; UI change to gesture-only deck may need product sign-off.

Re-trigger cubic

@saksham1991999
saksham1991999 merged commit 2ca2b99 into main Jul 16, 2026
2 of 4 checks passed
@saksham1991999
saksham1991999 deleted the fix/discover-likes-and-location-ux branch July 16, 2026 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants