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 functionality to check group members and show relevant content on PlacesList screen. #131

Merged

Conversation

cp-sneh-s
Copy link
Collaborator

@cp-sneh-s cp-sneh-s commented Dec 9, 2024

Changelog

Implemented a check to prevent adding places in a group with only one member. This change ensures that place management is only possible when there are multiple members in the group.

New Features

  • Added a condition to block place addition for groups with only one member.

Enhancements

  • Improved the functionality to ensure places can only be added when the group has more than one member.
Screen_recording_20241209_123116.mp4

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new UI component for displaying content when no members are present, including a title and subtitle.
    • Added loading indicators to enhance user feedback during data fetching.
    • Implemented functionality to manage space information and member invitations.
    • Enhanced error handling with immediate feedback mechanisms in various screens.
  • Bug Fixes

    • Improved conditional rendering to ensure appropriate content is displayed based on the presence of members.
    • Added validation checks for location coordinates to prevent invalid submissions.
  • Documentation

    • Added new string resources for clearer user instructions regarding group membership and adding places.

Copy link

coderabbitai bot commented Dec 9, 2024

Walkthrough

The pull request introduces several enhancements across multiple files, primarily focusing on managing and displaying user interface components related to member presence in a space. A new composable function, NoMemberEmptyContent, is added to provide a visual indication when no members are present. The PlacesListScreen is updated to utilize this new function and includes a loading state. Additionally, the PlacesListViewModel is enhanced with methods for managing space information and member invitations. New string resources are also added to support these UI changes.

Changes

File Change Summary
app/src/main/java/com/canopas/yourspace/ui/component/NoMemberEmptyContent.kt Added a new composable function NoMemberEmptyContent for displaying a no-member state.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListScreen.kt Introduced LoadingContent composable, modified content display logic to incorporate loading states and member checks.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListViewModel.kt Added methods getCurrentSpace and addMember, and expanded PlacesListScreenState with new properties.
app/src/main/java/com/canopas/yourspace/ui/flow/messages/thread/ThreadsScreen.kt Updated usage of NoMemberEmptyContent to include title and subtitle parameters, removed old implementation.
app/src/main/res/values/strings.xml Added new string resources for member-related UI messages.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapScreen.kt Added error handling with AppBanner for displaying error messages.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapViewModel.kt Introduced resetErrorState method and validation for location coordinates in addPlace.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameScreen.kt Refined error message display logic in AppBanner.
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameViewModel.kt Added validation for latitude and longitude in addPlace method to prevent invalid submissions.

Possibly related PRs

Suggested reviewers

  • cp-megh-l
  • kaushiksaliya

📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 66773d9 and afac3ae.

📒 Files selected for processing (2)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameScreen.kt (1 hunks)
  • app/src/main/res/values/strings.xml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameScreen.kt
  • app/src/main/res/values/strings.xml

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:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 or 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.

Copy link

@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

🧹 Outside diff range and nitpick comments (5)
app/src/main/java/com/canopas/yourspace/ui/component/NoMemberEmptyContent.kt (2)

23-29: Add parameter documentation and preview composable.

The implementation looks good! Consider these enhancements:

  1. Add KDoc to document parameters
  2. Add a preview composable for testing different states
+/**
+ * A composable that displays content when there are no members in a group
+ *
+ * @param loadingInviteCode Boolean indicating if invite code is being loaded
+ * @param title Resource ID for the title text
+ * @param subtitle Resource ID for the subtitle text
+ * @param addMember Callback invoked when add member button is clicked
+ */
@Composable
fun NoMemberEmptyContent(
    loadingInviteCode: Boolean,
    title: Int,
    subtitle: Int,
    addMember: () -> Unit
)

+@Preview(showBackground = true)
+@Composable
+private fun PreviewNoMemberEmptyContent() {
+    NoMemberEmptyContent(
+        loadingInviteCode = false,
+        title = R.string.place_list_screen_no_members_title,
+        subtitle = R.string.place_list_screen_no_members_subtitle,
+        addMember = {}
+    )
+}

37-42: Add content description for accessibility.

The icon should have a meaningful content description for accessibility.

 Icon(
     painter = painterResource(id = R.drawable.ic_thread_no_member),
-    contentDescription = null,
+    contentDescription = stringResource(id = R.string.content_description_no_members_icon),
     modifier = Modifier.size(64.dp),
     tint = AppTheme.colorScheme.textPrimary
 )
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListViewModel.kt (1)

44-61: Add retry mechanism for space fetch.

The implementation looks good, but consider adding retry logic for better reliability.

 private fun getCurrentSpace() = viewModelScope.launch(appDispatcher.IO) {
+    var retryCount = 0
+    val maxRetries = 3
+    
+    while (retryCount < maxRetries) {
         try {
             _state.emit(_state.value.copy(loadingSpace = true))
             val space = spaceRepository.getCurrentSpaceInfo()
             val members = space?.members ?: emptyList()

             _state.emit(
                 _state.value.copy(
                     currentSpace = space,
                     loadingSpace = false,
                     hasMembers = members.size > 1
                 )
             )
+            return@launch
         } catch (e: Exception) {
             Timber.e(e, "Failed to fetch current space")
+            retryCount++
+            if (retryCount == maxRetries) {
                 _state.emit(_state.value.copy(error = e.message, loadingSpace = false))
+            } else {
+                delay(1000L * retryCount)
+            }
         }
     }
 }
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListScreen.kt (2)

154-163: Make LoadingContent more reusable.

Consider making the loading content more flexible for reuse across the app.

+/**
+ * A reusable loading indicator that can be customized with size and colors
+ *
+ * @param modifier Modifier for the container
+ * @param size Size of the progress indicator
+ * @param color Color of the progress indicator
+ */
 @Composable
-fun LoadingContent(modifier: Modifier) {
+fun LoadingContent(
+    modifier: Modifier = Modifier,
+    size: Dp = 48.dp,
+    color: Color = AppTheme.colorScheme.primary
+) {
     Column(
         horizontalAlignment = Alignment.CenterHorizontally,
         verticalArrangement = Arrangement.Center,
         modifier = modifier.fillMaxSize()
     ) {
-        AppProgressIndicator()
+        AppProgressIndicator(
+            modifier = Modifier.size(size),
+            color = color
+        )
     }
 }

Line range hint 89-99: Extract visibility condition to a function.

The floating action button visibility logic could be clearer if extracted to a function.

+private fun shouldShowAddPlaceButton(
+    placesLoading: Boolean,
+    connectivityStatus: ConnectivityObserver.Status,
+    hasMembers: Boolean
+): Boolean = !placesLoading && 
+    connectivityStatus == ConnectivityObserver.Status.Available && 
+    hasMembers

-if (!state.placesLoading && state.connectivityStatus == ConnectivityObserver.Status.Available && state.hasMembers) {
+if (shouldShowAddPlaceButton(
+    state.placesLoading,
+    state.connectivityStatus,
+    state.hasMembers
+)) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d1088e1 and 0c6a714.

📒 Files selected for processing (5)
  • app/src/main/java/com/canopas/yourspace/ui/component/NoMemberEmptyContent.kt (1 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListScreen.kt (5 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListViewModel.kt (3 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/messages/thread/ThreadsScreen.kt (2 hunks)
  • app/src/main/res/values/strings.xml (1 hunks)
🔇 Additional comments (1)
app/src/main/java/com/canopas/yourspace/ui/flow/messages/thread/ThreadsScreen.kt (1)

163-167: LGTM! Consistent usage of NoMemberEmptyContent

The component is appropriately used to display a message when there are no members, with proper title and subtitle parameters.

@cp-sneh-s cp-sneh-s requested a review from cp-megh-l December 12, 2024 10:59
Copy link

@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: 3

🧹 Outside diff range and nitpick comments (5)
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameViewModel.kt (1)

Line range hint 76-90: Implement single-member group validation

Per the PR objectives, places should not be added when a group has only one member. However, this validation is missing in the current implementation.

Here's a suggested implementation:

         val memberIds = spaceRepository.getMemberBySpaceId(currentSpaceId)?.map { it.user_id }
             ?: emptyList()
+        if (memberIds.size <= 1) {
+            _state.value = _state.value.copy(
+                error = Exception("Cannot add places in groups with only one member.")
+            )
+            return@launch
+        }
         apiPlaceService.addPlace(
             spaceId = currentSpaceId,
             name = state.value.placeName,
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameScreen.kt (2)

Line range hint 143-146: Add member count validation before enabling place creation

According to the PR objectives, places should not be added when a group has only one member. However, the "Add Place" button is currently enabled based only on the place name being non-empty.

Consider updating the button's enabled state to include the member count check:

         PrimaryButton(
             label = stringResource(R.string.common_btn_add_place),
             modifier = Modifier.align(Alignment.CenterHorizontally),
             onClick = {
                 onNext()
                 keyboardController?.hide()
             },
-            enabled = placeName.trim().isNotEmpty(),
+            enabled = placeName.trim().isNotEmpty() && state.memberCount > 1,
             showLoader = showLoader
         )

This will require:

  1. Adding memberCount to the screen's state
  2. Updating the ViewModel to track member count

Line range hint 119-121: Add user guidance about member requirements

Users should be informed about the requirement of having multiple members before adding a place. Consider adding explanatory text near the suggestions.

Add informative text below the existing caption:

         Text(
             text = stringResource(R.string.home_create_space_suggestions),
             style = AppTheme.appTypography.caption.copy(color = AppTheme.colorScheme.textDisabled),
             modifier = Modifier
                 .fillMaxWidth()
                 .padding(horizontal = 16.dp)
         )
+        Text(
+            text = stringResource(R.string.place_creation_member_requirement),
+            style = AppTheme.appTypography.caption.copy(color = AppTheme.colorScheme.textDisabled),
+            modifier = Modifier
+                .fillMaxWidth()
+                .padding(horizontal = 16.dp, top = 4.dp)
+        )

This will require adding a new string resource:

<string name="place_creation_member_requirement">Note: Places can only be added when the group has more than one member</string>
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapScreen.kt (2)

150-154: Consider using Kotlin's safe call operator

The error handling implementation can be more concise using Kotlin's safe call operator.

-if (state.error != null) {
-    AppBanner(msg = state.error!!.message!!) {
-        viewModel.resetErrorState()
-    }
-}
+state.error?.message?.let { errorMessage ->
+    AppBanner(msg = errorMessage) {
+        viewModel.resetErrorState()
+    }
+}

Based on the code analysis, I can now provide the final response:

Member validation check is missing in place addition flow

The place addition implementation in both LocateOnMapViewModel and ChoosePlaceNameViewModel lacks the required validation to prevent place addition in single-member groups. While PlacesListViewModel tracks member count with hasMembers state, this validation isn't enforced in the actual place addition flow.

Required changes:

  • Add member count validation in LocateOnMapViewModel.onNextClick() before proceeding with place addition
  • Implement similar validation in ChoosePlaceNameViewModel.addPlace()
  • Consider moving the validation logic to a shared location since it's used in multiple places
🔗 Analysis chain

Line range hint 80-85: Verify implementation of group member check requirement

Let's verify if the codebase has any other implementations of the group member check, as the current changes don't fully address the PR's main objective.


Let me gather more specific information about place addition validation.


Let me check the place addition implementation in ChoosePlaceNameViewModel since that's where the actual place addition logic resides.


Let me check the LocateOnMapViewModel since it's the entry point for place addition.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any other implementations of member count validation
rg -l "memberIds?.size|members?.size|count.*member|member.*count" 

# Search for other place addition implementations that might need the same validation
ast-grep --pattern 'fun $name($$$) {
  $$$
  addPlace($$$)
  $$$
}'

Length of output: 568


Script:

#!/bin/bash
# Check PlacesListViewModel for member validation logic
cat "app/src/main/java/com/canopas/yourspace/ui/flow/geofence/places/PlacesListViewModel.kt"

# Search for place addition related functions in the codebase
rg -g "*.kt" "fun.*addPlace|fun.*savePlace" -A 5

# Look for group member validation patterns
rg -g "*.kt" "if.*member.*size|when.*member.*size" -A 3

Length of output: 12992


Script:

#!/bin/bash
# Check ChoosePlaceNameViewModel for the complete implementation
cat "app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameViewModel.kt"

# Also check if there are any member validation checks in this path
rg -g "*/geofence/add/**/*.kt" "member.*size|hasMembers"

Length of output: 5317


Script:

#!/bin/bash
# Check LocateOnMapViewModel implementation
cat "app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapViewModel.kt"

# Check if there are any member validation checks in this specific file
rg -g "LocateOnMapViewModel.kt" "member.*size|hasMembers|members"

Length of output: 5832

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0c6a714 and 66773d9.

📒 Files selected for processing (4)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapScreen.kt (2 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapViewModel.kt (2 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameScreen.kt (1 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/placename/ChoosePlaceNameViewModel.kt (1 hunks)
🔇 Additional comments (2)
app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapViewModel.kt (1)

142-144: LGTM: Error state reset implementation

The error state reset implementation follows proper state management practices.

app/src/main/java/com/canopas/yourspace/ui/flow/geofence/add/locate/LocateOnMapScreen.kt (1)

39-39: LGTM: AppBanner import

The import is correctly added for the new error handling UI component.

kaushiksaliya
kaushiksaliya previously approved these changes Dec 16, 2024
…e-member-groups

# Conflicts:
#	app/src/main/res/values/strings.xml
@cp-sneh-s cp-sneh-s merged commit e5b3fd9 into main Dec 16, 2024
2 checks passed
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.

2 participants