Skip to content

feat: search in favourites + starred (#562)#581

Merged
rainxchzed merged 4 commits into
mainfrom
feat/search-starred-favourites
May 12, 2026
Merged

feat: search in favourites + starred (#562)#581
rainxchzed merged 4 commits into
mainfrom
feat/search-starred-favourites

Conversation

@rainxchzed
Copy link
Copy Markdown
Member

@rainxchzed rainxchzed commented May 12, 2026

Add inline search bar to Favourites and Starred screens, matching the existing Apps-screen search pattern. Filter is case-insensitive across repo name, owner, description, and primary language. Closes #562.

UX: search bar appears above the grid only when the underlying list is non-empty (no clutter on empty state). Clear-X trailing icon resets the query. remember-cached filter recomputes only when list or query changes.

Note: ~/.gradle was unmounted during this session — no local compile-verify. Visual review only. Please compile-check before merge: :feature:favourites:presentation and :feature:starred:presentation (both Android + JVM targets).

Summary by CodeRabbit

  • New Features
    • Added search to Starred and Favourites: top-of-screen search bars let you quickly filter lists by repository name, owner, description, or language (case-insensitive). Results update instantly and include a clear button for easy reset; search is shown when there are repositories and integrates with existing loading and refresh behaviors.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 53713abe-ef63-4511-a223-db4b45dd5cee

📥 Commits

Reviewing files that changed from the base of the PR and between 368e039 and 3498666.

📒 Files selected for processing (2)
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposViewModel.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt

Walkthrough

Search is added to Starred and Favourites: new OnSearchChange actions, searchQuery in state, view-model handlers, UI search bars, and case-insensitive filtering (name, owner, description, language). Release notes updated.

Changes

Search in Starred and Favourites

Layer / File(s) Summary
Favourites search: action, state, VM, and UI
feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesAction.kt, FavouritesState.kt, FavouritesViewModel.kt, FavouritesRoot.kt
FavouritesAction.OnSearchChange carries a query string; FavouritesState.searchQuery added; FavouritesViewModel.onAction updates state on search changes; FavouritesRoot adds FavouritesSearchBar, conditionally shows it when favourites exist, computes filteredRepositories via case-insensitive matching against name/owner/description/language, and renders the filtered list.
Starred search: action, state, VM, and UI
feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposAction.kt, StarredReposState.kt, StarredReposViewModel.kt, StarredReposRoot.kt
StarredReposAction.OnSearchChange carries a query string; StarredReposState.searchQuery added; StarredReposViewModel.onAction updates/clears searchQuery (cleared on refresh); StarredReposRoot adds StarredSearchBar, computes filteredRepositories via case-insensitive matching, and feeds filtered results to the grid.
Release notes update
core/presentation/src/commonMain/composeResources/files/whatsnew/17.json
Version 17 release notes include: "Search in Starred and Favourites — quickly filter long lists by repo name, owner, description, or language."

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • OpenHub-Store/GitHub-Store#177: Introduced the initial Starred and Favourites presentation components that this PR extends with search functionality.

Poem

🐇 I nibble keys and chase the light,
Typing queries through the night,
Starred and Favourites, small and grand,
Filtered quick by paw and hand,
Hooray—search hops across the land!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: search in favourites + starred (#562)' directly summarizes the main change—adding search functionality to both Favourites and Starred screens, which aligns perfectly with the changeset.
Linked Issues check ✅ Passed All coding requirements from issue #562 are met: case-insensitive search filtering by repo name/owner/description/language implemented in both Favourites and Starred screens, search bar UI added and conditionally shown, clear button included, and state management added.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing search functionality in Favourites and Starred screens. The WhatsNew update documents the feature; all code changes support the search feature without introducing unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/search-starred-favourites

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 and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 12, 2026

Greptile Summary

  • Adds case-insensitive inline search bars to both Starred and Favourites screens, filtering across repo name, owner, description, and language; the bar is hidden on empty lists and the filter is remember-cached on list+query keys, matching the existing Apps-screen pattern.
  • StarredReposViewModel correctly clears searchQuery on OnRefresh so a stale filter doesn't hide freshly-synced results; FavouritesViewModel has no refresh action so no equivalent reset is needed there.
  • Two P2 UX gaps remain: no "no results" empty-state when the filter matches nothing, and FavouritesViewModel doesn't clear searchQuery when the last favourite is removed — the stale query silently reactivates the next time a new favourite is added.

Confidence Score: 5/5

Safe to merge; all findings are P2 UX suggestions with no runtime errors or data-loss risk.

Both previously-flagged P1 issues (missing isNotEmpty guard on Starred search bar; stale query on refresh) are resolved in this revision. Remaining comments are P2 quality-of-life gaps that do not affect correctness or data integrity.

No files require special attention beyond the two P2 UX gaps noted in FavouritesRoot.kt and StarredReposRoot.kt.

Important Files Changed

Filename Overview
feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt Adds inline search bar (with guard and clear-X) and remember-cached filter above the staggered grid; pull-to-refresh correctly resets the query in the ViewModel; minor UX gap: no "no results" empty-state for zero filtered matches.
feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt Mirrors the Starred search pattern; search bar correctly hidden on empty list; stale-query risk when all items are removed while a filter is active and a new favourite is later added.
feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposViewModel.kt Adds OnSearchChange handler updating searchQuery; OnRefresh correctly clears searchQuery before syncing to avoid stale filter on refreshed data.
feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesViewModel.kt Adds OnSearchChange handler; no refresh action so no query-reset needed there; stale-query-on-empty-list concern is in the DB observation flow (outside this diff).
feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposAction.kt Adds OnSearchChange(query) action; straightforward addition.
feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesAction.kt Adds OnSearchChange(query) action; straightforward addition.
feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposState.kt Adds searchQuery: String = "" field; defaults to empty string as expected.
feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesState.kt Adds searchQuery: String = "" field; defaults to empty string as expected.
core/presentation/src/commonMain/composeResources/files/whatsnew/17.json Appends "Search in Starred and Favourites" bullet to version 17 release notes; JSON comma correctly added to previous entry.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User types in SearchBar] --> B[OnSearchChange dispatched]
    B --> C[ViewModel updates searchQuery in state]
    C --> D{favouriteRepositories / starredRepositories non-empty?}
    D -- Yes --> E[remember recomputes filteredRepositories]
    D -- No --> F[Search bar hidden, stale query persists in state]
    E --> G{query blank?}
    G -- Yes --> H[Show full list]
    G -- No --> I[Filter: name / owner / description / language]
    I --> J{filteredRepositories empty?}
    J -- Yes --> K[Empty grid shown — no feedback ⚠️]
    J -- No --> L[Render LazyVerticalStaggeredGrid]
    F --> M[New favourite added later]
    M --> N[Search bar reappears with stale query ⚠️]
Loading

Reviews (2): Last reviewed commit: "fix(starred): guard search bar + clear q..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@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: 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
`@feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt`:
- Line 161: The code references Modifier.animateItem() in FavouritesRoot (the
composable using Modifier.animateItem()), but the extension import is missing;
add the import androidx.compose.foundation.lazy.staggeredgrid.animateItem to the
top of FavouritesRoot.kt (the imports section) so Modifier.animateItem()
resolves correctly.

In
`@feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt`:
- Around line 155-159: StarredSearchBar is always rendered inside the Column
even when isSyncing && starredRepositories.isEmpty(), but the UI should only
show the search bar when the repository list is non-empty; update the
composition to conditionally render StarredSearchBar only when
starredRepositories.isNotEmpty() (or inverse check starredRepositories.isEmpty()
== false), keeping the same props (query = state.searchQuery and onQueryChange =
{ onAction(StarredReposAction.OnSearchChange(it)) }); ensure the condition uses
the same state/source where isSyncing and starredRepositories are defined so the
search bar is omitted during the empty-syncing state.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6ba95b50-5531-472e-ad8c-139b9c2748ba

📥 Commits

Reviewing files that changed from the base of the PR and between 3adde72 and 368e039.

📒 Files selected for processing (9)
  • core/presentation/src/commonMain/composeResources/files/whatsnew/17.json
  • feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesAction.kt
  • feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt
  • feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesState.kt
  • feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesViewModel.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposAction.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposRoot.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposState.kt
  • feature/starred/presentation/src/commonMain/kotlin/zed/rainxch/starred/presentation/StarredReposViewModel.kt

onDevProfileClick = {
onAction(FavouritesAction.OnDeveloperProfileClick(repo.repoOwner))
},
modifier = Modifier.animateItem(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify animateItem usage/import consistency in Kotlin sources
rg -n --type=kt '\banimateItem\s*\('
rg -n --type=kt 'import\s+androidx\.compose\.foundation\.lazy\.staggeredgrid\.animateItem'

Repository: OpenHub-Store/GitHub-Store

Length of output: 124


🏁 Script executed:

#!/bin/bash
# Find the target file
fd "FavouritesRoot.kt" -type f

# If file exists, check its imports and content around line 161
if [ -f "feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt" ]; then
  echo "=== File found. Checking imports and line 161 ==="
  echo "--- Imports section ---"
  head -50 "feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt" | grep -n "import"
  echo ""
  echo "--- Around line 161 ---"
  sed -n '155,170p' "feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt"
fi

Repository: OpenHub-Store/GitHub-Store

Length of output: 3764


🏁 Script executed:

#!/bin/bash
# Search for all animateItem usages in kotlin files
rg "animateItem\s*\(" --glob="*.kt" -n

# Search for imports of animateItem from any source
rg "import.*animateItem" --glob="*.kt" -n

# Check if animateItem is defined anywhere in the project
rg "fun.*animateItem" --glob="*.kt" -n
rg "extension.*animateItem" --glob="*.kt" -n

Repository: OpenHub-Store/GitHub-Store

Length of output: 1489


🏁 Script executed:

#!/bin/bash
# Check imports in one other file that uses animateItem
echo "=== Checking SearchRoot.kt imports ==="
head -60 "feature/search/presentation/src/commonMain/kotlin/zed/rainxch/search/presentation/SearchRoot.kt" | grep "import.*staggeredgrid"

Repository: OpenHub-Store/GitHub-Store

Length of output: 407


Add missing import for animateItem() extension function.

Line 161 uses Modifier.animateItem() without importing the extension from androidx.compose.foundation.lazy.staggeredgrid, which will cause an unresolved reference compile error.

Proposed fix
 import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
 import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
+import androidx.compose.foundation.lazy.staggeredgrid.animateItem
 import androidx.compose.foundation.lazy.staggeredgrid.items
 import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
🤖 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
`@feature/favourites/presentation/src/commonMain/kotlin/zed/rainxch/favourites/presentation/FavouritesRoot.kt`
at line 161, The code references Modifier.animateItem() in FavouritesRoot (the
composable using Modifier.animateItem()), but the extension import is missing;
add the import androidx.compose.foundation.lazy.staggeredgrid.animateItem to the
top of FavouritesRoot.kt (the imports section) so Modifier.animateItem()
resolves correctly.

@rainxchzed rainxchzed merged commit ab5a617 into main May 12, 2026
1 check passed
@rainxchzed rainxchzed deleted the feat/search-starred-favourites branch May 12, 2026 10:14
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.

Search in Starred and Favorites

1 participant