Skip to content
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

Add media library permissions handling and photo access components #352

Merged
merged 6 commits into from
Jan 3, 2025

Conversation

jaronheard
Copy link
Owner

@jaronheard jaronheard commented Jan 3, 2025

  • ✨ feat: enhance loading states and empty state handling in feed view
  • ♻️ refactor: revert to using EventListItemSkeleton component
  • ✨ feat: enhance photo library access handling and UI feedback
  • ✨ feat: enhance photo library permission handling and media access
  • ♻️ refactor: improve media library permissions and photo loading logic
  • ♻️ remove unused PhotoAccessPrompt import and hasFullPhotoAccess state

Summary by CodeRabbit

Release Notes

  • New Features

    • Added enhanced media permissions management for photo access
    • Introduced a new photo access prompt to guide users through permission settings
  • Improvements

    • Refined photo selection and loading process
    • Added more robust handling of media library permissions
    • Improved user experience for photo access management
  • Bug Fixes

    • Resolved issues with photo loading and permission checks
    • Enhanced state management for media permissions

The update focuses on improving photo access and permissions, providing users with clearer guidance and more control over their media library interactions.

The commit improves user experience by implementing better loading states and
empty state handling, including a new LoadingEventItem component and refined
conditional rendering logic for various feed states.
The commit improves the photo library access experience by:
- Adding support for partial photo access on iOS
- Introducing a dedicated PhotoAccessPrompt component
- Implementing ActionSheet for managing photo permissions
The commit improves media library access by adding support for partial photo
access, implementing proper permission checks, and optimizing photo grid
display based on permission status.
The commit reorganizes the media library handling in the NewEventModal component,
introducing better separation of concerns and more reliable permission checks
through useFocusEffect.
Copy link

linear bot commented Jan 3, 2025

Copy link

vercel bot commented Jan 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
soonlist-turbo ⬜️ Skipped (Inspect) Jan 3, 2025 8:47am

Copy link
Contributor

coderabbitai bot commented Jan 3, 2025

Walkthrough

The pull request focuses on enhancing media permissions and photo access functionality across multiple components in an Expo application. The changes introduce a comprehensive approach to managing media library access, including checking permissions, handling user interactions, and providing clear UI guidance. The modifications span several files, adding new components like PhotoAccessPrompt, updating state management in the app store, and implementing a more robust media permissions hook.

Changes

File Change Summary
apps/expo/src/app/new.tsx Updated PhotoGrid component props to include media permission checks, added useFocusEffect for permission management, modified rendering logic to handle different permission states
apps/expo/src/components/AddEventButton.tsx Added media permission check before navigation, implemented permission request logic
apps/expo/src/components/PhotoAccessPrompt.tsx New component created to prompt users for photo library access with settings navigation
apps/expo/src/hooks/useMediaPermissions.ts Enhanced permission checking logic, added subscription to media library changes
apps/expo/src/store.ts Added new state properties for hasFullPhotoAccess, isLoadingPhotos, and photoLoadingError

Sequence Diagram

sequenceDiagram
    participant User
    participant App
    participant MediaLibrary
    participant DeviceSettings

    User->>App: Attempts to access photos
    App->>MediaLibrary: Check Permissions
    alt No Media Permission
        App->>User: Show PhotoAccessPrompt
        User->>DeviceSettings: Enable Photo Access
        DeviceSettings-->>MediaLibrary: Update Permissions
    end
    MediaLibrary-->>App: Confirm Permissions
    App->>App: Load Recent Photos
    App->>User: Display Photo Grid
Loading

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai bot changed the title @coderabbitai Add media library permissions handling and photo access components Jan 3, 2025
Copy link
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

🧹 Nitpick comments (10)
apps/expo/src/hooks/useMediaPermissions.ts (2)

12-21: Handle permission statuses more granularly if required.
Right now, the code treats both partial and fully granted permissions uniformly for isGranted. If you need special logic for limited access (e.g., “selected photos” on iOS), you might separate checks for each permission type (e.g., “limited,” “denied,” etc.).


39-39: Confirm necessity of both setHasMediaPermission and setRecentPhotos.
Although you’re referencing both store setters in the dependency array, setHasMediaPermission isn’t directly used in this effect definition. Verify whether you need it here to avoid unnecessary re-renders.

apps/expo/src/app/new.tsx (6)

64-68: Props are well-structured but watch for future complexity.
Expanding PhotoGrid with extra permission flags is fine for now. If you continue adding more permission types, consider an all-in-one permission object.


85-89: Don’t pass empty array if permission is denied.
This approach to conditionally set data improves privacy by hiding photos from the grid. If you need to prompt the user more strongly for permission, consider an alternative UI that directs them to “request permission.”


107-120: Support partial library permission states contextually.
The user sees the “Manage” button only if they have partial library access. This is a good pattern. Double-check the copy for clarity, especially if you later add more granular states (e.g., “limited”).


539-544: Offline or ephemeral states might need error handling.
Currently, you rely on re-focusing to reload. If the user is offline, consider storing partial state or gracefully handling errors in setPhotoLoadingError.


576-576: Console logging the most recent photo is fine.
If this is only for debugging, remove or wrap it with a debug flag to avoid noise for production.


720-816: Preview container logic is large; consider splitting.
The multiple conditions for either image preview, link preview, or text input can become unwieldy. Factor out a smaller component if this grows further.

apps/expo/src/components/PhotoAccessPrompt.tsx (1)

10-16: Good practice: direct user to system settings.
This approach is typical for partial media permissions. Consider including a direct “requestPermissionsAsync” fallback for better control on Android.

apps/expo/src/store.ts (1)

221-222: Check usage of isLoadingPhotos / photoLoadingError.
These new states are settable but aren’t used extensively. Consider a loading spinner or error message in the UI to improve the user experience.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d45328c and 36a78da.

📒 Files selected for processing (5)
  • apps/expo/src/app/new.tsx (9 hunks)
  • apps/expo/src/components/AddEventButton.tsx (1 hunks)
  • apps/expo/src/components/PhotoAccessPrompt.tsx (1 hunks)
  • apps/expo/src/hooks/useMediaPermissions.ts (1 hunks)
  • apps/expo/src/store.ts (3 hunks)
🔇 Additional comments (21)
apps/expo/src/hooks/useMediaPermissions.ts (3)

7-7: Use destructured setters for clarity.
Using destructured store setters is effective for readability. Just ensure you invoke them consistently within your codebase to reduce ambiguity.


23-28: Validate potential repeated subscriptions.
When isGranted is true, checkPermissionsAndSubscribe re-subscribes after incremental changes, which could result in multiple active subscriptions if frequent changes occur. Although you clear the subscription on unmount, consider ensuring you don’t stack multiple subscriptions.


32-32: Immediate invocation is well-organized.
Calling checkPermissionsAndSubscribe() upon mount is a good approach to ensure immediate permission checks and subscriptions.

apps/expo/src/app/new.tsx (11)

3-3: Platform-specific consideration for ActionSheetIOS.
Importing ActionSheetIOS explicitly ties the code to iOS. Ensure the app gracefully handles or bypasses this flow on Android.


37-37: Recheck necessity of PhotoAccessPrompt import.
The import seems essential, but ensure there’s no circular dependency or leftover references if you later relocate the prompt.


81-83: Inline handler is straightforward.
handleManagePress simply opens settings, which is consistent with iOS partial-permissions workflows.


91-96: Clear heading text.
This “Recents” heading is helpful. Just ensure it’s localized or consistent with your design guidelines if needed.


124-124: Appropriate key assignment for FlatList data.
Using id is suitable. If new placeholders or logic are added, ensure unique id generation.


226-226: Ensure consistent usage of hasFullPhotoAccess.
You’ve destructured hasFullPhotoAccess; confirm it’s used consistently throughout.


462-535: In-depth focus effect is well-organized but watch for repeated permission calls.
You’re loading permissions and photos each focus. That’s good to stay fresh, but ensure a user’s repeated navigations don’t cause excessive calls. Possibly skip if hasMediaPermission is already up to date.


717-719: Conditional usage of PhotoAccessPrompt.
Nicely done to handle prompting only if permission is absent and not from an external intent. Verify that “describe” is always a safe override.


819-827: PhotoGrid usage is consistent.
Passing hasMediaPermission and hasFullPhotoAccess keeps the logic in the same domain. Good job.


833-848: Create event button approach is user-friendly.
Disabling the button if no input is present avoids spurious requests. The Capture event label is clear.


850-850: Overall structural clarity.
The final bracket ends a large conditional block. Everything looks consistent.

apps/expo/src/components/PhotoAccessPrompt.tsx (3)

1-2: Confirm that Linking to Settings is cross-platform.
On iOS, openSettings() function typically routes to the app settings. On Android, this may open a default settings screen or sometimes do nothing. Consider a fallback approach for other platforms.


5-8: Prop naming clarity is good.
onClose and showCloseButton are intuitive. Keep them consistent if you add more prompt variants.


18-47: UI layout is minimal and direct.
Centering the message is user friendly. The text clearly indicates why the permission is needed. Nicely done.

apps/expo/src/store.ts (2)

72-72: Adding a separate hasFullPhotoAccess flag is beneficial
Separating partial from full permission states is helpful for handling iOS “limited” access. Good addition.


204-204: Keep partial permission states in sync.
You set default hasFullPhotoAccess: false. Ensure that any manual permission updates or partial-limited toggles do not incorrectly override.

apps/expo/src/components/AddEventButton.tsx (2)

13-13: Decoupled permission logic.
Retrieving hasMediaPermission directly from the store is clean. Just ensure you handle partial permission states if you plan to differentiate “limited” vs “full.”


16-20: Conditional logic is straightforward.
Early return if permission is already present is a good design. Minimizes redundant permission requests.

Comment on lines +129 to +152
onPress={() => {
if (hasMediaPermission && !hasFullPhotoAccess) {
// Show action sheet for partial access
ActionSheetIOS.showActionSheetWithOptions(
{
options: [
"Select More Photos",
"Change Settings",
"Cancel",
],
cancelButtonIndex: 2,
},
(buttonIndex) => {
if (buttonIndex === 0) {
void MediaLibrary.presentPermissionsPickerAsync();
} else if (buttonIndex === 1) {
void Linking.openSettings();
}
},
);
} else {
onMorePhotos();
}
}}
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 3, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

ActionSheet iOS block might need Android fallback.
Relying on ActionSheetIOS.showActionSheetWithOptions can disrupt cross-platform usage. Ensure you degrade gracefully on Android, or wrap it with a suitable platform check.

Copy link
Owner Author

Choose a reason for hiding this comment

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

not focusing on ios for now

Copy link
Contributor

Choose a reason for hiding this comment

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

@jaronheard Understood! Since you’re not focusing on cross-platform functionality at the moment, we can skip adding a fallback on Android for now. Let me know if you want to revisit this in the future.

Comment on lines +28 to +31
router.push("/new");
} catch (error) {
console.error("Error requesting media permissions:", error);
router.push("/new");
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 3, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider not navigating if user denies.
Even if an error or denial occurs, you still call router.push("/new"). That might confuse users who can’t actually pick images. Possibly remain on the current screen or show a prompt if the user denies.

Copy link
Owner Author

Choose a reason for hiding this comment

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

intended behavior

Copy link
Contributor

Choose a reason for hiding this comment

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

@jaronheard Understood—thanks for clarifying. We’ll keep the existing navigation flow as is. Let me know if anything else comes up!

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.

1 participant