{"id":26260463,"url":"https://github.com/kbanashek/rncardlist","last_synced_at":"2025-03-13T23:14:59.717Z","repository":{"id":282083954,"uuid":"947375942","full_name":"kbanashek/RNCardList","owner":"kbanashek","description":"React Native baseball card app built with Expo and React Relay","archived":false,"fork":false,"pushed_at":"2025-03-12T18:24:28.000Z","size":4589,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-12T18:34:30.846Z","etag":null,"topics":["expo","react-native","react-relay","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kbanashek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-12T15:35:38.000Z","updated_at":"2025-03-12T18:24:32.000Z","dependencies_parsed_at":"2025-03-12T18:45:16.161Z","dependency_job_id":null,"html_url":"https://github.com/kbanashek/RNCardList","commit_stats":null,"previous_names":["kbanashek/rncardlist"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbanashek%2FRNCardList","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbanashek%2FRNCardList/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbanashek%2FRNCardList/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbanashek%2FRNCardList/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kbanashek","download_url":"https://codeload.github.com/kbanashek/RNCardList/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243495482,"owners_count":20299923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expo","react-native","react-relay","typescript"],"created_at":"2025-03-13T23:14:59.048Z","updated_at":"2025-03-13T23:14:59.712Z","avatar_url":"https://github.com/kbanashek.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RNCardList\n\nA React Native app built with Expo and React Relay (against a mock service) for managing a collection of baseball cards. Users can view cards, see detailed information, and like their favorite cards.\n\n## List Screen:\n\n![alt text](image.png)\n\n## Detail Screen:\n\n![alt text](image-1.png)\n\n## Screenshots\n\n### Optimistic UI Updates\n\nThe like button demonstrates immediate feedback:\n\n1. Heart icon changes instantly on tap\n2. Loading indicator shows during request\n3. Reverts on error (e.g., when offline)\n\n## Features\n\n- View list of baseball cards\n- Card details view\n- Like/unlike cards with instant feedback\n- Optimistic UI updates\n  - Immediate UI response without waiting for server\n  - Smooth user experience for like/unlike actions\n  - Graceful error handling and state reversion\n- Offline capabilities\n- Image caching\n\n## Tech Stack\n\n- [React Native](https://reactnative.dev) - A framework for building native apps using React\n- [Expo/EAS](https://expo.dev) - Platform and build service for React Native apps\n- [React Relay](https://relay.dev) - Production-ready GraphQL client for React\n- [TypeScript](https://www.typescriptlang.org) - JavaScript with syntax for types\n- [React Navigation](https://reactnavigation.org) - Routing and navigation for React Native apps\n- [React Native Paper](https://callstack.github.io/react-native-paper) - Material Design components for React Native\n\n## Prerequisites\n\n- [Node.js](https://nodejs.org) v18 or higher - JavaScript runtime environment\n- [npm](https://www.npmjs.com) or [yarn](https://yarnpkg.com) - Package managers for Node.js\n- [Expo CLI](https://docs.expo.dev/get-started/installation) - Command line tool for Expo development\n- iOS Simulator (for iOS development)\n  - macOS - Required for iOS development\n  - Xcode (latest version) - iOS development environment\n- Android Studio (for Android development)\n  - Android SDK - Software development kit for Android\n  - Android Emulator - Virtual device for testing Android apps\n\n## Getting Started\n\n1. Clone the repository:\n\n   ```bash\n   git clone https://github.com/kbanashek/RNCardList.git\n   cd RNCardList\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n3. Start the development server:\n\n   ```bash\n   npm start\n   ```\n\n4. Open the app:\n\n   - For iOS: Press `i` in the terminal or run `npm run ios`\n   - For Android: Press `a` in the terminal or run `npm run android`\n\n5. Unit Tests\n\n   ```bash\n   npm run test\n   ```\n\n## Development\n\nThe app uses a mock GraphQL service for data. All network requests are handled through Relay, with offline support and optimistic updates.\n\n### Optimistic Updates\n\nThe app implements optimistic UI updates to provide instant feedback for user actions:\n\n```typescript\n// Example from useToggleCardLike hook\ncommit({\n  variables: { input: { cardId } },\n  // Update UI immediately\n  optimisticResponse: {\n    toggleCardLike: {\n      card: {\n        id: cardId,\n        isLiked: true,\n      },\n    },\n  },\n  // Revert UI if server request fails\n  onError: (error) =\u003e {\n    // Handle error state\n  },\n});\n```\n\nThis pattern:\n\n1. Updates UI immediately when user takes action\n2. Sends request to server in background\n3. Handles errors by reverting UI if needed\n\n#### Implementation Details\n\nThe optimistic updates are implemented using React Relay's mutation API:\n\n1. **State Management**:\n\n   ```typescript\n   const [state, setState] = useState\u003cMutationState\u003e({\n     loadingCardIds: new Set(), // Track loading state per card\n     error: null, // Handle errors globally\n   });\n   ```\n\n2. **Loading States**:\n\n   - Each card tracks its own loading state\n   - UI can show loading indicators while request is pending\n   - Prevents duplicate requests for the same card\n\n3. **Error Handling**:\n   - Global error state for user feedback\n   - Automatic UI reversion on failure\n   - Proper cleanup of loading states\n\n#### Component Integration\n\nThe `LikeButton` component integrates with the optimistic update system:\n\n```typescript\nconst LikeButton = ({ cardId, isLiked }) =\u003e {\n  const { toggleLike, isLoading } = useToggleCardLike();\n\n  return (\n    \u003cIconButton\n      icon={isLiked ? \"heart\" : \"heart-outline\"}\n      onPress={() =\u003e toggleLike(cardId)}\n      disabled={isLoading}\n      // Show loading state while request is pending\n      loading={isLoading}\n    /\u003e\n  );\n};\n```\n\n#### Optimistic Updates\n\n1. Enable network debugging in Chrome DevTools\n2. Like a card and verify:\n   - UI updates immediately\n   - Network request is sent in background\n   - UI remains updated after request completes\n3. Test error handling:\n   - Enable airplane mode\n   - Like a card\n   - Verify UI reverts when offline\n\n#### Offline Testing\n\n1. Load the app with network connection\n2. Enable airplane mode\n3. Verify:\n   - Cards are still visible\n   - Images load from cache\n   - Like/unlike actions show proper error states\n   - Network status banner appears\n4. Re-enable network:\n   - Banner should disappear\n   - Any pending actions should resolve\n\n### Architecture\n\n#### Offline Support\n\nThe app uses several strategies to provide a seamless offline experience:\n\n1. **Data Persistence**:\n\n   - Relay stores query data in memory cache\n   - Images are pre-cached on first load\n   - Network state is monitored via NetInfo\n\n2. **UI Feedback**:\n\n   - Network status banner shows offline state\n   - Loading states indicate pending actions\n   - Error states show when actions fail\n   - Cached data is used when offline\n\n3. **Error Recovery**:\n   - Automatic retry when network returns\n   - Clear error states on reconnection\n   - Preserve user actions when possible\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbanashek%2Frncardlist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkbanashek%2Frncardlist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbanashek%2Frncardlist/lists"}