Repository navigation
fix(ui): remove a device from the list after signing it out - #1004
Conversation
"Sign out of this device" revoked the session, but the Active devices
list kept showing it until Security was reopened. The row's
DeviceViewModel re-fetched active sessions and threw the result away,
and the list lives in UserProfileSecurityViewModel. Every row also
shared one DeviceViewModel, and the section passed onError = {}, so a
failed sign-out was silent.
Sign-out now lives in UserProfileSecurityViewModel, which owns the list.
On success it drops the revoked session from the list. On failure it
leaves the list alone and reports the error through the screen's
existing snackbar. DeviceViewModel and its test are deleted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: clerk/clerk-android/.coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (7)
💤 Files with no reviewable changes (2)
Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour. 📝 WalkthroughWalkthroughDevice sign-out now uses a callback from the device row to ChangesDevice-session sign-out
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to Device sign-out now removes the session from the list on success and reports errors on failure. No merge-blocking risk was identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Emulator recordingWorkbench on a clean Pixel (API 36) emulator, this branch merged locally with #1002 and #997. Path: UserButton > Security > Active devices. Before the tap, the list had six devices. "Sign out of this device" on the second row (10:57 AM) returned devices-refresh-fixed.mp4On |
swolfand
left a comment
There was a problem hiding this comment.
Moving sign-out into the screen's ViewModel is the right ownership, and the tests check the list the user sees. Non-blocking: if a reload is still in flight when a revoke finishes, the state is Loading, so the removal is skipped and the revoked row can come back until the next reload. Keeping the revoked ids in a set and filtering them in loadSessions would close that. LGTM.
Summary
In the prebuilt UserProfile > Security > Active devices list, "Sign out of this device" revoked the session, but the device stayed in the list until you left and reopened Security.
Each row had its own
DeviceViewModel. After a successful revoke it calledClerk.user?.activeSessions()and discarded the result, while the list itself lives inUserProfileSecurityViewModel. Two related problems:DeviceViewModel, becauseviewModel()was called without a key.onError = {}, so a failed sign-out showed nothing.Sign-out now lives in
UserProfileSecurityViewModel, which owns the list:The row and section take an
onSignOutcallback, andDeviceViewModeland its test are deleted. That test only asserted the row's ownSuccessstate, which is why it passed while the list stayed stale.Testing
UserProfileSecurityViewModelTestcases:./gradlew :source:ui:testDebugUnitTest :source:ui:spotlessCheck :source:ui:detektpasses (504 tests).Verified on an emulator
The Active devices list only renders with #1002, and sign-out only succeeds with #997. So I verified with this branch merged locally with both: workbench on a clean API 36 emulator, test instance
amusing-barnacle-26, the test user with six active sessions. "Sign out of this device" on the second row returned 200, and that row disappeared immediately, while the screen stayed on Security. Recording follows in a comment.This PR doesn't depend on either one to merge, since it only changes where the list is updated.
🤖 Generated with Claude Code
Summary by CodeRabbit