├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values │ │ │ │ ├── styles.xml │ │ │ │ └── strings.xml │ │ │ └── layout │ │ │ │ ├── list_item_normal.xml │ │ │ │ ├── activity_repositories_list.xml │ │ │ │ ├── list_item_big.xml │ │ │ │ ├── list_item_featured.xml │ │ │ │ ├── activity_splash.xml │ │ │ │ └── activity_repository_details.xml │ │ ├── java │ │ │ └── frogermcs │ │ │ │ └── io │ │ │ │ └── githubclient │ │ │ │ ├── ui │ │ │ │ ├── activity │ │ │ │ │ ├── ActivityScope.java │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ ├── component │ │ │ │ │ │ ├── RepositoryDetailsActivityComponent.java │ │ │ │ │ │ ├── SplashActivityComponent.java │ │ │ │ │ │ └── RepositoriesListActivityComponent.java │ │ │ │ │ ├── presenter │ │ │ │ │ │ ├── RepositoryDetailsActivityPresenter.java │ │ │ │ │ │ ├── RepositoriesListActivityPresenter.java │ │ │ │ │ │ └── SplashActivityPresenter.java │ │ │ │ │ ├── module │ │ │ │ │ │ ├── RepositoryDetailsActivityModule.java │ │ │ │ │ │ ├── SplashActivityModule.java │ │ │ │ │ │ └── RepositoriesListActivityModule.java │ │ │ │ │ ├── RepositoryDetailsActivity.java │ │ │ │ │ ├── RepositoriesListActivity.java │ │ │ │ │ └── SplashActivity.java │ │ │ │ └── adapter │ │ │ │ │ ├── viewholder │ │ │ │ │ ├── RepositoriesListViewHolderFactory.java │ │ │ │ │ ├── RepositoryViewHolder.java │ │ │ │ │ ├── RepositoryViewHolderNormal.java │ │ │ │ │ ├── RepositoryViewHolderBig.java │ │ │ │ │ └── RepositoryViewHolderFeatured.java │ │ │ │ │ └── RepositoriesListAdapter.java │ │ │ │ ├── data │ │ │ │ ├── UserScope.java │ │ │ │ ├── api │ │ │ │ │ ├── GithubApiService.java │ │ │ │ │ ├── UserModule.java │ │ │ │ │ ├── response │ │ │ │ │ │ ├── UserResponse.java │ │ │ │ │ │ └── RepositoryResponse.java │ │ │ │ │ ├── UserManager.java │ │ │ │ │ ├── GithubApiModule.java │ │ │ │ │ └── RepositoriesManager.java │ │ │ │ ├── UserComponent.java │ │ │ │ └── model │ │ │ │ │ ├── User.java │ │ │ │ │ └── Repository.java │ │ │ │ ├── utils │ │ │ │ ├── Validator.java │ │ │ │ ├── SimpleObserver.java │ │ │ │ └── AnalyticsManager.java │ │ │ │ ├── ExecutorModule.java │ │ │ │ ├── HeavyExternalLibrary.java │ │ │ │ ├── AppComponent.java │ │ │ │ ├── AppModule.java │ │ │ │ ├── GithubClientApplication.java │ │ │ │ └── HeavyLibraryWrapper.java │ │ └── AndroidManifest.xml │ ├── androidTest │ │ └── java │ │ │ └── frogermcs │ │ │ └── io │ │ │ └── githubclient │ │ │ ├── tests │ │ │ ├── ApplicationTest.java │ │ │ └── SplashActivityUITests.java │ │ │ ├── MyTestRunner.java │ │ │ └── inject │ │ │ ├── GithubApiModuleMock.java │ │ │ └── ApplicationMock.java │ └── test │ │ └── java │ │ └── frogermcs │ │ └── io │ │ └── githubclient │ │ ├── MockAppModule.java │ │ ├── ui │ │ └── activity │ │ │ ├── module │ │ │ └── MockSplashActivityModule.java │ │ │ └── SplashActivityTests.java │ │ └── TestGithubClientApplication.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── README.md ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frogermcs/GithubClient/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frogermcs/GithubClient/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | *.iml 9 | .idea 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GithubClient 3 | https://api.github.com 4 | 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip 6 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/ActivityScope.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity; 2 | 3 | import javax.inject.Scope; 4 | 5 | /** 6 | * Created by Miroslaw Stanek on 22.04.15. 7 | */ 8 | @Scope 9 | public @interface ActivityScope { 10 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/UserScope.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | import javax.inject.Scope; 7 | 8 | /** 9 | * Created by Miroslaw Stanek on 22.04.15. 10 | */ 11 | @Scope 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface UserScope { 14 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/adapter/viewholder/RepositoriesListViewHolderFactory.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.adapter.viewholder; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.ViewGroup; 5 | 6 | /** 7 | * Created by Miroslaw Stanek on 11.06.2016. 8 | */ 9 | 10 | public interface RepositoriesListViewHolderFactory { 11 | RecyclerView.ViewHolder createViewHolder(ViewGroup parent); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/androidTest/java/frogermcs/io/githubclient/tests/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.tests; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/utils/Validator.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import javax.inject.Inject; 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * Created by Miroslaw Stanek on 23.04.15. 10 | */ 11 | public class Validator { 12 | 13 | public Validator() { 14 | } 15 | 16 | public boolean validUsername(String username) { 17 | return !TextUtils.isEmpty(username); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/utils/SimpleObserver.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.utils; 2 | 3 | import rx.Observer; 4 | 5 | /** 6 | * Created by Miroslaw Stanek on 23.04.15. 7 | */ 8 | public class SimpleObserver implements Observer { 9 | @Override 10 | public void onCompleted() { 11 | 12 | } 13 | 14 | @Override 15 | public void onError(Throwable e) { 16 | 17 | } 18 | 19 | @Override 20 | public void onNext(T t) { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ExecutorModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | import java.util.concurrent.Executor; 4 | import java.util.concurrent.Executors; 5 | 6 | import dagger.Module; 7 | import dagger.Provides; 8 | import dagger.producers.Production; 9 | 10 | /** 11 | * Created by froger_mcs on 12/02/2018. 12 | */ 13 | 14 | @Module 15 | final class ExecutorModule { 16 | @Provides 17 | @Production 18 | static Executor executor() { 19 | return Executors.newSingleThreadExecutor(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/adapter/viewholder/RepositoryViewHolder.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.adapter.viewholder; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | 6 | import frogermcs.io.githubclient.data.model.Repository; 7 | 8 | /** 9 | * Created by Miroslaw Stanek on 11.06.2016. 10 | */ 11 | 12 | public abstract class RepositoryViewHolder extends RecyclerView.ViewHolder { 13 | public RepositoryViewHolder(View itemView) { 14 | super(itemView); 15 | } 16 | 17 | public abstract void bind(Repository repository); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/HeavyExternalLibrary.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | /** 4 | * Created by Miroslaw Stanek on 28.09.15. 5 | */ 6 | public class HeavyExternalLibrary { 7 | 8 | private boolean initialized = false; 9 | 10 | public HeavyExternalLibrary() { 11 | } 12 | 13 | public void init() { 14 | try { 15 | Thread.sleep(500); 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | initialized = true; 20 | } 21 | 22 | public void callMethod() { 23 | if (!initialized) throw new RuntimeException("Call init() before you use this library"); 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | import frogermcs.io.githubclient.AppComponent; 7 | import frogermcs.io.githubclient.GithubClientApplication; 8 | 9 | /** 10 | * Created by Miroslaw Stanek on 23.04.15. 11 | */ 12 | public abstract class BaseActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setupActivityComponent(); 18 | } 19 | 20 | protected abstract void setupActivityComponent(); 21 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/froger_mcs/dev/android_sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/frogermcs/io/githubclient/MyTestRunner.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.support.test.runner.AndroidJUnitRunner; 6 | 7 | import frogermcs.io.githubclient.inject.ApplicationMock; 8 | 9 | /** 10 | * Created by Miroslaw Stanek on 24.09.15. 11 | */ 12 | public class MyTestRunner extends AndroidJUnitRunner { 13 | 14 | @Override 15 | public Application newApplication(ClassLoader cl, String className, Context context) 16 | throws InstantiationException, IllegalAccessException, ClassNotFoundException { 17 | return super.newApplication(cl, ApplicationMock.class.getName(), context); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/test/java/frogermcs/io/githubclient/MockAppModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | import android.app.Application; 4 | 5 | import org.mockito.Mock; 6 | import org.mockito.MockitoAnnotations; 7 | 8 | import frogermcs.io.githubclient.utils.AnalyticsManager; 9 | 10 | /** 11 | * Created by Miroslaw Stanek on 20.09.15. 12 | */ 13 | public class MockAppModule extends AppModule { 14 | @Mock 15 | AnalyticsManager analyticsManagerMock; 16 | 17 | public MockAppModule(Application application) { 18 | super(application); 19 | MockitoAnnotations.initMocks(this); 20 | } 21 | 22 | @Override 23 | AnalyticsManager provideAnalyticsManager() { 24 | return analyticsManagerMock; 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/component/RepositoryDetailsActivityComponent.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.component; 2 | 3 | import dagger.Subcomponent; 4 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 5 | import frogermcs.io.githubclient.ui.activity.RepositoryDetailsActivity; 6 | import frogermcs.io.githubclient.ui.activity.module.RepositoryDetailsActivityModule; 7 | 8 | /** 9 | * Created by Miroslaw Stanek on 23.04.15. 10 | */ 11 | @ActivityScope 12 | @Subcomponent( 13 | modules = RepositoryDetailsActivityModule.class 14 | ) 15 | public interface RepositoryDetailsActivityComponent { 16 | 17 | RepositoryDetailsActivity inject(RepositoryDetailsActivity repositoryDetailsActivity); 18 | 19 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/component/SplashActivityComponent.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.component; 2 | 3 | import dagger.Subcomponent; 4 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 5 | import frogermcs.io.githubclient.ui.activity.SplashActivity; 6 | import frogermcs.io.githubclient.ui.activity.module.SplashActivityModule; 7 | import frogermcs.io.githubclient.ui.activity.presenter.SplashActivityPresenter; 8 | 9 | /** 10 | * Created by Miroslaw Stanek on 23.04.15. 11 | */ 12 | @ActivityScope 13 | @Subcomponent( 14 | modules = SplashActivityModule.class 15 | ) 16 | public interface SplashActivityComponent { 17 | 18 | SplashActivity inject(SplashActivity splashActivity); 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/utils/AnalyticsManager.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.utils; 2 | 3 | import android.app.Application; 4 | 5 | import javax.inject.Inject; 6 | import javax.inject.Singleton; 7 | 8 | import frogermcs.io.githubclient.data.UserScope; 9 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 10 | import timber.log.Timber; 11 | 12 | /** 13 | * Created by Miroslaw Stanek on 23.04.15. 14 | */ 15 | public class AnalyticsManager { 16 | 17 | private Application app; 18 | 19 | public AnalyticsManager(Application app) { 20 | this.app = app; 21 | } 22 | 23 | public void logScreenView(String screenName) { 24 | Timber.d("Logged screen name: " + screenName); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /app/src/androidTest/java/frogermcs/io/githubclient/inject/GithubApiModuleMock.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.inject; 2 | 3 | import frogermcs.io.githubclient.data.api.GithubApiModule; 4 | import frogermcs.io.githubclient.data.api.GithubApiService; 5 | import frogermcs.io.githubclient.data.api.UserManager; 6 | 7 | /** 8 | * Created by Miroslaw Stanek on 23.09.15. 9 | */ 10 | public class GithubApiModuleMock extends GithubApiModule { 11 | 12 | private UserManager userManagerMock; 13 | 14 | public GithubApiModuleMock(UserManager userManagerMock) { 15 | this.userManagerMock = userManagerMock; 16 | } 17 | 18 | @Override 19 | public UserManager provideUserManager(GithubApiService githubApiService) { 20 | return userManagerMock; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/api/GithubApiService.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data.api; 2 | 3 | import java.util.List; 4 | 5 | import frogermcs.io.githubclient.data.api.response.RepositoryResponse; 6 | import frogermcs.io.githubclient.data.api.response.UserResponse; 7 | import retrofit2.http.GET; 8 | import retrofit2.http.Path; 9 | import rx.Observable; 10 | 11 | /** 12 | * Created by Miroslaw Stanek on 22.04.15. 13 | */ 14 | public interface GithubApiService { 15 | 16 | @GET("/users/{username}") 17 | Observable getUser( 18 | @Path("username") String username 19 | ); 20 | 21 | @GET("/users/{username}/repos") 22 | Observable> getUsersRepositories( 23 | @Path("username") String username 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_repositories_list.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/api/UserModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data.api; 2 | 3 | import dagger.Module; 4 | import dagger.Provides; 5 | import frogermcs.io.githubclient.data.UserScope; 6 | import frogermcs.io.githubclient.data.model.User; 7 | 8 | /** 9 | * Created by Miroslaw Stanek on 23.06.15. 10 | */ 11 | @Module 12 | public class UserModule { 13 | 14 | private User user; 15 | 16 | public UserModule(User user) { 17 | this.user = user; 18 | } 19 | 20 | @Provides 21 | @UserScope 22 | User provideUser() { 23 | return user; 24 | } 25 | 26 | @Provides 27 | @UserScope 28 | RepositoriesManager provideRepositoriesManager(User user, GithubApiService githubApiService) { 29 | return new RepositoriesManager(user, githubApiService); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/component/RepositoriesListActivityComponent.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.component; 2 | 3 | import dagger.Subcomponent; 4 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 5 | import frogermcs.io.githubclient.ui.activity.RepositoriesListActivity; 6 | import frogermcs.io.githubclient.ui.activity.module.RepositoriesListActivityModule; 7 | import frogermcs.io.githubclient.ui.activity.presenter.RepositoriesListActivityPresenter; 8 | 9 | /** 10 | * Created by Miroslaw Stanek on 23.04.15. 11 | */ 12 | @ActivityScope 13 | @Subcomponent( 14 | modules = RepositoriesListActivityModule.class 15 | ) 16 | public interface RepositoriesListActivityComponent { 17 | 18 | RepositoriesListActivity inject(RepositoriesListActivity repositoriesListActivity); 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/presenter/RepositoryDetailsActivityPresenter.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.presenter; 2 | 3 | import frogermcs.io.githubclient.data.model.User; 4 | import frogermcs.io.githubclient.ui.activity.RepositoryDetailsActivity; 5 | 6 | /** 7 | * Created by Miroslaw Stanek on 23.04.15. 8 | */ 9 | public class RepositoryDetailsActivityPresenter { 10 | private RepositoryDetailsActivity repositoryDetailsActivity; 11 | private User user; 12 | 13 | public RepositoryDetailsActivityPresenter(RepositoryDetailsActivity repositoryDetailsActivity, User user) { 14 | this.repositoryDetailsActivity = repositoryDetailsActivity; 15 | this.user = user; 16 | } 17 | 18 | public void init() { 19 | repositoryDetailsActivity.setupUserName(user.login); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/AppComponent.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | import javax.inject.Singleton; 4 | 5 | import dagger.Component; 6 | import frogermcs.io.githubclient.data.api.GithubApiModule; 7 | import frogermcs.io.githubclient.data.UserComponent; 8 | import frogermcs.io.githubclient.data.api.UserModule; 9 | import frogermcs.io.githubclient.ui.activity.component.SplashActivityComponent; 10 | import frogermcs.io.githubclient.ui.activity.module.SplashActivityModule; 11 | 12 | /** 13 | * Created by Miroslaw Stanek on 22.04.15. 14 | */ 15 | @Singleton 16 | @Component( 17 | modules = { 18 | AppModule.class, 19 | GithubApiModule.class 20 | } 21 | ) 22 | public interface AppComponent { 23 | 24 | SplashActivityComponent plus(SplashActivityModule module); 25 | 26 | UserComponent plus(UserModule userModule); 27 | 28 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /app/src/test/java/frogermcs/io/githubclient/ui/activity/module/MockSplashActivityModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.module; 2 | 3 | import dagger.Provides; 4 | import frogermcs.io.githubclient.data.api.UserManager; 5 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 6 | import frogermcs.io.githubclient.ui.activity.SplashActivity; 7 | import frogermcs.io.githubclient.ui.activity.presenter.SplashActivityPresenter; 8 | import frogermcs.io.githubclient.utils.Validator; 9 | 10 | import static org.mockito.Mockito.mock; 11 | 12 | /** 13 | * Created by Miroslaw Stanek on 20.09.15. 14 | */ 15 | public class MockSplashActivityModule extends SplashActivityModule { 16 | 17 | public MockSplashActivityModule(SplashActivity splashActivity) { 18 | super(splashActivity); 19 | } 20 | 21 | @Provides 22 | @ActivityScope 23 | SplashActivityPresenter provideSplashActivityPresenter(Validator validator, UserManager userManager) { 24 | return mock(SplashActivityPresenter.class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GithubClient 2 | Example of Github API client implemented on top of Dagger 2 DI framework. 3 | 4 | This code was created as an example for Dependency Injection with Dagger 2 series on my dev-blog: 5 | 6 | - [Introdution to Dependency Injection](http://frogermcs.github.io/dependency-injection-with-dagger-2-introdution-to-di/) 7 | - [Dagger 2 API](http://frogermcs.github.io/dependency-injection-with-dagger-2-the-api/) 8 | - [Dagger 2 - custom scopes](http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/) 9 | - [Dagger 2 - graph creation performance](http://frogermcs.github.io/dagger-graph-creation-performance/) 10 | - [Dependency injection with Dagger 2 - Producers](http://frogermcs.github.io/dependency-injection-with-dagger-2-producers/) 11 | - [Inject everything - ViewHolder and Dagger 2 (with Multibinding and AutoFactory example)](http://frogermcs.github.io/inject-everything-viewholder-and-dagger-2-example/) 12 | 13 | This code was originally prepared for my presentation at Google I/O Extended 2015 in Tech Space Cracow. http://www.meetup.com/GDG-Krakow/events/221822600/ 14 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/api/response/UserResponse.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data.api.response; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Created by Miroslaw Stanek on 22.04.15. 7 | */ 8 | public class UserResponse { 9 | public String login; 10 | public long id; 11 | public String avatar_url; 12 | public String gravatar_id; 13 | public String url; 14 | public String html_url; 15 | public String followers_url; 16 | public String following_url; 17 | public String gists_url; 18 | public String starred_url; 19 | public String subscriptions_url; 20 | public String organizations_url; 21 | public String repos_url; 22 | public String events_url; 23 | public String received_events_url; 24 | public String type; 25 | public String name; 26 | public String blog; 27 | public String location; 28 | public String email; 29 | public int public_repos; 30 | public int public_gists; 31 | public int followers; 32 | public int following; 33 | public Date created_at; 34 | public Date updated_at; 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_big.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/UserComponent.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data; 2 | 3 | import dagger.Subcomponent; 4 | import frogermcs.io.githubclient.data.api.UserModule; 5 | import frogermcs.io.githubclient.ui.activity.component.RepositoriesListActivityComponent; 6 | import frogermcs.io.githubclient.ui.activity.component.RepositoryDetailsActivityComponent; 7 | import frogermcs.io.githubclient.ui.activity.component.SplashActivityComponent; 8 | import frogermcs.io.githubclient.ui.activity.module.RepositoriesListActivityModule; 9 | import frogermcs.io.githubclient.ui.activity.module.RepositoryDetailsActivityModule; 10 | import frogermcs.io.githubclient.ui.activity.module.SplashActivityModule; 11 | 12 | /** 13 | * Created by Miroslaw Stanek on 23.06.15. 14 | */ 15 | @UserScope 16 | @Subcomponent( 17 | modules = { 18 | UserModule.class 19 | } 20 | ) 21 | public interface UserComponent { 22 | 23 | RepositoriesListActivityComponent plus(RepositoriesListActivityModule module); 24 | 25 | RepositoryDetailsActivityComponent plus(RepositoryDetailsActivityModule module); 26 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/adapter/viewholder/RepositoryViewHolderNormal.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.adapter.viewholder; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | import android.widget.TextView; 6 | 7 | import com.google.auto.factory.AutoFactory; 8 | 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import frogermcs.io.githubclient.R; 12 | import frogermcs.io.githubclient.data.model.Repository; 13 | 14 | /** 15 | * Created by Miroslaw Stanek on 11.06.2016. 16 | */ 17 | @AutoFactory(implementing = RepositoriesListViewHolderFactory.class) 18 | public class RepositoryViewHolderNormal extends RepositoryViewHolder { 19 | 20 | @BindView(R.id.tvName) 21 | TextView tvName; 22 | 23 | public RepositoryViewHolderNormal(ViewGroup parent) { 24 | super(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_normal, parent, false)); 25 | ButterKnife.bind(this, itemView); 26 | } 27 | 28 | @Override 29 | public void bind(Repository repository) { 30 | tvName.setText(repository.name); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/api/response/RepositoryResponse.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data.api.response; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Created by Miroslaw Stanek on 22.04.15. 7 | */ 8 | public class RepositoryResponse { 9 | public long id; 10 | public String name; 11 | public String full_name; 12 | public UserResponse owner; 13 | public String html_url; 14 | public String description; 15 | public String url; 16 | public Date created_at; 17 | public Date updated_at; 18 | public Date pushed_at; 19 | public String git_url; 20 | public String ssh_url; 21 | public String clone_url; 22 | public String svn_url; 23 | public String homepage; 24 | public int stargazers_count; 25 | public int watchers_count; 26 | public String language; 27 | public boolean has_issues; 28 | public boolean has_downloads; 29 | public boolean has_wiki; 30 | public boolean has_pages; 31 | public int forks_count; 32 | public int open_issues_count; 33 | public int forks; 34 | public int open_issues; 35 | public int watchers; 36 | public String default_branch; 37 | } 38 | -------------------------------------------------------------------------------- /app/src/test/java/frogermcs/io/githubclient/TestGithubClientApplication.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient; 2 | 3 | import frogermcs.io.githubclient.ui.activity.component.SplashActivityComponent; 4 | import frogermcs.io.githubclient.ui.activity.module.SplashActivityModule; 5 | 6 | import static org.mockito.Matchers.any; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.when; 9 | 10 | /** 11 | * Created by Miroslaw Stanek on 19.09.15. 12 | */ 13 | public class TestGithubClientApplication 14 | extends GithubClientApplication { 15 | 16 | private AppComponent appComponent; 17 | private SplashActivityComponent splashActivityComponent; 18 | 19 | @Override 20 | public AppComponent getAppComponent() { 21 | if (appComponent == null) { 22 | appComponent = mock(AppComponent.class); 23 | when(appComponent.plus(any(SplashActivityModule.class))) 24 | .thenReturn(splashActivityComponent); 25 | } 26 | 27 | return appComponent; 28 | } 29 | 30 | public void setSplashActivityComponent(SplashActivityComponent component) { 31 | this.splashActivityComponent = component; 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/androidTest/java/frogermcs/io/githubclient/inject/ApplicationMock.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.inject; 2 | 3 | import frogermcs.io.githubclient.AppComponent; 4 | import frogermcs.io.githubclient.AppModule; 5 | import frogermcs.io.githubclient.DaggerAppComponent; 6 | import frogermcs.io.githubclient.GithubClientApplication; 7 | import frogermcs.io.githubclient.data.api.GithubApiModule; 8 | 9 | /** 10 | * Created by Miroslaw Stanek on 24.09.15. 11 | */ 12 | public class ApplicationMock extends GithubClientApplication { 13 | 14 | private AppComponent appComponent; 15 | private GithubApiModule githubApiModuleMock; 16 | 17 | public void setGithubApiModuleMock(GithubApiModule githubApiModuleMock) { 18 | this.githubApiModuleMock = githubApiModuleMock; 19 | setupMockAppComponent(); 20 | } 21 | 22 | public void setupMockAppComponent() { 23 | appComponent = DaggerAppComponent.builder() 24 | .appModule(new AppModule(this)) 25 | .githubApiModule(githubApiModuleMock) 26 | .build(); 27 | } 28 | 29 | @Override 30 | public AppComponent getAppComponent() { 31 | return appComponent == null ? super.getAppComponent() : appComponent; 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_featured.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 26 | 27 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/module/RepositoryDetailsActivityModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.module; 2 | 3 | import dagger.Module; 4 | import dagger.Provides; 5 | import frogermcs.io.githubclient.data.model.User; 6 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 7 | import frogermcs.io.githubclient.ui.activity.RepositoryDetailsActivity; 8 | import frogermcs.io.githubclient.ui.activity.presenter.RepositoryDetailsActivityPresenter; 9 | 10 | /** 11 | * Created by Miroslaw Stanek on 23.04.15. 12 | */ 13 | @Module 14 | public class RepositoryDetailsActivityModule { 15 | private RepositoryDetailsActivity repositoryDetailsActivity; 16 | 17 | public RepositoryDetailsActivityModule(RepositoryDetailsActivity repositoryDetailsActivity) { 18 | this.repositoryDetailsActivity = repositoryDetailsActivity; 19 | } 20 | 21 | @Provides 22 | @ActivityScope 23 | RepositoryDetailsActivity provideRepositoryDetailsActivity() { 24 | return repositoryDetailsActivity; 25 | } 26 | 27 | @Provides 28 | @ActivityScope 29 | RepositoryDetailsActivityPresenter provideRepositoryDetailsActivityPresenter(User user) { 30 | return new RepositoryDetailsActivityPresenter(repositoryDetailsActivity, user); 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/data/model/User.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.data.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by Miroslaw Stanek on 22.04.15. 8 | */ 9 | public class User implements Parcelable { 10 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 11 | public User createFromParcel(Parcel source) { 12 | return new User(source); 13 | } 14 | 15 | public User[] newArray(int size) { 16 | return new User[size]; 17 | } 18 | }; 19 | public String login; 20 | public long id; 21 | public String url; 22 | public String email; 23 | 24 | public User() { 25 | } 26 | 27 | protected User(Parcel in) { 28 | this.login = in.readString(); 29 | this.id = in.readLong(); 30 | this.url = in.readString(); 31 | this.email = in.readString(); 32 | } 33 | 34 | @Override 35 | public int describeContents() { 36 | return 0; 37 | } 38 | 39 | @Override 40 | public void writeToParcel(Parcel dest, int flags) { 41 | dest.writeString(this.login); 42 | dest.writeLong(this.id); 43 | dest.writeString(this.url); 44 | dest.writeString(this.email); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/adapter/viewholder/RepositoryViewHolderBig.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.adapter.viewholder; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | import android.widget.TextView; 6 | 7 | import com.google.auto.factory.AutoFactory; 8 | 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import frogermcs.io.githubclient.R; 12 | import frogermcs.io.githubclient.data.model.Repository; 13 | 14 | /** 15 | * Created by Miroslaw Stanek on 11.06.2016. 16 | */ 17 | @AutoFactory(implementing = RepositoriesListViewHolderFactory.class) 18 | public class RepositoryViewHolderBig extends RepositoryViewHolder { 19 | 20 | @BindView(R.id.tvName) 21 | TextView tvName; 22 | @BindView(R.id.tvStars) 23 | TextView tvStars; 24 | @BindView(R.id.tvForks) 25 | TextView tvForks; 26 | 27 | public RepositoryViewHolderBig(ViewGroup parent) { 28 | super(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_big, parent, false)); 29 | ButterKnife.bind(this, itemView); 30 | } 31 | 32 | @Override 33 | public void bind(Repository repository) { 34 | tvName.setText(repository.name); 35 | tvStars.setText("Stars: " + repository.stargazers_count); 36 | tvForks.setText("Forks: " + repository.forks_count); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/adapter/viewholder/RepositoryViewHolderFeatured.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.adapter.viewholder; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | import android.widget.TextView; 6 | 7 | import com.google.auto.factory.AutoFactory; 8 | 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import frogermcs.io.githubclient.R; 12 | import frogermcs.io.githubclient.data.model.Repository; 13 | 14 | /** 15 | * Created by Miroslaw Stanek on 11.06.2016. 16 | */ 17 | @AutoFactory(implementing = RepositoriesListViewHolderFactory.class) 18 | public class RepositoryViewHolderFeatured extends RepositoryViewHolder { 19 | 20 | @BindView(R.id.tvName) 21 | TextView tvName; 22 | @BindView(R.id.tvStars) 23 | TextView tvStars; 24 | @BindView(R.id.tvForks) 25 | TextView tvForks; 26 | 27 | public RepositoryViewHolderFeatured(ViewGroup parent) { 28 | super(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_featured, parent, false)); 29 | ButterKnife.bind(this, itemView); 30 | } 31 | 32 | @Override 33 | public void bind(Repository repository) { 34 | tvName.setText(repository.name); 35 | tvStars.setText("Stars: " + repository.stargazers_count); 36 | tvForks.setText("Forks: " + repository.forks_count); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/frogermcs/io/githubclient/ui/activity/module/SplashActivityModule.java: -------------------------------------------------------------------------------- 1 | package frogermcs.io.githubclient.ui.activity.module; 2 | 3 | import dagger.Module; 4 | import dagger.Provides; 5 | import frogermcs.io.githubclient.HeavyExternalLibrary; 6 | import frogermcs.io.githubclient.HeavyLibraryWrapper; 7 | import frogermcs.io.githubclient.data.api.UserManager; 8 | import frogermcs.io.githubclient.ui.activity.ActivityScope; 9 | import frogermcs.io.githubclient.ui.activity.SplashActivity; 10 | import frogermcs.io.githubclient.ui.activity.presenter.SplashActivityPresenter; 11 | import frogermcs.io.githubclient.utils.Validator; 12 | 13 | /** 14 | * Created by Miroslaw Stanek on 23.04.15. 15 | */ 16 | @Module 17 | public class SplashActivityModule { 18 | private SplashActivity splashActivity; 19 | 20 | public SplashActivityModule(SplashActivity splashActivity) { 21 | this.splashActivity = splashActivity; 22 | } 23 | 24 | @Provides 25 | @ActivityScope 26 | SplashActivity provideSplashActivity() { 27 | return splashActivity; 28 | } 29 | 30 | @Provides 31 | @ActivityScope 32 | SplashActivityPresenter 33 | provideSplashActivityPresenter(Validator validator, UserManager userManager, HeavyLibraryWrapper heavyLibraryWrapper) { 34 | return new SplashActivityPresenter(splashActivity, validator, userManager, heavyLibraryWrapper); 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 20 | 21 |