Add Ctrl+F search to projects page - #1541
Conversation
Greptile SummaryAdds a shared project filter with a Ctrl/Cmd+F overlay, match navigation, active-card styling, and highlighted project-name matches.
Confidence Score: 4/5The stale active-match index should be fixed before merging because interval changes can leave the search overlay and project selection inconsistent. Preserved-state interval navigation can replace the matching project set without constraining the retained match index; Unicode highlighting and effect-driven reset logic also warrant non-blocking corrections. Files Needing Attention: app/javascript/pages/Projects/Index.svelte; app/javascript/pages/Projects/components/ProjectCard.svelte Important Files Changed
Prompt To Fix All With AI### Issue 1
app/javascript/pages/Projects/Index.svelte:184-187
**Match index becomes stale**
When a user selects a later match and changes to an interval with fewer matching projects, the preserved `currentMatchIndex` remains outside the updated result set, causing an impossible count such as 4/2 and leaving no project selected.
### Issue 2
app/javascript/pages/Projects/components/ProjectCard.svelte:62-76
**Lowercasing invalidates highlight offsets**
If a project name contains a character whose locale-lowercased representation has a different UTF-16 length, match offsets calculated from `normalizedName` no longer align with `project.name`, producing incorrectly highlighted or omitted text.
### Issue 3
app/javascript/pages/Projects/Index.svelte:184-187
**Effect derives navigation state**
This effect reads `searchQuery` solely to reset `currentMatchIndex`, splitting query-update behavior between implicit reactive execution and explicit handlers. Reset the index at the query update boundary instead so the navigation state remains explicit and maintainable.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "Add Ctrl+F search to projects page" | Re-trigger Greptile |
| $effect(() => { | ||
| searchQuery; | ||
| currentMatchIndex = 0; | ||
| }); |
There was a problem hiding this comment.
When a user selects a later match and changes to an interval with fewer matching projects, the preserved currentMatchIndex remains outside the updated result set, causing an impossible count such as 4/2 and leaving no project selected.
Knowledge Base Used: Frontend App (Inertia.js + Svelte)
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/javascript/pages/Projects/Index.svelte
Line: 184-187
Comment:
**Match index becomes stale**
When a user selects a later match and changes to an interval with fewer matching projects, the preserved `currentMatchIndex` remains outside the updated result set, causing an impossible count such as 4/2 and leaving no project selected.
**Knowledge Base Used:** [Frontend App (Inertia.js + Svelte)](https://app.greptile.com/mahadk/-/custom-context/knowledge-base/hackclub/hackatime/-/docs/frontend-app.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| const normalizedName = project.name.toLocaleLowerCase(); | ||
| const normalizedQuery = query.toLocaleLowerCase(); | ||
| let cursor = 0; | ||
| let matchStart = normalizedName.indexOf(normalizedQuery); | ||
|
|
||
| while (matchStart >= 0) { | ||
| if (matchStart > cursor) { | ||
| parts.push({ | ||
| text: project.name.slice(cursor, matchStart), | ||
| highlighted: false, | ||
| }); | ||
| } | ||
| const matchEnd = matchStart + query.length; | ||
| parts.push({ | ||
| text: project.name.slice(matchStart, matchEnd), |
There was a problem hiding this comment.
Lowercasing invalidates highlight offsets
If a project name contains a character whose locale-lowercased representation has a different UTF-16 length, match offsets calculated from normalizedName no longer align with project.name, producing incorrectly highlighted or omitted text.
Knowledge Base Used: Frontend App (Inertia.js + Svelte)
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/javascript/pages/Projects/components/ProjectCard.svelte
Line: 62-76
Comment:
**Lowercasing invalidates highlight offsets**
If a project name contains a character whose locale-lowercased representation has a different UTF-16 length, match offsets calculated from `normalizedName` no longer align with `project.name`, producing incorrectly highlighted or omitted text.
**Knowledge Base Used:** [Frontend App (Inertia.js + Svelte)](https://app.greptile.com/mahadk/-/custom-context/knowledge-base/hackclub/hackatime/-/docs/frontend-app.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| $effect(() => { | ||
| searchQuery; | ||
| currentMatchIndex = 0; | ||
| }); |
There was a problem hiding this comment.
Effect derives navigation state
This effect reads searchQuery solely to reset currentMatchIndex, splitting query-update behavior between implicit reactive execution and explicit handlers. Reset the index at the query update boundary instead so the navigation state remains explicit and maintainable.
Rule Used: What: Don't use effects to derive state that can b... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/javascript/pages/Projects/Index.svelte
Line: 184-187
Comment:
**Effect derives navigation state**
This effect reads `searchQuery` solely to reset `currentMatchIndex`, splitting query-update behavior between implicit reactive execution and explicit handlers. Reset the index at the query update boundary instead so the navigation state remains explicit and maintainable.
**Rule Used:** What: Don't use effects to derive state that can b... ([source](https://app.greptile.com/mahadk/-/custom-context?memory=8569b05b-35ae-4e04-9b00-50fe1f992c68))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary of the problem
The projects page has an inline filter but does not support the familiar browser find workflow for quickly navigating project matches.
Describe your changes
Adds a compact Chrome-style Ctrl+F and Cmd+F overlay while preserving the existing search bar. Both controls share the same query, show match counts, support previous and next navigation and highlight matching project name text in yellow.
Screenshots / Media
https://ampcode.com/user-content/artifacts/db724bd693d7b8ea9ca6da2e8f715b691cd0723a31fcdb14c7cb399276102116-file.webm