feat(frontend): dedicated account settings from profile tab#77
feat(frontend): dedicated account settings from profile tab#77SamanSP1386 merged 6 commits intodevfrom
Conversation
- Add /account-settings stack screen with message notifications, sign out, and delete account - Profile tab shows a Settings row (and account settings on incomplete profile) linking there - Web: OpenInAppPrompt for account settings deep link, consistent with profile tab - Fix typed-route pushes with as never where the generated routes lag Made-with: Cursor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 53 minutes and 1 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 Walkthrough📝 Walkthrough🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
frontend/app/account-settings.tsx (1)
177-184: Outer catch block appears unreachable.The
tryblock for handling notifications has early returns in all error paths before reaching this outer catch. The only code path that could reach here is ifupdateMessageNotificationsEnabled({ enabled: true })on line 139 throws, but this would be the same error type handled in the inner catch blocks.Consider whether this catch is intentionally defensive or can be removed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/account-settings.tsx` around lines 177 - 184, The outer catch in the notification update flow is effectively unreachable because all inner error paths return; either remove the outer catch block and keep the finally that calls setIsUpdatingMessageNotifications(false), or change inner handlers to rethrow so the outer catch can handle them; locate the try/catch surrounding updateMessageNotificationsEnabled, setMessageNotificationsValue, and setIsUpdatingMessageNotifications and either delete the outer catch (leaving finally) or make inner catch blocks rethrow the error so the outer catch can run.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/app/account-settings.tsx`:
- Around line 140-176: When disabling notifications, handle the case where
removePushToken fails but updateMessageNotificationsEnabled succeeds: detect
removePushTokenError after the preference update and either (a) revert the saved
preference by calling updateMessageNotificationsEnabled({ enabled: true }) and
setMessageNotificationsValue(previousValue) or (b) surface an immediate
Alert.alert to inform the user that their push token could not be removed and
they may still receive notifications, including the removePushTokenError
message; update the block around removePushToken /
updateMessageNotificationsEnabled to perform this check and take one of the two
actions (retry/remediate or notify) using the existing identifiers
removePushToken, updateMessageNotificationsEnabled, removePushTokenError,
removePushTokenSucceeded, setMessageNotificationsValue, previousValue, and
Alert.alert.
---
Nitpick comments:
In `@frontend/app/account-settings.tsx`:
- Around line 177-184: The outer catch in the notification update flow is
effectively unreachable because all inner error paths return; either remove the
outer catch block and keep the finally that calls
setIsUpdatingMessageNotifications(false), or change inner handlers to rethrow so
the outer catch can handle them; locate the try/catch surrounding
updateMessageNotificationsEnabled, setMessageNotificationsValue, and
setIsUpdatingMessageNotifications and either delete the outer catch (leaving
finally) or make inner catch blocks rethrow the error so the outer catch can
run.
🪄 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: 647d3e07-4966-416c-961b-429bff5977f8
📒 Files selected for processing (4)
frontend/app/(tabs)/settings.tsxfrontend/app/_layout.tsxfrontend/app/account-settings.tsxfrontend/app/listings/[id].tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
backend/convex/blocks.ts (1)
110-112: Docstring behavior mismatch for hidden profiles.The comment says hidden profiles are omitted, but the implementation still returns a row (
"Unavailable user"). Update wording to match runtime behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/convex/blocks.ts` around lines 110 - 112, The docstring above the blocks query/comment stating "Omits hidden profiles but still returns blockedId" doesn't match runtime behavior—hidden profiles are not omitted and are returned as an "Unavailable user" placeholder row; update the comment text (the block starting "Users the current account has blocked (for settings / management UI). Sorted by display name. Omits hidden profiles but still returns blockedId so they can be unblocked.") to state that hidden profiles are included as an "Unavailable user" placeholder (while still returning blockedId) so the docstring matches the implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/convex/blocks.ts`:
- Around line 125-128: The lookup of a profile uses .unique() on the by_userId
index (ctx.db.query('profiles').withIndex('by_userId', (q) => q.eq('userId',
block.blockedId)).unique()) but that index isn't guaranteed DB-unique; replace
.unique() with .first() to defensively return the first matching profile instead
of throwing on accidental duplicates, keeping the existing null-handling logic
intact (or optionally add a DB migration to enforce uniqueness if you prefer a
strict constraint).
---
Nitpick comments:
In `@backend/convex/blocks.ts`:
- Around line 110-112: The docstring above the blocks query/comment stating
"Omits hidden profiles but still returns blockedId" doesn't match runtime
behavior—hidden profiles are not omitted and are returned as an "Unavailable
user" placeholder row; update the comment text (the block starting "Users the
current account has blocked (for settings / management UI). Sorted by display
name. Omits hidden profiles but still returns blockedId so they can be
unblocked.") to state that hidden profiles are included as an "Unavailable user"
placeholder (while still returning blockedId) so the docstring matches the
implementation.
🪄 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: 0ef507e5-c0ac-4fea-ad2c-8c0f87d08f88
📒 Files selected for processing (4)
backend/convex/blocks.tsfrontend/app/account-settings.tsxfrontend/ios/PolyBuys.xcodeproj/project.xcworkspace/contents.xcworkspacedatafrontend/ios/PolyBuys.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
✅ Files skipped from review due to trivial changes (3)
- frontend/ios/PolyBuys.xcodeproj/project.xcworkspace/contents.xcworkspacedata
- frontend/ios/PolyBuys.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
- frontend/app/account-settings.tsx
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/convex/blocks.ts`:
- Around line 109-112: Update the doc comment sentence that currently reads
"Users the current account has blocked" to the grammatically correct "Users that
the current account has blocked" in the comment block above the relevant export
in backend/convex/blocks.ts (the comment describing blocked users / settings
management UI and placeholder name behavior).
- Around line 118-144: The loop performs a serial DB call per block; instead
collect unique blockedIds from the `blocks` result, fetch all matching
`profiles` in a single batched query (use
`ctx.db.query('profiles').withIndex('by_userId', q => q.in('userId',
blockedIds)).collect()`), build a map from profile.userId to profile, then
iterate `blocks` to populate `rows` using the map (fall back to 'Unknown user'
or 'Unavailable user' when no profile or profile.isHidden). Replace
per-iteration `ctx.db.query('profiles').first()` calls with this batched
approach in the same function where `blocks`, `rows`, and `blockedId` are used.
🪄 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: 9bf4d533-c7ab-42ae-94c0-0157b458900a
📒 Files selected for processing (2)
backend/convex/blocks.tsfrontend/app/account-settings.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/app/account-settings.tsx
| const blocks = await ctx.db | ||
| .query('userBlocks') | ||
| .withIndex('by_blocker_blocked', (q) => q.eq('blockerId', blockerId)) | ||
| .collect(); | ||
|
|
||
| const rows: BlockedUserListRow[] = []; | ||
|
|
||
| for (const block of blocks) { | ||
| const profile = await ctx.db | ||
| .query('profiles') | ||
| .withIndex('by_userId', (q) => q.eq('userId', block.blockedId)) | ||
| .first(); | ||
|
|
||
| if (!profile) { | ||
| rows.push({ blockedId: block.blockedId, name: 'Unknown user' }); | ||
| continue; | ||
| } | ||
| if (profile.isHidden) { | ||
| rows.push({ blockedId: block.blockedId, name: 'Unavailable user' }); | ||
| continue; | ||
| } | ||
| rows.push({ | ||
| blockedId: block.blockedId, | ||
| name: profile.name, | ||
| major: profile.major, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Avoid serial DB round-trips in the blocked-user loop.
The loop does one awaited profiles query per block (Line 125–129), so latency grows linearly and can degrade quickly for users with many blocks. Fetch profiles concurrently and iterate unique blocked IDs.
⚡ Proposed refactor
- const rows: BlockedUserListRow[] = [];
-
- for (const block of blocks) {
- const profile = await ctx.db
- .query('profiles')
- .withIndex('by_userId', (q) => q.eq('userId', block.blockedId))
- .first();
+ const blockedIds = [...new Set(blocks.map((b) => b.blockedId))];
+ const profilesByBlockedId = new Map(
+ await Promise.all(
+ blockedIds.map(async (blockedId) => {
+ const profile = await ctx.db
+ .query('profiles')
+ .withIndex('by_userId', (q) => q.eq('userId', blockedId))
+ .first();
+ return [blockedId, profile] as const;
+ })
+ )
+ );
+
+ const rows: BlockedUserListRow[] = [];
+ for (const blockedId of blockedIds) {
+ const profile = profilesByBlockedId.get(blockedId);
if (!profile) {
- rows.push({ blockedId: block.blockedId, name: 'Unknown user' });
+ rows.push({ blockedId, name: 'Unknown user' });
continue;
}
if (profile.isHidden) {
- rows.push({ blockedId: block.blockedId, name: 'Unavailable user' });
+ rows.push({ blockedId, name: 'Unavailable user' });
continue;
}
rows.push({
- blockedId: block.blockedId,
+ blockedId,
name: profile.name,
major: profile.major,
});
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/convex/blocks.ts` around lines 118 - 144, The loop performs a serial
DB call per block; instead collect unique blockedIds from the `blocks` result,
fetch all matching `profiles` in a single batched query (use
`ctx.db.query('profiles').withIndex('by_userId', q => q.in('userId',
blockedIds)).collect()`), build a map from profile.userId to profile, then
iterate `blocks` to populate `rows` using the map (fall back to 'Unknown user'
or 'Unavailable user' when no profile or profile.isHidden). Replace
per-iteration `ctx.db.query('profiles').first()` calls with this batched
approach in the same function where `blocks`, `rows`, and `blockedId` are used.
Made-with: Cursor
Linked Issues
Closes #77
Linear: POLY-56
Summary
Briefly explain the change and why.
How to Test
Steps to verify locally:
npm run lintnpm run typechecknpm testnpm run dev:backend(in terminal A)npm run dev(in terminal B)Checklist
npm run lint)devScreenshots / Demos
(if UI or visible behavior - attach images, videos, or GIFs)
Summary by CodeRabbit
New Features
Refactoring
Chores