Skip to content

[jules] enhance: Add skeleton loading for mobile home screen#290

Open
Devasy wants to merge 2 commits intomainfrom
jules/ux-mobile-skeleton-loading-2058336560218393763
Open

[jules] enhance: Add skeleton loading for mobile home screen#290
Devasy wants to merge 2 commits intomainfrom
jules/ux-mobile-skeleton-loading-2058336560218393763

Conversation

@Devasy
Copy link
Owner

@Devasy Devasy commented Feb 22, 2026

Implemented a complete skeleton loading system for the mobile Home screen.

  • Created reusable Skeleton component (mobile/components/ui/Skeleton.js) using Animated for pulsing effect.
  • Created GroupListSkeleton component (mobile/components/skeletons/GroupListSkeleton.js) to mimic the group list layout.
  • Updated mobile/screens/HomeScreen.js to replace the generic ActivityIndicator with the new skeleton loader.
  • Updated todo.md, changelog.md, and knowledge.md to reflect the changes.

PR created automatically by Jules for task 2058336560218393763 started by @Devasy23

Summary by CodeRabbit

  • New Features

    • Replaced the loading spinner on the Home screen groups list with animated, pulsing skeleton placeholders (multiple card-style skeletons) for a smoother loading experience.
    • Introduced a reusable skeleton component to standardize loading visuals.
  • Documentation

    • Added guidance for the skeleton loading pattern for consistent web and mobile implementation.

Co-authored-by: Devasy23 <110348311+Devasy23@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@Devasy Devasy requested a review from vrajpatelll as a code owner February 22, 2026 19:51
@netlify
Copy link

netlify bot commented Feb 22, 2026

Deploy Preview for split-but-wiser canceled.

Name Link
🔨 Latest commit 944ba63
🔍 Latest deploy log https://app.netlify.com/projects/split-but-wiser/deploys/699dc43f683bb00008db23f9

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 22, 2026

Walkthrough

Adds a reusable mobile Skeleton component and a GroupListSkeleton placeholder, replaces the HomeScreen ActivityIndicator with the GroupListSkeleton, and updates related documentation and task metadata.

Changes

Cohort / File(s) Summary
Skeleton Components
mobile/components/ui/Skeleton.js, mobile/components/skeletons/GroupListSkeleton.js
Added a reusable Skeleton (Animated pulsing opacity, theme-aware) and GroupListSkeleton (renders four skeleton group cards mirroring group card layout).
HomeScreen Integration
mobile/screens/HomeScreen.js
Replaced spinner-based loading UI with GroupListSkeleton; removed loaderContainer styles and adjusted loading render path.
Docs & Task Metadata
.Jules/changelog.md, .Jules/knowledge.md, .Jules/todo.md
Documented the skeleton loading pattern for Web and Mobile, added implementation notes, and marked the skeleton task as completed with updated metadata.

Suggested reviewers

  • vrajpatelll
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main change: adding skeleton loading for the mobile home screen, which is the primary focus of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.Jules/knowledge.md:
- Around line 313-321: Add a blank line immediately before the fenced code block
that begins with ```jsx so the example block is separated from the preceding
text; update the section containing the Card/Card.Title/Skeleton example to
insert one empty line before the opening ```jsx fence to satisfy markdownlint
MD031.

In `@mobile/components/skeletons/GroupListSkeleton.js`:
- Line 9: The View in GroupListSkeleton that sets accessibilityLabel="Loading
groups" must also include accessible={true} so screen readers reliably announce
the container as a single element; update the View in the GroupListSkeleton
component to add accessible={true} alongside the existing accessibilityLabel
prop so assistive tech skips its children and announces "Loading groups".
- Around line 14-16: The render-prop parameter named props in the left prop of
Card.Title is unused and should be prefixed to avoid linter warnings; rename
props to _props (or _) in the left={(props) => (...) } arrow function so it
becomes left={(_props) => (<Skeleton width={40} height={40} borderRadius={20}
/>)} to signal intentional non-use while keeping the Skeleton usage unchanged in
GroupListSkeleton.js.
- Around line 12-17: The Card.Title usage in GroupListSkeleton.js is causing a
runtime crash because title expects text-based content but we're passing the
View-based Skeleton; replace the Card.Title block (the Card.Title call that
currently has title={<Skeleton .../>} and left={(props) => <Skeleton .../>})
with a plain View-based header layout: create a container View with
flexDirection: 'row' and alignItems: 'center', render the left avatar Skeleton
(width 40 height 40 borderRadius 20) as the first child, and render a right-side
column View containing the title Skeleton (width 150 height 20) and optional
subtitle Skeleton (e.g. width 100 height 14) stacked vertically; this keeps all
Skeletons as Views and avoids nesting Views inside Text while visually matching
the Card.Title header.

In `@mobile/components/ui/Skeleton.js`:
- Around line 30-41: The Animated.View used in the Skeleton component should be
hidden from screen readers: update the Animated.View (in
mobile/components/ui/Skeleton.js) to include accessible={false} and
importantForAccessibility="no-hide-descendants" so assistive tech ignores the
placeholder (importantForAccessibility applies on Android for full suppression).
- Line 35: In the Skeleton component replace the fallback for borderRadius so it
doesn't override explicit zero values: update the style assignment that
currently uses "borderRadius: borderRadius || 4" to use nullish coalescing
(borderRadius ?? 4) so only null/undefined fall back to 4; locate this in the
Skeleton component's render/style object where borderRadius is referenced.

Comment on lines +313 to +321
**Example:**
```jsx
<Card>
<Card.Title
title={<Skeleton width={150} height={20} />}
left={(props) => <Skeleton width={40} height={40} borderRadius={20} />}
/>
</Card>
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a blank line before the fenced code block to fix the MD031 lint warning.

markdownlint requires blank lines surrounding fenced code blocks.

📝 Proposed fix
 **Example:**
+
 ```jsx
 <Card>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Example:**
```jsx
<Card>
<Card.Title
title={<Skeleton width={150} height={20} />}
left={(props) => <Skeleton width={40} height={40} borderRadius={20} />}
/>
</Card>
```
**Example:**
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 314-314: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.Jules/knowledge.md around lines 313 - 321, Add a blank line immediately
before the fenced code block that begins with ```jsx so the example block is
separated from the preceding text; update the section containing the
Card/Card.Title/Skeleton example to insert one empty line before the opening
```jsx fence to satisfy markdownlint MD031.

const GroupListSkeleton = () => {
// Render 4 skeleton items to fill the screen
return (
<View style={{ padding: 16 }} accessibilityLabel="Loading groups">
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

accessibilityLabel on a plain View requires accessible={true} to be reliably announced.

Without accessible={true}, React Native may not treat this View as a focusable accessibility element and the label may be ignored on both iOS and Android. Add accessible={true} so the container is announced as a single element and screen readers skip traversal into children.

♿ Proposed fix
-      <View style={{ padding: 16 }} accessibilityLabel="Loading groups">
+      <View style={{ padding: 16 }} accessible={true} accessibilityLabel="Loading groups">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<View style={{ padding: 16 }} accessibilityLabel="Loading groups">
<View style={{ padding: 16 }} accessible={true} accessibilityLabel="Loading groups">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/skeletons/GroupListSkeleton.js` at line 9, The View in
GroupListSkeleton that sets accessibilityLabel="Loading groups" must also
include accessible={true} so screen readers reliably announce the container as a
single element; update the View in the GroupListSkeleton component to add
accessible={true} alongside the existing accessibilityLabel prop so assistive
tech skips its children and announces "Loading groups".

Comment on lines 14 to 16
left={(props) => (
<Skeleton width={40} height={40} borderRadius={20} />
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Prefix the unused props parameter with _ to signal intentional non-use.

The left render prop receives { size: number } from Card.Title, but Skeleton uses fixed dimensions. Renaming to _props (or just _) prevents lint warnings and communicates intent clearly.

♻️ Proposed fix
-            left={(props) => (
+            left={(_props) => (
               <Skeleton width={40} height={40} borderRadius={20} />
             )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
left={(props) => (
<Skeleton width={40} height={40} borderRadius={20} />
)}
left={(_props) => (
<Skeleton width={40} height={40} borderRadius={20} />
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/skeletons/GroupListSkeleton.js` around lines 14 - 16, The
render-prop parameter named props in the left prop of Card.Title is unused and
should be prefixed to avoid linter warnings; rename props to _props (or _) in
the left={(props) => (...) } arrow function so it becomes left={(_props) =>
(<Skeleton width={40} height={40} borderRadius={20} />)} to signal intentional
non-use while keeping the Skeleton usage unchanged in GroupListSkeleton.js.

Comment on lines +30 to +41
<Animated.View
style={[
{
width,
height,
borderRadius: borderRadius || 4,
backgroundColor: theme.colors.surfaceVariant,
opacity,
},
style,
]}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hide the skeleton placeholder from screen readers.

Without accessible={false}, screen readers may traverse into this animated view and announce nothing useful (or confuse users). Add accessible={false} to suppress it, and importantForAccessibility="no-hide-descendants" on Android for full suppression.

♿ Proposed fix
     <Animated.View
+      accessible={false}
+      importantForAccessibility="no-hide-descendants"
       style={[
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/ui/Skeleton.js` around lines 30 - 41, The Animated.View
used in the Skeleton component should be hidden from screen readers: update the
Animated.View (in mobile/components/ui/Skeleton.js) to include
accessible={false} and importantForAccessibility="no-hide-descendants" so
assistive tech ignores the placeholder (importantForAccessibility applies on
Android for full suppression).

{
width,
height,
borderRadius: borderRadius || 4,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use nullish coalescing ?? instead of || for the borderRadius default.

borderRadius || 4 evaluates to 4 when borderRadius={0} is explicitly passed (e.g., sharp corners), silently ignoring the caller's intent. Use ?? to only fall back when the value is null/undefined.

🐛 Proposed fix
-          borderRadius: borderRadius || 4,
+          borderRadius: borderRadius ?? 4,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
borderRadius: borderRadius || 4,
borderRadius: borderRadius ?? 4,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/ui/Skeleton.js` at line 35, In the Skeleton component
replace the fallback for borderRadius so it doesn't override explicit zero
values: update the style assignment that currently uses "borderRadius:
borderRadius || 4" to use nullish coalescing (borderRadius ?? 4) so only
null/undefined fall back to 4; locate this in the Skeleton component's
render/style object where borderRadius is referenced.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@9404621). Learn more about missing BASE report.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #290   +/-   ##
=======================================
  Coverage        ?   63.55%           
=======================================
  Files           ?       21           
  Lines           ?     2456           
  Branches        ?      254           
=======================================
  Hits            ?     1561           
  Misses          ?      831           
  Partials        ?       64           
Components Coverage Δ
Authentication System 71.35% <ø> (?)
Expense Management 70.15% <ø> (?)
Group Management 73.78% <ø> (?)
User Management 97.16% <ø> (?)
Backend Core 70.78% <ø> (?)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

♻️ Duplicate comments (1)
mobile/components/skeletons/GroupListSkeleton.js (1)

9-9: Add accessible={true} to make the label reliably announced.

accessibilityLabel on a plain View may be ignored unless the view is marked accessible. This was flagged previously and still applies.

♿ Proposed fix
-    <View style={{ padding: 16 }} accessibilityLabel="Loading groups">
+    <View style={{ padding: 16 }} accessible={true} accessibilityLabel="Loading groups">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/components/skeletons/GroupListSkeleton.js` at line 9, The View in the
GroupListSkeleton component uses accessibilityLabel but isn't marked accessible,
so screen readers may ignore it; update the root View in GroupListSkeleton to
include accessible={true} (e.g., the View that currently has style={{ padding:
16 }} and accessibilityLabel="Loading groups") so the label is reliably
announced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@mobile/components/skeletons/GroupListSkeleton.js`:
- Line 9: The View in the GroupListSkeleton component uses accessibilityLabel
but isn't marked accessible, so screen readers may ignore it; update the root
View in GroupListSkeleton to include accessible={true} (e.g., the View that
currently has style={{ padding: 16 }} and accessibilityLabel="Loading groups")
so the label is reliably announced.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4265fae and 944ba63.

📒 Files selected for processing (1)
  • mobile/components/skeletons/GroupListSkeleton.js

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