-
Notifications
You must be signed in to change notification settings - Fork 0
feat(ui,hooks): add recently used version to the version picker #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: c0bf504 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
- filter out the recently used versions in the useFilterVersions hook to remove them from the main list so they don't show twice. - add top 3 most recently clicked on bible versions and store them in localStorage. - allow both lists to be filtered through the searchQuery.
844ff89 to
8b0c2a4
Compare
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Greptile SummaryAdds a "Recently Used Versions" feature to the Bible version picker that tracks the top 3 most recently clicked versions in localStorage and displays them in a separate section above the main list. Key Changes:
Implementation Quality:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant VersionPicker as BibleVersionPicker
participant LocalStorage
participant Hook as useFilteredVersions
participant State as React State
User->>VersionPicker: Opens picker
VersionPicker->>LocalStorage: getRecentVersions()
LocalStorage-->>VersionPicker: Returns recent versions array
VersionPicker->>State: Initialize recentVersions state
VersionPicker->>Hook: Call useFilteredVersions(versions, searchQuery, language, recentVersions)
Hook->>Hook: Filter by language
Hook->>Hook: Filter by search term
Hook->>Hook: Exclude recent versions from main list
Hook-->>VersionPicker: Returns filtered versions
VersionPicker->>User: Display "Recently Used Versions" section
VersionPicker->>User: Display "All Versions" section (without recent versions)
User->>VersionPicker: Selects a version
VersionPicker->>VersionPicker: Call addRecentVersion()
VersionPicker->>State: Update recentVersions state (move to top, limit to 3)
VersionPicker->>LocalStorage: saveRecentVersions()
LocalStorage-->>VersionPicker: Persisted
VersionPicker->>Hook: Re-filter with updated recentVersions
Hook-->>VersionPicker: Returns updated filtered list
VersionPicker->>User: Close picker with new selection
User->>VersionPicker: Opens picker again
VersionPicker->>User: Shows selected version in "Recently Used Versions"
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 files reviewed, 1 comment
931ddbf to
6b01ea5
Compare
|
By OpenCode Here's a fun little code review that I had OpenCode do.## Code Review: PR #106 - Recently Used Versions FeatureOverviewAdds localStorage-based "Recently Used Versions" feature (max 3) to Bible version picker with search filtering and exclusion from main list. 🔴 Critical Issues1. Bug in search filter logic -
|
cameronapak
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Brenden, this code mainly looks good. I had a few small nitpicks and one suggestion. Thank you for your hard work on this!
| function getStoredRecentVersions(): StoredRecentVersion[] { | ||
| return JSON.parse(localStorage.getItem(RECENT_VERSIONS_KEY) || '[]') as StoredRecentVersion[]; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: I know that this is weird, but sometimes when I see something like this, I really want to wrap it in a try-catch because I've totally messed with local storage and can see somebody else messing with local storage and then it breaking the app.
| import { BookOpen } from 'lucide-react'; | ||
| import { Button } from './ui/button'; | ||
|
|
||
| const RECENT_VERSIONS_KEY = 'youversion-platform:picker:recent-versions'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: Since this is testing the version picker component and we have two of these keys, one in this test file, one in the regular file, can we move that into one file?
| {/* Versions View */} | ||
| <div | ||
| className={`yv:h-[66vh] yv:flex yv:flex-col yv:transition-all yv:duration-300 yv:rounded-2xl yv:origin-center ${ | ||
| className={`yv:min-h-0 yv:flex yv:flex-col yv:transition-all yv:duration-300 yv:rounded-2xl yv:origin-center ${ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: I'm suggesting that we add back the max height so that it doesn't get too tall
| className={`yv:min-h-0 yv:flex yv:flex-col yv:transition-all yv:duration-300 yv:rounded-2xl yv:origin-center ${ | |
| className={`yv:min-h-0 yv:max-h-[66svh] yv:flex yv:flex-col yv:transition-all yv:duration-300 yv:rounded-2xl yv:origin-center ${ |
|
@greptileai, do you find any validity to the details in this AI code review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at that AI code review, I can see several valid points mixed with some that are less critical. Let me break down what I think has merit:
Valid Concerns:
-
Search performance - The reviewer correctly identifies that filtering recent versions on every render could be optimized. The current implementation recreates the filter array each time:
const filteredRecentVersions = useMemo(() => { if (!searchQuery.trim()) return recentVersions; const query = searchQuery.trim().toLowerCase(); return recentVersions.filter(/* ... */); }, [recentVersions, searchQuery]);
This is actually fine though since it's memoized and recent versions are limited to 3 items.
-
Error handling - The
getRecentVersions()function has a basic try/catch, but it could be more robust about handling malformed JSON or migration scenarios. -
Type safety - The concern about runtime type validation is valid. If localStorage contains unexpected data, it could cause issues.
Less Critical Points:
-
"Complex state management" - The recent versions logic is actually quite straightforward and well-contained within the component.
-
"Performance impact" - With max 3 recent versions, the performance impact is negligible.
-
"Accessibility concerns" - The component already has proper ARIA labels and semantic structure.
Specific Issues I'd Address:
The most valid concern is around localStorage data integrity. Here's what I'd suggest improving:
function getRecentVersions(): RecentVersion[] {
if (typeof window === 'undefined') return [];
try {
const stored = localStorage.getItem(RECENT_VERSIONS_KEY);
if (!stored) return [];
const parsed = JSON.parse(stored);
if (!Array.isArray(parsed)) return [];
// Validate each item has required properties
return parsed.filter((item): item is RecentVersion =>
typeof item === 'object' &&
item !== null &&
typeof item.id === 'number' &&
typeof item.title === 'string' &&
typeof item.localized_abbreviation === 'string'
).slice(0, MAX_RECENT_VERSIONS);
} catch {
return [];
}
}
Overall, the review raises some legitimate points about robustness, but most of the current implementation is solid. The main improvement would be better data validation when reading from localStorage.
d1b5fac to
87e71fe
Compare
cameronapak
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me!
Light mode:

Dark mode:
