From f504d9a0dc462a8db9718cfa289650702b59fb59 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 16 Apr 2026 20:17:55 +0000
Subject: [PATCH] [jules] ux: Complete skeleton loading for HomeScreen groups
Replaced the generic `ActivityIndicator` on the Home screen with a `GroupListSkeleton` utilizing a newly created `Skeleton` primitive.
The primitive uses React Native's `Animated` with `useNativeDriver: true` for efficient pulsing animations.
Updated tracking files `.Jules/todo.md` and `.Jules/changelog.md`.
Co-authored-by: Devasy23 <110348311+Devasy23@users.noreply.github.com>
---
.Jules/changelog.md | 10 ++++
.Jules/todo.md | 4 +-
.../components/skeletons/GroupListSkeleton.js | 41 ++++++++++++++
mobile/components/ui/Skeleton.js | 54 +++++++++++++++++++
mobile/screens/HomeScreen.js | 5 +-
5 files changed, 110 insertions(+), 4 deletions(-)
create mode 100644 mobile/components/skeletons/GroupListSkeleton.js
create mode 100644 mobile/components/ui/Skeleton.js
diff --git a/.Jules/changelog.md b/.Jules/changelog.md
index 11fc864..745f69c 100644
--- a/.Jules/changelog.md
+++ b/.Jules/changelog.md
@@ -1,5 +1,15 @@
# Splitwiser UI/UX Changelog
+
+## [Unreleased]
+
+### Added
+- Created reusable `Skeleton` UI primitive in `mobile/components/ui/Skeleton.js` with pulsing animation.
+- Created `GroupListSkeleton` in `mobile/components/skeletons/GroupListSkeleton.js` using the new `Skeleton` component.
+
+### Changed
+- Replaced `ActivityIndicator` with `GroupListSkeleton` in `mobile/screens/HomeScreen.js` for a better loading experience.
+
> All UI/UX changes made by Jules automated enhancement agent.
---
diff --git a/.Jules/todo.md b/.Jules/todo.md
index ebb0c7a..3a53806 100644
--- a/.Jules/todo.md
+++ b/.Jules/todo.md
@@ -57,7 +57,9 @@
- Impact: Native feel, users can easily refresh data
- Size: ~150 lines
-- [ ] **[ux]** Complete skeleton loading for HomeScreen groups
+- [x] **[ux]** Complete skeleton loading for HomeScreen groups
+ - Completed: 2026-04-16
+ - Files modified: `mobile/screens/HomeScreen.js`, `mobile/components/ui/Skeleton.js`, `mobile/components/skeletons/GroupListSkeleton.js`
- File: `mobile/screens/HomeScreen.js`
- Context: Replace ActivityIndicator with skeleton group cards
- Impact: Better loading experience, less jarring
diff --git a/mobile/components/skeletons/GroupListSkeleton.js b/mobile/components/skeletons/GroupListSkeleton.js
new file mode 100644
index 0000000..1ea57c9
--- /dev/null
+++ b/mobile/components/skeletons/GroupListSkeleton.js
@@ -0,0 +1,41 @@
+import React from 'react';
+import { StyleSheet, View } from 'react-native';
+import { Card } from 'react-native-paper';
+import Skeleton from '../ui/Skeleton';
+
+const GroupListSkeletonItem = () => (
+
+ }
+ left={(props) => (
+
+
+
+ )}
+ />
+
+
+
+
+);
+
+const GroupListSkeleton = () => {
+ return (
+
+ {[1, 2, 3, 4, 5].map((key) => (
+
+ ))}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ padding: 16,
+ },
+ card: {
+ marginBottom: 16,
+ },
+});
+
+export default GroupListSkeleton;
diff --git a/mobile/components/ui/Skeleton.js b/mobile/components/ui/Skeleton.js
new file mode 100644
index 0000000..6f78271
--- /dev/null
+++ b/mobile/components/ui/Skeleton.js
@@ -0,0 +1,54 @@
+import React, { useEffect, useRef } from 'react';
+import { Animated, StyleSheet } from 'react-native';
+import { useTheme } from 'react-native-paper';
+
+const Skeleton = ({ width, height, borderRadius = 4, style }) => {
+ const theme = useTheme();
+ const opacity = useRef(new Animated.Value(0.3)).current;
+
+ useEffect(() => {
+ const loop = Animated.loop(
+ Animated.sequence([
+ Animated.timing(opacity, {
+ toValue: 0.7,
+ duration: 800,
+ useNativeDriver: true,
+ }),
+ Animated.timing(opacity, {
+ toValue: 0.3,
+ duration: 800,
+ useNativeDriver: true,
+ }),
+ ])
+ );
+ loop.start();
+
+ return () => {
+ loop.stop();
+ };
+ }, [opacity]);
+
+ return (
+
+ );
+};
+
+const styles = StyleSheet.create({
+ skeleton: {
+ overflow: 'hidden',
+ },
+});
+
+export default Skeleton;
diff --git a/mobile/screens/HomeScreen.js b/mobile/screens/HomeScreen.js
index d2f3c38..e60806e 100644
--- a/mobile/screens/HomeScreen.js
+++ b/mobile/screens/HomeScreen.js
@@ -17,6 +17,7 @@ import * as Haptics from "expo-haptics";
import { createGroup, getGroups, getOptimizedSettlements } from "../api/groups";
import { AuthContext } from "../context/AuthContext";
import { formatCurrency, getCurrencySymbol } from "../utils/currency";
+import GroupListSkeleton from "../components/skeletons/GroupListSkeleton";
const HomeScreen = ({ navigation }) => {
const { token, logout, user } = useContext(AuthContext);
@@ -257,9 +258,7 @@ const HomeScreen = ({ navigation }) => {
{isLoading ? (
-
-
-
+
) : (