This is an Android app that uses the Github GraphQl API to allow searching for repositories and their issues. The app implements pagination to efficiently retrieve data in manageable chunks from the Github API. This approach optimizes network usage and enhances performance. Additionally, the app employs local caching, storing fetched data in a local database. This feature enables offline functionality, allowing users to access previously loaded content even without an active internet connection.
Idle Screen | Repositories search result | No repository found |
---|---|---|
Paged Issues List | Issue List with query | Valid Issue Labels |
---|---|---|
Gitissuesdemo.mp4
Pre-requisites
- A.S Koala or newer
- JDK 17
- A Fine Grained Access token from Github to download schema from Github GraphQl API.
- Sentry DSN and Auth Token from Sentry
- GithubClient and Secret key to provide Oauth2 Login from Github Developers Page
- Once received place it in the local.properties file as follows:
GITHUBCLIENTKEY = your_key
GITHUBSECRET = your_secret
SENTRYDSN = SENTRY_DSN
SENTRYAUTHTOKEN = sentry_auth_token
GITDEVTOKEN = fine_grained_token
To Inject the Key when using CI/CD with github actions , add the key to your projects secrets and extract in to your build workflow:
- name: Get local.properties from secrets
run: echo "${{secrets.ProjectSecrets }}" > $GITHUB_WORKSPACE/local.properties
This project uses a modularized approach using MVVM with Clean architecture which has the following advantages
- Loose coupling between the code - The code can easily be modified without affecting any or a large part of the app's codebase thus easier to scale the application later on.
- Easier to test code.
- Separation of Concern - Different modules have specific responsibilities making it easier for modification and maintenance.
This project uses Paging 3 to efficiently load and display paginated data from GitHub. The RemoteMediator is integrated to handle both local database caching and network requests.
- The app fetches data from GitHub and stores it in a local Room database.
- When the user reaches the end of the currently displayed data, Paging 3 automatically triggers the RemoteMediator to load more data from GitHub.
- The system handles refreshing data and loading additional pages seamlessly, ensuring smooth scrolling and minimal load times for the user. This approach helps maintain a responsive UI while managing data efficiently, even for large datasets.
core
data
- aggregates the data from the network and local database
network
- handles getting data from any server/remote source
database
- handles getting cached device data
domain
- defines the core business logic for reuse
app
- handles UI entry point of the app and navigation logic.
feature
repository
- handles the functionality for searching repositories on github.
issues
- handles the functionality for searching and filtering a repository's issues on github.
testing
- Encompasses the core testing functionality of the project and provides modules for use in End to End tests.
%%{
init: {
'theme': 'base',
'themeVariables': {"primaryTextColor":"#fff","primaryColor":"#5a4f7c","primaryBorderColor":"#5a4f7c","lineColor":"#f5a623","tertiaryColor":"#40375c","fontSize":"12px"}
}
}%%
graph LR
subgraph :core
:core:testing["testing"]
:core:data["data"]
:core:datastore["datastore"]
:core:domain["domain"]
:core:network["network"]
:core:database["database"]
end
subgraph :feature
:feature:issues["issues"]
:feature:repository["repository"]
end
:core:testing --> :core:data
:core:testing --> :core:datastore
:core:data --> :core:domain
:core:data --> :core:network
:core:data --> :core:database
:core:network --> :core:datastore
:core:network --> :core:domain
:feature:issues --> :core:data
:feature:issues --> :core:domain
:app --> :core:testing
:app --> :feature:repository
:app --> :feature:issues
:app --> :core:datastore
:app --> :core:domain
:feature:repository --> :core:data
:feature:repository --> :core:domain
The project includes unit tests for all modules, Instrumented tests are ran as unit tests with the use of Roboelectric apart from End to End tests which are run on a physical device declared in the app androidTest folder
E2Etests.mp4
-
Tech-stack
- Kotlin - a modern, cross-platform, statically typed, general-purpose programming language with type inference.
- Coroutines - lightweight threads to perform asynchronous tasks.
- Flow - a stream of data that emits multiple values sequentially.
- Dagger Hilt - a dependency injection library for Android built on top of Dagger that reduces the boilerplate of doing manual injection.
- Jetpack
- Jetpack Compose - A modern toolkit for building native Android UI
- Lifecycle - perform actions in response to a change in the lifecycle state.
- ViewModel - store and manage UI-related data lifecycle in a conscious manner and survive configuration change.
- Room - An ORM that provides an abstraction layer over SQLite to allow fluent database access.
- DataStore - A data storage solution that allows you to store key-value pairs.
- Paging3 - A Paging library helps you load and display pages of data from a larger dataset from local storage or over a network
- Timber - a highly extensible Android logger.
- Sentry - Application monitoring software with real-time event logging and aggregation platform.
- Coil - An image loading library for Android backed by Kotlin Coroutines.
- Apollo Kotlin - A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
-
Tests
- JUnit - a simple framework for writing repeatable tests.
- MockK - mocking library for Kotlin
- Truth - A fluent assertions library for Android and Java.
- Roboelectric - A library that allows you to run your tests on a simulated Android platform.
- Turbine - Turbine is a testing library for kotlinx.coroutines Flow.
-
Gradle
- Gradle Kotlin DSL - An alternative syntax for writing Gradle build scripts using Koltin.
- Version Catalogs - A scalable way of maintaining dependencies and plugins in a multi-module project.
- Convention Plugins - A way to encapsulate and reuse common build configuration in Gradle
- Plugins
-
CI/CD
- GitHub Actions *Firebase App Distribution - A service that allows you to distribute your app to testers and get feedback on your app.