A Flutter app for exploring GitHub users, their repositories, and related data via the GitHub REST API.
The project showcases clean architecture, API integration with Dio, state management using flutter_bloc, and golden/widget testing for reliability.
-
Search GitHub users by username via /search/users endpoint.
-
Paginated results with scroll-to-load-more support.
-
Debounced search input to reduce API calls.
-
View individual user details (/users/{login}).
-
Displays profile information (avatar, bio, stats, created_at).
-
List repositories for a user (/users/{login}/repos).
-
Repository widget displays:
- Name
- Description
- Language
- Stars, forks, watchers
- Creation date
-
Mark/unmark users as favorites.
-
Stored locally with SQLite (sqflite) using a Favorite Users Repository.
-
State managed via a FavoritesCubit.
-
Date Formatting
-
DateTimeUtils.formatDate() for normalizing ISO 8601 timestamps into yyyy-MM-dd.
- determineEndpoint(RequestOptions) to map Dio request paths into semantic enums (Endpoints.user, Endpoints.userRepos, etc.) for consistent handling.
- String.padStart (later replaced/fixed with Dart’s padLeft for zero-padding consistency).
-
determineEndpoint → verifies correct endpoint resolution with normalized/messy paths.
-
DateTimeUtils → ensures valid ISO strings format correctly, invalid strings return unchanged, and padding works.
-
FavoritesCubit → validates state transitions when toggling favorites.
-
Database migrations tested for applying/upgrading schemas.
-
GoldenToolkit used for UI snapshots (CustomAppBar, search result tiles, etc.).
-
Helped catch regressions in design during refactors.
- Verified snackbars and state flows (e.g., “Added to favorites”).
-
Framework: Flutter (3.x with FVM).
-
State Management: flutter_bloc / Cubits.
-
Networking: Dio (with error handling & request interception).
-
Database: sqflite (with DatabaseHelper and migration runner).
-
Testing: flutter_test, mockito, golden_toolkit.
-
Normalizing URLs like ///users//dario///repos/// was tricky.
-
Solved with
_normalizeand_segshelpers.
-
Extension padStart clashed with Dart’s own padLeft.
-
Produced bugs like 2025-1-3 instead of 2025-01-03.
-
Fixed by dropping the extension in favor of native padLeft.
-
Inserting favorites triggered FOREIGN KEY constraint failed.
-
Root cause: mismatched schema vs. insert queries.
-
Fixed by ensuring favorite_github_users schema included proper relations.
-
FavoriteButton repeatedly triggered snackbars.
-
Needed BlocSelector / BlocConsumer to refine rebuild behavior.
-
Testing RepositoryProvider Contexts
- Fixed by wrapping widgets in RepositoryProvider setup in tests.
-
API unauthenticated requests hit 60 req/hr.
-
Planned solution: add OAuth token support in Dio interceptors.
-
Stronger Type Safety
-
Replace raw String endpoints with enums or sealed classes across the networking layer.
-
Error Boundaries in UI
-
Build dedicated error widgets instead of snackbars-only flows.
-
Better Offline Support
-
Cache search results and user details in SQLite/Hive for offline browsing.
-
CI/CD GitHub Actions pipeline to:
- Run widget tests with golden diffs.
- Auto-update golden images with approval step.
- Push code coverage to Codecov.
-
Use Retrofit/Chopper for APIs (potentially)
-
Handwriting models & Dio calls was verbose.
-
A Retrofit-style generator would cut boilerplate.
-
Refine DB Layer
-
Wrap raw sqflite with a repo/DAO pattern for cleaner testing.
- Add GitHub OAuth login to raise rate limits & enable private repo support