Skip to content

fix(web): detect SPA navigation while find-in-page is active - #398

Merged
trvny merged 3 commits into
mainfrom
fix/web-find-spa-navigation
Oct 17, 2026
Merged

trvny merged 3 commits into
mainfrom
fix/web-find-spa-navigation

Conversation

@trvny

@trvny trvny commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Fix

  • While Find is open, check the active WebView URL / location.href at a bounded 300 ms interval.
  • Close Find if an SPA calls history.pushState or replaceState without triggering WebViewClient navigation callbacks.
  • Stop polling immediately when Find closes. Do not retain, export or log URLs or page text.

Why

The unchanged Android instrumentation test WebChatFindTest.sameDocumentConversationNavigationClosesFind timed out in both Aistee Claude PRs #396 and #397 (71/72 passing). The existing onUrlChanged callback does not reliably fire for same-document navigation on Android 16 WebView.

CI including Android smoke is the validation gate. Profile regeneration unverified; this affects the Find overlay only, not benchmarked startup/provider-switch journeys.

@kanarek-companion

kanarek-companion Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

🐤 Kanarek · 🟣 merged

main ✅

It landed in main. Kanarek closes the notebook.

App · 1 files

@sourcery-ai

sourcery-ai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The Find overlay now detects SPA pushState/replaceState navigation by polling the active WebView URL and location.href every 300 ms only during the active Find session, closing promptly on URL changes while preventing stale callbacks and data retention.

Sequence diagram for Find overlay SPA navigation detection

sequenceDiagram
    participant User
    participant FindOverlay
    participant WebChatScreen
    participant WebView

    User->>FindOverlay: Open Find
    FindOverlay->>WebChatScreen: Start LaunchedEffect(findSession)
    loop Every 300 ms while Find is active
        WebChatScreen->>WebView: Read webView.url
        alt URL differs from activeSearch.pageUrl
            WebChatScreen->>FindOverlay: closeFindInPage()
        else URL unchanged
            WebChatScreen->>WebView: evaluateJavascript(window.location.href)
            WebView-->>WebChatScreen: location.href
            alt href differs from activeSearch.pageUrl
                WebChatScreen->>FindOverlay: closeFindInPage()
            end
        end
    end
    User->>FindOverlay: Close Find
    FindOverlay-->>WebChatScreen: Clear findSession
    WebChatScreen-->>WebChatScreen: Stop polling
Loading

File-Level Changes

Change Details Files
Add bounded URL polling while the Find overlay is active to detect same-document SPA navigation that bypasses WebView callbacks.
  • Launch a 300 ms polling effect scoped to the current Find session.
  • Compare both WebView URL and JavaScript location.href with the URL captured when Find opened.
  • Close Find when either source reports a changed URL.
  • Stop polling and ignore stale JavaScript callbacks when the Find session closes or changes.
  • Avoid retaining or logging URLs and page content.
app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T19:48:16.476111Z ef69716 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@mergify

mergify Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@sourcery-ai sourcery-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.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt" line_range="188-189" />
<code_context>
+        while (findSession === activeSearch) {
+            delay(300L)
+            val webView = activeSearch.webView
+            if (webView.url?.let { it != activeSearch.pageUrl } == true) {
+                closeFindInPage()
+                break
+            }
</code_context>
<issue_to_address>
**Find closes before navigation**

When find opens before `webView.url` is assigned, `activeSearch.pageUrl` is null, so the `webView.url` check treats the first assigned URL as navigation, and the `evaluateJavascript` callback compares against `""`; either path calls `closeFindInPage()` and dismisses Find before the user can search the loaded page.

Only treat a URL as changed when `activeSearch.pageUrl` is non-null, in both checks.

Also at `app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt:194-195`.
</issue_to_address>

### Comment 2
<location path="app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt" line_range="183-185" />
<code_context>
     }
+    // pushState/replaceState in a SPA do not consistently trigger WebViewClient callbacks.
+    // Watch only while Find is visible; never retain or log the provider URL.
+    LaunchedEffect(findSession) {
+        val activeSearch = findSession ?: return@LaunchedEffect
+        while (findSession === activeSearch) {
+            delay(300L)
+            val webView = activeSearch.webView
</code_context>
<issue_to_address>
**Hidden tab keeps polling**

When the user switches tabs while Find is open, `LaunchedEffect(findSession)` does not check `isActive`, so the loop keeps polling the hidden WebView every 300 ms; a URL change also calls `closeFindInPage()` and loses the retained Find session when the user returns.

Gate the polling effect on `isActive` so it stops while the tab is inactive.
</issue_to_address>

Sourcery assessment

Approval pending. 2 findings to address first.

Blocking findings: app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt:189, app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt:185


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt Outdated
Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt Outdated
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: QUIET
  • Plan: Advanced
  • Run ID: 584b1a0e-97e7-4704-84a9-b5ea6fb84081
📝 Walkthrough

新增监测。Find 会话活动时,代码每 300 毫秒检查 WebView URL 和页面 URL。URL 不同时,代码关闭 Find。会话变化时,监测停止。简单明白。

Priority: ⬇️ Low

Merge Risk: 🟠 High · up to ef697

The new check that closes Find after in-page navigation misreads the current page address. On ordinary web pages, Find can close by itself about 300 ms after opening, even though the page has not changed. Find-in-page becomes effectively unusable. Parse the returned value into a plain string before comparing it with the page URL, and fix this before merging.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed 标题清楚说明修复目标:在 Find 激活时检测 SPA 导航。标题与主要改动一致。通过。
Description check Passed 描述说明轮询 WebView URL、关闭 Find 的条件、停止轮询时机和验证背景。内容与改动相关。通过。
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.
✨ Finishing Touches: 💡 1
✨ Simplify code
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

页面悄悄换了址
监测每三百毫秒看一眼
JavaScript 也报个信
地址不同,Find 就关
会话结束,轮询停
小小守望,不留 URL

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: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: QUIET
  • Plan: Advanced
  • Run ID: 9bf3be4f-d5d4-4cf5-a9ac-66bd38516aac
📥 Commits

Reviewing files that changed from the base of the PR and between 39630af and ef69716.

📒 Files selected for processing: 1
  • app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt Outdated
Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt Fixed

@sourcery-ai sourcery-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.

Sourcery assessment

Approved.

Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt Fixed
Comment thread app/src/main/java/ais/tee/ui/screens/WebChatScreen.kt
@trvny
trvny merged commit 9732eea into main Oct 17, 2026
6 checks passed
@trvny
trvny deleted the fix/web-find-spa-navigation branch October 17, 2026 20:45
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