Skip to content

Conversation

paodb
Copy link
Member

@paodb paodb commented Aug 21, 2025

Those options can help to get more accurate results on trackLocation and goToCurrentLocation features.

Close #151

Summary by CodeRabbit

  • New Features
    • Add configurable geolocation options for current location and live tracking (high accuracy, timeout, maximum age) while preserving existing no-argument behavior.
    • Enforce a single active tracking session with a clear error if one is already running.
  • Tests / Samples
    • Update demo to show how to start tracking with the new options.
  • Chores
    • Update copyright year to 2025.

Those options can help to get more accurate results on trackLocation and goToCurrentLocation features.

Close #151
Copy link

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds a GeolocationOptions model and integrates it into GoogleMap API and frontend so geolocation calls (current location and tracking) can accept enableHighAccuracy, timeout, and maximumAge; updates demo to use the new options.

Changes

Cohort / File(s) Summary
Geolocation options model
src/main/java/.../googlemaps/GeolocationOptions.java
New public class with fields enableHighAccuracy, timeout, maximumAge, Lombok accessors/constructor, and toJson() producing a JsonObject including enableHighAccuracy and maximumAge always and timeout when non-null.
GoogleMap API overloads for geolocation
src/main/java/.../googlemaps/GoogleMap.java
Added goToCurrentLocation(GeolocationOptions) and trackLocation(GeolocationOptions); no-arg variants delegate to the overloads with null; options converted to JSON (or empty object) and passed to client; trackLocation enforces single active session and fires tracking event.
Frontend geolocation options wiring
src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js
Updated get(map, options) and trackLocation(map, options) signatures; forwards options to navigator.geolocation.getCurrentPosition and watchPosition. Copyright year bumped.
Demo updates
src/test/java/.../TrackLocationDemo.java
Demo now constructs GeolocationOptions(true, 5000L, 0L) and calls trackLocation(options) (replaces prior no-arg call).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Enable high accuracy when using location tracking (#151)

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 69e3e4f and 53b4a86.

📒 Files selected for processing (1)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-151

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (1)

659-671: Fix race and false “activated” event; set a pending sentinel and gate event firing.

  • Race: Because trackLocationId is assigned asynchronously in the .then callback, a second call can pass the null check and start another watch. Mark the session as “pending” before calling JS to prevent concurrent starts.
  • False activation: If geolocation is unsupported/denied, JS returns null/undefined. The current code still fires LocationTrackingActivatedEvent. Gate the event on a non-null id.

Apply this focused change:

-  public void trackLocation(GeolocationOptions options) {
-    if (getTrackLocationId() == null) {
-      JsonObject optionsJson = options == null ? Json.createObject() : options.toJson();
-      getElement().executeJs("return geolocation.trackLocation($0, $1)", this, optionsJson)
-          .then(Integer.class, trackLocationId -> {
-            this.trackLocationId = trackLocationId;
-            ComponentUtil.fireEvent(this, new LocationTrackingActivatedEvent(this, false));
-          });
-    } else {
+  public void trackLocation(GeolocationOptions options) {
+    if (getTrackLocationId() == null) {
+      // Mark as pending to avoid concurrent starts before the async callback runs.
+      this.trackLocationId = -1;
+      JsonObject optionsJson = options == null ? Json.createObject() : options.toJson();
+      getElement().executeJs("return geolocation.trackLocation($0, $1)", this, optionsJson)
+          .then(Integer.class, trackLocationId -> {
+            if (trackLocationId != null) {
+              this.trackLocationId = trackLocationId;
+              ComponentUtil.fireEvent(this, new LocationTrackingActivatedEvent(this, false));
+            } else {
+              // Reset on failure/unavailable geolocation (JS returned null/undefined).
+              this.trackLocationId = null;
+            }
+          });
+    } else {
       throw new IllegalStateException(
           "A tracking location session is already active. Please stop the current session before starting a new one.");
     }
   }

Additionally, align stopTrackLocation to ignore the pending sentinel (place this outside the selected range):

// In stopTrackLocation():
if (trackLocationId != null && trackLocationId >= 0) {
  getElement().executeJs("geolocation.clearTracking($0)", trackLocationId);
}
trackLocationId = null;
🧹 Nitpick comments (5)
src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js (2)

22-34: Forwarding options to getCurrentPosition is correct; add a small defensive guard and (optionally) propagate error details.

  • Guard against non-object values to avoid passing unexpected types; the browser treats undefined or {} the same for defaults.
  • Optional: capture the PositionError object and forward its code/message server-side in a future API to aid diagnostics.

Apply this focused change to coerce options locally:

-  get: function(map, options) {
+  get: function(map, options) {
+    const opts = options && typeof options === 'object' ? options : undefined;
     // if browser supports geolocation, return current location
     if (navigator.geolocation) {
-      navigator.geolocation.getCurrentPosition(
+      navigator.geolocation.getCurrentPosition(
         position => {
           map.$server.handleGeolocation(position.coords.latitude, position.coords.longitude);
         }, 
-        () => {
+        /* Consider: error => { this._handleGeolocationError(true, map); } */
+        () => {
           this._handleGeolocationError(true, map);
-        },
-        options
+        },
+        opts
       );

41-53: Returning watch id is correct; initialize explicitly and coerce options.

  • When geolocation is unavailable, the function currently returns undefined; returning null is clearer and avoids ambiguity downstream.
  • Same options guard as above keeps behavior robust.
-  trackLocation: function(map, options) {
-    let trackLocationId;
+  trackLocation: function(map, options) {
+    let trackLocationId = null;
+    const opts = options && typeof options === 'object' ? options : undefined;
     if (navigator.geolocation) {
-      trackLocationId = navigator.geolocation.watchPosition(
+      trackLocationId = navigator.geolocation.watchPosition(
         position => {
           map.$server.handleGeolocation(position.coords.latitude, position.coords.longitude);
         }, 
-        () => {
+        /* Consider: error => { this._handleGeolocationError(true, map); } */
+        () => {
           this._handleGeolocationError(true, map);
-        },
-        options
+        },
+        opts
       );
     } else { // browser doesn't support geolocation
       this._handleGeolocationError(false, map);
     }
     return trackLocationId;
   },
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java (1)

63-75: Validate non-negative numeric options before serializing.
Timeout and maximumAge must not be negative per the Web Geolocation spec. Add a quick guard to prevent sending invalid options to the client.

Minimal tweak within this method:

   public JsonObject toJson() {
+    validate();
     JsonObject json = Json.createObject();
     if (enableHighAccuracy != null) {
       json.put("enableHighAccuracy", enableHighAccuracy);
     }
     if (timeout != null) {
       json.put("timeout", timeout);
     }
     if (maximumAge != null) {
       json.put("maximumAge", maximumAge);
     }
     return json;
   }

And add this helper (outside the selected range):

private void validate() {
  if (timeout != null && timeout < 0) {
    throw new IllegalArgumentException("timeout must be >= 0");
  }
  if (maximumAge != null && maximumAge < 0) {
    throw new IllegalArgumentException("maximumAge must be >= 0");
  }
}
src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java (1)

52-52: Handle failed activation in the UI (optional).
If geolocation is denied/unsupported, the current code enables the Stop button on click but never re-disables it. You already show a Notification on error; also toggle buttons for a smoother UX.

Patch the existing error listener to reset buttons:

-    gmaps.addGeolocationErrorEventListener(e -> Notification.show(e.isBrowserHasGeolocationSupport()
-        ? "The geolocation service failed on retrieving your location."
-        : "Your browser doesn't support geolocation."));
+    gmaps.addGeolocationErrorEventListener(e -> {
+      Notification.show(e.isBrowserHasGeolocationSupport()
+          ? "The geolocation service failed on retrieving your location."
+          : "Your browser doesn't support geolocation.");
+      // Reset buttons on failure
+      startLocationTrackingButton.setEnabled(true);
+      stopLocationTrackingButton.setEnabled(false);
+    });
src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (1)

549-560: Optional: pass “undefined” instead of empty object to JS when no options.
This preserves pure browser defaults and avoids sending an empty object over the wire. Vaadin doesn’t support “omit arg” easily, so this is non-trivial and fine to skip. Mentioned for completeness.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f3d895e and 69e3e4f.

📒 Files selected for processing (4)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (4 hunks)
  • src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js (4 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java (2 hunks)
🔇 Additional comments (6)
src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js (1)

5-5: LGTM: license header year updated.
No issues.

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java (1)

35-38: ✔ Lombok is already configured in the build

The pom.xml declares Lombok as a provided-scope dependency:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <scope>provided</scope>
  <version>1.18.34</version>
</dependency>

Multiple classes (e.g. GeolocationOptions.java) rely on Lombok annotations, and the build includes the necessary dependency. No further action is needed.

src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java (1)

45-47: Good: demo shows the intended high-accuracy options.
Constructing GeolocationOptions(true, 5000L, 0L) matches the linked issue’s recommendation and clearly documents intent.

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java (3)

539-548: Delegation reads well.
goToCurrentLocation() delegating to the options overload keeps API backward compatible and reduces duplication.


549-560: Options serialization and client call look correct.
Building an empty JsonObject when options is null is fine; the browser will use defaults.


627-643: Delegation for trackLocation() is fine.
Keeps old API while enabling the new options-aware variant.

* If true and if the device is able to provide a more accurate position, it will do so. This may
* result in slower response times or increased power consumption.
*/
private Boolean enableHighAccuracy;
Copy link
Member

Choose a reason for hiding this comment

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

In Geolocation API enableHighAccuracy defaults to false, so we can avoid the wrapper and use primitive instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

* A positive long value representing the maximum age (in milliseconds) of a possible cached
* position that is acceptable to return.
*/
private Long maximumAge;
Copy link
Member

Choose a reason for hiding this comment

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

In Geolocation API maximumAge to 0, so we can avoid the wrapper and use primitive instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done


/**
* A positive long value representing the maximum length of time (in milliseconds) the device is
* allowed to take in order to return a position.
Copy link
Member

Choose a reason for hiding this comment

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

Document that the default value (null) means that the device won't timeout until the position is available

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@github-project-automation github-project-automation bot moved this from To Do to In Progress in Flowing Code Addons Aug 21, 2025
@paodb paodb requested a review from javier-godoy August 21, 2025 20:47
Copy link

@javier-godoy javier-godoy merged commit 9ab7000 into master Aug 22, 2025
5 of 6 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Pending release in Flowing Code Addons Aug 22, 2025
@javier-godoy javier-godoy deleted the issue-151 branch August 22, 2025 12:23
@paodb paodb moved this from Pending release to Done in Flowing Code Addons Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

Enable high accuracy

2 participants