Skip to content

Commit

Permalink
Fix ci2 (#11)
Browse files Browse the repository at this point in the history
* cleaning up and upgrade AS

* cleaning up and upgrade AS

* implement hilt

* implement swipe to refresh with hilt

* update CI github actions
  • Loading branch information
Tarek-Bohdima authored Oct 17, 2024
1 parent 4e02f99 commit 82b5ab4
Show file tree
Hide file tree
Showing 17 changed files with 70 additions and 83 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ jobs:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build debug APK
Expand Down
9 changes: 5 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id 'kotlin-kapt'
id 'kotlin-parcelize'
id 'androidx.navigation.safeargs.kotlin'
id 'com.google.dagger.hilt.android'
}

android {
Expand Down Expand Up @@ -53,12 +54,12 @@ dependencies {
def lifecycle_version = "2.5.1"
def recyclerview_version = "1.2.1"
def navigation_version = "2.5.3"
def hilt_version = "2.44"
def swipe_to_refresh_version = "1.1.0"

def test_junit_version = "4.13.2"
def androidTest_junit_version = "1.1.5"
def androidTest_espresso_version = "3.5.1"
def dagger_version = "2.43"


implementation "androidx.core:core-ktx:$core_version"
Expand Down Expand Up @@ -103,9 +104,9 @@ dependencies {
// swipe to refresh
implementation "androidx.swiperefreshlayout:swiperefreshlayout:$swipe_to_refresh_version"

// dagger2
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
// hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"

testImplementation "junit:junit:$test_junit_version"
androidTestImplementation "androidx.test.ext:junit:$androidTest_junit_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.android.dogsapp

import android.annotation.SuppressLint
import android.view.View
import android.widget.ImageView
import android.widget.TextView
Expand Down Expand Up @@ -49,6 +50,7 @@ fun bindStatus(statusImageView: ImageView, status: DogsApiStatus?) {
}
}

@SuppressLint("SetTextI18n")
@BindingAdapter("breedName")
fun bindBreedName(textView: TextView, imageUrl: String?) {
imageUrl?.let {
Expand Down
13 changes: 2 additions & 11 deletions app/src/main/java/com/example/android/dogsapp/DogsApplication.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
package com.example.android.dogsapp

import android.app.Application
import com.example.android.dogsapp.common.di.application.ApplicationComponent
import com.example.android.dogsapp.common.di.application.ApplicationModule
import com.example.android.dogsapp.common.di.application.DaggerApplicationComponent

import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class DogsApplication: Application() {

val appComponent: ApplicationComponent by lazy {
DaggerApplicationComponent.builder()
.applicationModule(ApplicationModule(application = this))
.build()
}

override fun onCreate() {
super.onCreate()
appComponent.inject(this)
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
package com.example.android.dogsapp.common.di.application

import android.app.Application
import android.content.Context
import com.example.android.dogsapp.DogsApplication
import com.example.android.dogsapp.data.network.DogsApi
import com.example.android.dogsapp.data.repository.DogsRepository
import com.example.android.dogsapp.data.repository.DogsRepositoryImpl
import com.example.android.dogsapp.ui.utils.RefreshManager
import com.example.android.dogsapp.ui.utils.SwipeToRefreshManagerImpl
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import javax.inject.Singleton


private const val BASE_URL = "https://dog.ceo/api/"

@Module
class ApplicationModule(private val application: Application) {
@InstallIn(SingletonComponent::class)
object ApplicationModule {

@Singleton
@Provides
fun provideApplication(@ApplicationContext app: Context): DogsApplication =
app as DogsApplication

@Singleton
@Provides
@ApplicationScope
fun retrofit(): Retrofit {
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
Expand All @@ -27,19 +43,19 @@ class ApplicationModule(private val application: Application) {
.build()
}

@Singleton
@Provides
@ApplicationScope
fun provideDogsRepository(dogsApi: DogsApi): DogsRepository = DogsRepositoryImpl(dogsApi)
fun provideDogsApi(retrofit: Retrofit): DogsApi {
return retrofit.create(DogsApi::class.java)
}

@Provides
@ApplicationScope
fun application() = application
fun provideDogsRepository(dogsApi: DogsApi): DogsRepository {
return DogsRepositoryImpl(dogsApi)
}

@Provides
@ApplicationScope
fun dogsApi(retrofit: Retrofit): DogsApi = retrofit.create(DogsApi::class.java)

companion object{
private const val BASE_URL = "https://dog.ceo/api/"
fun provideRefreshManager(swipeToRefreshManagerImpl: SwipeToRefreshManagerImpl): RefreshManager {
return swipeToRefreshManagerImpl
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import com.example.android.dogsapp.data.domain.DogsResponse

interface DogsRepository {
suspend fun getDogsPhotos(): DogsResponse
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.example.android.dogsapp.data.repository

import com.example.android.dogsapp.common.di.application.ApplicationScope
import com.example.android.dogsapp.data.domain.DogsResponse
import com.example.android.dogsapp.data.network.DogsApi
import javax.inject.Inject

@ApplicationScope
class DogsRepositoryImpl @Inject constructor(private val dogsApi: DogsApi): DogsRepository {

override suspend fun getDogsPhotos(): DogsResponse = dogsApi.getRandomDogs()
Expand Down
21 changes: 4 additions & 17 deletions app/src/main/java/com/example/android/dogsapp/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,25 @@ import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI
import com.example.android.dogsapp.DogsApplication
import com.example.android.dogsapp.R
import com.example.android.dogsapp.common.di.activity.ActivityComponent
import com.example.android.dogsapp.common.di.activity.DaggerActivityComponent
import com.example.android.dogsapp.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var activityComponent: ActivityComponent

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityComponent = DaggerActivityComponent.builder()
.applicationComponent((application as DogsApplication).appComponent)
.build()

activityComponent.inject(this)

DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)

val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
.findFragmentById(R.id.nav_host_fragment_container) as NavHostFragment
val navController = navHostFragment.navController

NavigationUI.setupActionBarWithNavController(this, navController)
}

fun getActivityComponent(): ActivityComponent {
return activityComponent
}

override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.nav_host_fragment)
val navController = this.findNavController(R.id.nav_host_fragment_container)
return NavigationUI.navigateUp(navController, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.android.dogsapp.databinding.FragmentDetailsBinding

class DetailsFragment : Fragment(){
class DetailsFragment : Fragment() {

private lateinit var binding: FragmentDetailsBinding

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
// return inflater.inflate(R.layout.fragment_details, container, false)
binding = FragmentDetailsBinding.inflate(inflater, container, false)
binding.lifecycleOwner = viewLifecycleOwner

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ class DogsAdapter(private val listener: DogClickListener) : ListAdapter<Dog, Dog
DiffCallBack
) {

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): DogsViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogsViewHolder {
return DogsViewHolder(GridViewItemBinding.inflate(LayoutInflater.from(parent.context)))
}

Expand Down Expand Up @@ -46,4 +43,4 @@ class DogsAdapter(private val listener: DogClickListener) : ListAdapter<Dog, Dog

class DogClickListener(val listener: (dog: Dog) -> Unit) {
fun onClick(dog: Dog) = listener(dog)
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,20 @@
package com.example.android.dogsapp.ui.main

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.example.android.dogsapp.DogsApplication
import com.example.android.dogsapp.data.repository.DogsRepository
import com.example.android.dogsapp.databinding.FragmentMainBinding
import com.example.android.dogsapp.ui.MainActivity
import com.example.android.dogsapp.ui.utils.RefreshManager
import javax.inject.Inject
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainFragment : Fragment() {

private lateinit var binding: FragmentMainBinding

@Inject
lateinit var dogsRepository: DogsRepository

@Inject
lateinit var refreshManager: RefreshManager

private val viewModel: MainViewModel by viewModels { MainViewModelFactory(dogsRepository, refreshManager) }

override fun onAttach(context: Context) {
super.onAttach(context)
(requireActivity() as MainActivity).getActivityComponent().inject(this)
}
private val viewModel: MainViewModel by viewModels()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import androidx.lifecycle.viewModelScope
import com.example.android.dogsapp.data.domain.Dog
import com.example.android.dogsapp.data.repository.DogsRepository
import com.example.android.dogsapp.ui.utils.RefreshManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

enum class DogsApiStatus { LOADING, ERROR, DONE }

class MainViewModel(
@HiltViewModel
class MainViewModel @Inject constructor(
private val dogsRepository: DogsRepository,
private val refreshManager: RefreshManager
) : ViewModel() {
Expand All @@ -21,7 +24,6 @@ class MainViewModel(
get() = _status

private val _dogs = MutableLiveData<List<Dog>>()

val dogs: LiveData<List<Dog>>
get() = _dogs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ class SwipeToRefreshManagerImpl @Inject constructor() : RefreshManager {
refreshListener?.invoke()
}
}
}
}
4 changes: 2 additions & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
android:layout_height="match_parent">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:id="@+id/nav_host_fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
app:navGraph="@navigation/navgraph" />

</FrameLayout>
</layout>
1 change: 1 addition & 0 deletions app/src/main/res/layout/fragment_details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:textAppearance="?attr/textAppearanceHeadline5"
app:breedName="@{dog.imageUrl}"
tools:text="Breed Name" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
android:id="@+id/navgraph"
app:startDestination="@id/mainFragment">

<fragment
Expand Down
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.44" // Add Hilt classpath here
}
}

plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
Expand Down

0 comments on commit 82b5ab4

Please sign in to comment.