diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..d323e7e --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,42 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/2.0/configuration-reference +version: 2.1 + +# Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects. +orbs: + android: circleci/android@1.0.3 + +jobs: + # Below is the definition of your job to build and test your app, you can rename and customize it as you want. + build-and-test: + # These next lines define the Android machine image executor: https://circleci.com/docs/2.0/executor-types/ + executor: + name: android/android-machine + + steps: + # Checkout the code as the first step. + - checkout + + # The next step will run the unit tests + - android/run-tests: + test-command: ./gradlew lint testDebug --continue + + # Then start the emulator and run the Instrumentation tests! + - android/start-emulator-and-run-tests: + test-command: ./gradlew connectedDebugAndroidTest + system-image: system-images;android-25;google_apis;x86 + + # And finally run the release build + - run: + name: Assemble release build + command: | + ./gradlew assembleRelease + +workflows: + # Below is the definition of your workflow. + # Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above. + # CircleCI will run this workflow on every commit. + # For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows + sample: + jobs: + - build-and-test diff --git a/.gitignore b/.gitignore index 5d18272..6ce26ca 100644 --- a/.gitignore +++ b/.gitignore @@ -38,18 +38,7 @@ captures/ # IntelliJ *.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -.idea/jarRepositories.xml -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml +.idea/* # Keystore files # Uncomment the following lines if you do not want to check your keystore files in. diff --git a/app/build.gradle b/app/build.gradle index 9f309a9..2359b9d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,6 +3,7 @@ plugins { id 'kotlin-android' id 'kotlin-kapt' id 'androidx.navigation.safeargs' + id 'dagger.hilt.android.plugin' } android { @@ -92,6 +93,12 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" + // Hilt + implementation "com.google.dagger:hilt-android:$hilt_version" + kapt "com.google.dagger:hilt-android-compiler:$hilt_version" + implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_extensions_version" + kapt "androidx.hilt:hilt-compiler:$hilt_extensions_version" + // Testing testImplementation "junit:junit:$junit_version" testImplementation "androidx.test:rules:$rules_version" diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/App.kt b/app/src/main/java/com/carlosjimz87/funwithflags/App.kt index 612a030..ade0c33 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/App.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/App.kt @@ -2,13 +2,12 @@ package com.carlosjimz87.funwithflags import android.app.Application import com.carlosjimz87.funwithflags.repositories.CountriesRepository +import dagger.hilt.android.HiltAndroidApp import timber.log.Timber +@HiltAndroidApp class App : Application() { - val countriesRepository: CountriesRepository - get() = ServiceLocator.provideCountriesRepository() - override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/MainActivity.kt b/app/src/main/java/com/carlosjimz87/funwithflags/MainActivity.kt index 5a1ecb6..d023837 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/MainActivity.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/MainActivity.kt @@ -5,8 +5,10 @@ import androidx.appcompat.app.AppCompatActivity import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupActionBarWithNavController +import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber +@AndroidEntryPoint class MainActivity : AppCompatActivity() { private lateinit var navController: NavController diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/ServiceLocator.kt b/app/src/main/java/com/carlosjimz87/funwithflags/ServiceLocator.kt deleted file mode 100644 index b0ee16d..0000000 --- a/app/src/main/java/com/carlosjimz87/funwithflags/ServiceLocator.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.carlosjimz87.funwithflags - - -import com.carlosjimz87.funwithflags.network.api.ApiManager -import com.carlosjimz87.funwithflags.network.services.CountriesServiceImpl -import com.carlosjimz87.funwithflags.repositories.CountriesRepository -import com.carlosjimz87.funwithflags.repositories.CountriesRepositoryImpl - -object ServiceLocator { - - @Volatile - var countriesRepository: CountriesRepository? = null - - private fun createCountriesRepository(): CountriesRepository { - val newRepo = CountriesRepositoryImpl(CountriesServiceImpl(ApiManager.retrofitService)) - countriesRepository = newRepo - return newRepo - } - - fun provideCountriesRepository(): CountriesRepository { - synchronized(this) { - return countriesRepository ?: createCountriesRepository() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ApiModule.kt b/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ApiModule.kt new file mode 100644 index 0000000..07f4696 --- /dev/null +++ b/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ApiModule.kt @@ -0,0 +1,75 @@ +package com.carlosjimz87.funwithflags.di.network + +import com.carlosjimz87.funwithflags.network.BASE_URL +import com.carlosjimz87.funwithflags.network.TIMEOUT +import com.carlosjimz87.funwithflags.network.api.CountriesApi +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.components.SingletonComponent +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Converter +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import java.util.concurrent.TimeUnit + +@Module +@InstallIn(SingletonComponent::class) +object ApiModule { + + @Provides + fun providesBaseUrl(): String { + return BASE_URL + } + + @Provides + fun providesLoggingInterceptor(): HttpLoggingInterceptor { + return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) + } + + @Provides + fun provideOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient { + val okHttpClient = OkHttpClient().newBuilder() + + okHttpClient.callTimeout(TIMEOUT, TimeUnit.SECONDS) + okHttpClient.connectTimeout(TIMEOUT, TimeUnit.SECONDS) + okHttpClient.readTimeout(TIMEOUT, TimeUnit.SECONDS) + okHttpClient.writeTimeout(TIMEOUT, TimeUnit.SECONDS) + okHttpClient.addInterceptor(loggingInterceptor) + okHttpClient.build() + return okHttpClient.build() + } + + @Provides + fun provideMoshi(): Moshi { + return Moshi.Builder() + .add(KotlinJsonAdapterFactory()) + .build() + } + + @Provides + fun provideConverterFactory(moshi: Moshi): Converter.Factory { + return MoshiConverterFactory.create(moshi) + } + + @Provides + fun provideRetrofitClient( + okHttpClient: OkHttpClient, + baseUrl: String, + converterFactory: Converter.Factory + ): Retrofit { + return Retrofit.Builder() + .baseUrl(baseUrl) + .client(okHttpClient) + .addConverterFactory(converterFactory) + .build() + } + + @Provides + fun provideCountriesApi(retrofit: Retrofit): CountriesApi { + return retrofit.create(CountriesApi::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ServiceModule.kt b/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ServiceModule.kt new file mode 100644 index 0000000..dbf8b5f --- /dev/null +++ b/app/src/main/java/com/carlosjimz87/funwithflags/di/network/ServiceModule.kt @@ -0,0 +1,17 @@ +package com.carlosjimz87.funwithflags.di.network + +import com.carlosjimz87.funwithflags.network.api.CountriesApi +import com.carlosjimz87.funwithflags.network.services.CountriesServiceImpl +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ActivityRetainedComponent + +@Module +@InstallIn(ActivityRetainedComponent::class) +object ServiceModule { + @Provides + fun providesNetworkService(apiService: CountriesApi): CountriesServiceImpl { + return CountriesServiceImpl(apiService) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/di/repositories/RepositoryModule.kt b/app/src/main/java/com/carlosjimz87/funwithflags/di/repositories/RepositoryModule.kt new file mode 100644 index 0000000..9c29f8a --- /dev/null +++ b/app/src/main/java/com/carlosjimz87/funwithflags/di/repositories/RepositoryModule.kt @@ -0,0 +1,19 @@ +package com.carlosjimz87.funwithflags.di.repositories + +import com.carlosjimz87.funwithflags.network.services.CountriesServiceImpl +import com.carlosjimz87.funwithflags.repositories.CountriesRepository +import com.carlosjimz87.funwithflags.repositories.CountriesRepositoryImpl +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ActivityRetainedComponent + +@Module +@InstallIn(ActivityRetainedComponent::class) +object RepositoryModule { + + @Provides + fun providesRepository(service: CountriesServiceImpl): CountriesRepository { + return CountriesRepositoryImpl(service) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/factory/ViewModelsFactory.kt b/app/src/main/java/com/carlosjimz87/funwithflags/factory/ViewModelsFactory.kt deleted file mode 100644 index e156de3..0000000 --- a/app/src/main/java/com/carlosjimz87/funwithflags/factory/ViewModelsFactory.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.carlosjimz87.funwithflags.factory - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import com.carlosjimz87.funwithflags.App -import com.carlosjimz87.funwithflags.fragments.details.DetailsViewModel -import com.carlosjimz87.funwithflags.fragments.list.ListViewModel - - -class ViewModelsFactory(private val app: App) : - ViewModelProvider.Factory { - - @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(ListViewModel::class.java)) - return ListViewModel(app.countriesRepository) as T - if (modelClass.isAssignableFrom(DetailsViewModel::class.java)) - return DetailsViewModel(app, app.countriesRepository) as T - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsFragment.kt b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsFragment.kt index c96fb22..11e01cc 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsFragment.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsFragment.kt @@ -2,20 +2,12 @@ package com.carlosjimz87.funwithflags.fragments.details import android.content.Intent import android.os.Bundle -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup +import android.view.* import androidx.fragment.app.viewModels import androidx.navigation.fragment.navArgs -import com.carlosjimz87.funwithflags.App import com.carlosjimz87.funwithflags.R import com.carlosjimz87.funwithflags.databinding.DetailsFragmentBinding -import com.carlosjimz87.funwithflags.factory.ViewModelsFactory import com.carlosjimz87.funwithflags.fragments.BaseFragment -import com.carlosjimz87.funwithflags.repositories.CountriesRepositoryImpl import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback @@ -26,11 +18,11 @@ import timber.log.Timber class DetailsFragment : BaseFragment(), OnMapReadyCallback { private var mMap: GoogleMap? = null - private val detailsViewModel by viewModels{ - ViewModelsFactory((requireContext().applicationContext as App)) - } + + private val detailsViewModel: DetailsViewModel by viewModels() private var binding: DetailsFragmentBinding? = null + private val args: DetailsFragmentArgs by navArgs() override fun onCreateView( @@ -45,6 +37,7 @@ class DetailsFragment : BaseFragment(), OnMapReadyCallback { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + val code = args.codeCountry Timber.i("Country ($code) sent to Details") setupViewModel(code) diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsViewModel.kt b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsViewModel.kt index 9e10412..a046421 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsViewModel.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/details/DetailsViewModel.kt @@ -3,6 +3,7 @@ package com.carlosjimz87.funwithflags.fragments.details import android.app.Application import android.content.Context import android.graphics.drawable.Drawable +import androidx.hilt.lifecycle.ViewModelInject import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -14,19 +15,12 @@ import com.carlosjimz87.funwithflags.network.models.CountryDetails import com.carlosjimz87.funwithflags.network.models.CountryProps import com.carlosjimz87.funwithflags.network.models.Currency import com.carlosjimz87.funwithflags.repositories.CountriesRepository -import com.carlosjimz87.funwithflags.repositories.CountriesRepositoryImpl -import com.carlosjimz87.funwithflags.utils.formatCurrency -import com.carlosjimz87.funwithflags.utils.formatPopulation -import com.carlosjimz87.funwithflags.utils.formatShareText -import com.carlosjimz87.funwithflags.utils.formatShareTitle -import com.carlosjimz87.funwithflags.utils.getCompatDrawable -import com.carlosjimz87.funwithflags.utils.handleResponse +import com.carlosjimz87.funwithflags.utils.* import kotlinx.coroutines.launch import timber.log.Timber -class DetailsViewModel( - application: Application, - private val countriesRepository: CountriesRepository = CountriesRepositoryImpl(), +class DetailsViewModel @ViewModelInject constructor( + private val countriesRepository: CountriesRepository, application: Application, ) : AndroidViewModel(application) { private val _status = MutableLiveData() @@ -118,28 +112,37 @@ class DetailsViewModel( private fun getNativeName(context: Context, nativeName: String?): Pair? { return nativeName?.let { - return Pair(first = context.resources.getString(R.string.native_prefix), - second = nativeName) + return Pair( + first = context.resources.getString(R.string.native_prefix), + second = nativeName + ) } } private fun getPopulation(context: Context, population: Long?): Pair? { return population?.let { - return Pair(first = context.resources.getString(R.string.population_prefix), - second = formatPopulation(population, context)) + return Pair( + first = context.resources.getString(R.string.population_prefix), + second = formatPopulation(population, context) + ) } } private fun getTimezones(context: Context, timezones: List): Pair? { - return if (timezones.isNotEmpty()) Pair(context.resources.getString(R.string.timezone_prefix), - "+${timezones[0]}") else null + return if (timezones.isNotEmpty()) Pair( + context.resources.getString(R.string.timezone_prefix), + "+${timezones[0]}" + ) else null } private fun getCallingCodes(context: Context, codes: List): Pair? { - return if (codes.isNotEmpty() && codes[0].isNotEmpty()) Pair(context.resources.getString( - R.string.calling_code_prefix), - "+${codes[0]}") else null + return if (codes.isNotEmpty() && codes[0].isNotEmpty()) Pair( + context.resources.getString( + R.string.calling_code_prefix + ), + "+${codes[0]}" + ) else null } private fun getCurrencies(context: Context, currencies: List): Pair? { diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListFragment.kt b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListFragment.kt index 4a26bdd..8b665da 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListFragment.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListFragment.kt @@ -1,21 +1,15 @@ package com.carlosjimz87.funwithflags.fragments.list import android.os.Bundle -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.view.inputmethod.EditorInfo import androidx.appcompat.widget.SearchView import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.RecyclerView -import com.carlosjimz87.funwithflags.App import com.carlosjimz87.funwithflags.R import com.carlosjimz87.funwithflags.adapters.CountryListAdapter import com.carlosjimz87.funwithflags.databinding.ListFragmentBinding -import com.carlosjimz87.funwithflags.factory.ViewModelsFactory import com.carlosjimz87.funwithflags.fragments.BaseFragment import com.carlosjimz87.funwithflags.utils.addDividerShape import timber.log.Timber @@ -26,9 +20,7 @@ class ListFragment : BaseFragment() { private var countryListAdapter: CountryListAdapter? = null - private val listViewModel by viewModels { - ViewModelsFactory((requireContext().applicationContext as App)) - } + private val listViewModel: ListViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListViewModel.kt b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListViewModel.kt index e11182e..73109fd 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListViewModel.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/fragments/list/ListViewModel.kt @@ -1,5 +1,6 @@ package com.carlosjimz87.funwithflags.fragments.list +import androidx.hilt.lifecycle.ViewModelInject import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -7,13 +8,13 @@ import androidx.lifecycle.viewModelScope import com.carlosjimz87.funwithflags.fragments.CountriesApiStatus import com.carlosjimz87.funwithflags.network.models.Country import com.carlosjimz87.funwithflags.repositories.CountriesRepository -import com.carlosjimz87.funwithflags.repositories.CountriesRepositoryImpl import com.carlosjimz87.funwithflags.utils.handleResponse +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import timber.log.Timber -class ListViewModel( - private val countriesRepository: CountriesRepository = CountriesRepositoryImpl(), +class ListViewModel @ViewModelInject constructor( + private val countriesRepository: CountriesRepository, ) : ViewModel() { private val _status = MutableLiveData() val status: LiveData = _status diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/network/Endpoints.kt b/app/src/main/java/com/carlosjimz87/funwithflags/network/Endpoints.kt index 73891bc..c58f44a 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/network/Endpoints.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/network/Endpoints.kt @@ -2,6 +2,7 @@ package com.carlosjimz87.funwithflags.network const val BASE_URL = "https://restcountries.eu/" +const val TIMEOUT = 40L object Endpoints { const val GET_ALL_COUNTRIES = "all/" diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/network/api/CountriesApi.kt b/app/src/main/java/com/carlosjimz87/funwithflags/network/api/CountriesApi.kt index cd38bc2..b7968aa 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/network/api/CountriesApi.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/network/api/CountriesApi.kt @@ -1,29 +1,24 @@ package com.carlosjimz87.funwithflags.network.api -import com.carlosjimz87.funwithflags.network.BASE_URL import com.carlosjimz87.funwithflags.network.Endpoints import com.carlosjimz87.funwithflags.network.models.Country import com.carlosjimz87.funwithflags.network.models.CountryDetails -import com.squareup.moshi.Moshi -import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory -import retrofit2.Retrofit -import retrofit2.converter.moshi.MoshiConverterFactory import retrofit2.http.GET import retrofit2.http.Path private const val api_type = "rest" private const val api_version = "v2" - -private val moshi = Moshi.Builder() - .add(KotlinJsonAdapterFactory()) - .build() - - -private val retrofit = Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .baseUrl(BASE_URL) - .client(LoggerInterceptorClient) - .build() +// +//private val moshi = Moshi.Builder() +// .add(KotlinJsonAdapterFactory()) +// .build() +// +// +//private val retrofit = Retrofit.Builder() +// .addConverterFactory(MoshiConverterFactory.create(moshi)) +// .baseUrl(BASE_URL) +// .client(LoggerInterceptorClient) +// .build() interface CountriesApi { @GET("$api_type/$api_version/${Endpoints.GET_ALL_COUNTRIES}") @@ -33,8 +28,8 @@ interface CountriesApi { suspend fun getCountryDetails(@Path(value = "country_code") countryId: String): CountryDetails } -object ApiManager { - val retrofitService: CountriesApi by lazy { - retrofit.create(CountriesApi::class.java) - } -} \ No newline at end of file +//object ApiManager { +// val retrofitService: CountriesApi by lazy { +// retrofit.create(CountriesApi::class.java) +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/network/services/CountriesServiceImpl.kt b/app/src/main/java/com/carlosjimz87/funwithflags/network/services/CountriesServiceImpl.kt index 07a1bef..7b18f59 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/network/services/CountriesServiceImpl.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/network/services/CountriesServiceImpl.kt @@ -5,8 +5,9 @@ import com.carlosjimz87.funwithflags.network.models.CountryDetails import com.carlosjimz87.funwithflags.network.models.Country import com.carlosjimz87.funwithflags.network.responses.ObserverResponse import kotlinx.coroutines.Dispatchers +import javax.inject.Inject -open class CountriesServiceImpl(private val api: CountriesApi) : BaseService { +open class CountriesServiceImpl @Inject constructor(private val api: CountriesApi) : BaseService { suspend fun getAllCountries(): ObserverResponse> { return apiCall(Dispatchers.IO) { api.getAllCountries() diff --git a/app/src/main/java/com/carlosjimz87/funwithflags/repositories/CountriesRepositoryImpl.kt b/app/src/main/java/com/carlosjimz87/funwithflags/repositories/CountriesRepositoryImpl.kt index 5a5f36e..192956b 100644 --- a/app/src/main/java/com/carlosjimz87/funwithflags/repositories/CountriesRepositoryImpl.kt +++ b/app/src/main/java/com/carlosjimz87/funwithflags/repositories/CountriesRepositoryImpl.kt @@ -1,15 +1,13 @@ package com.carlosjimz87.funwithflags.repositories -import com.carlosjimz87.funwithflags.network.api.ApiManager -import com.carlosjimz87.funwithflags.network.models.CountryDetails import com.carlosjimz87.funwithflags.network.models.Country +import com.carlosjimz87.funwithflags.network.models.CountryDetails import com.carlosjimz87.funwithflags.network.responses.ObserverResponse import com.carlosjimz87.funwithflags.network.services.CountriesServiceImpl -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers +import javax.inject.Inject -open class CountriesRepositoryImpl( - private val service: CountriesServiceImpl = CountriesServiceImpl(ApiManager.retrofitService), +open class CountriesRepositoryImpl @Inject constructor( + private val service: CountriesServiceImpl ) : CountriesRepository { override suspend fun getAllCountries(): ObserverResponse> { return service.getAllCountries() diff --git a/build.gradle b/build.gradle index ded0d57..901e033 100644 --- a/build.gradle +++ b/build.gradle @@ -2,33 +2,35 @@ buildscript { ext { gradle_plugin_version = "1.5.10" - core_ktx_version = "1.5.0" + core_ktx_version = '1.6.0' appcompat_version = "1.3.0" - material_version = "1.3.0" + material_version = '1.4.0' constraint_version = "2.0.4" legacy_support_version = "1.0.0" lifecycle_version = "2.3.1" nav_version = "2.3.5" retrofit_version = '2.9.0' moshi_version = "1.12.0" - coil_version = "1.2.2" + coil_version = '1.3.0' timber_version = "4.7.1" + hilt_version = "2.37" + hilt_extensions_version = "1.0.0-alpha01" okhttp_version = "5.0.0-alpha.2" fast_scroller_version = "0.1.3" - lottie_version = "3.7.0" + lottie_version = '3.7.1' gms_version = "17.0.1" // Testing junit_version = '4.13.2' rules_version = '1.4.0' hamcrest_version = '1.3' test_core_ktx_version = '1.3.0' - mockito_version = "3.6.0" + mockito_version = '3.11.2' arch_test_version = "1.1.1" - espresso_version = "3.3.0" - robolectricVersion = "4.5.1" - coroutines_version = '1.5.0' + espresso_version = '3.4.0' + robolectricVersion = '4.6.1' + coroutines_version = '1.5.1-native-mt' androidx_test_core_version = '1.4.0' - androidx_test_kotlin_runner_version = '1.1.2' + androidx_test_kotlin_runner_version = '1.1.3' } repositories { @@ -39,6 +41,7 @@ buildscript { classpath "com.android.tools.build:gradle:4.2.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$gradle_plugin_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" + classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" // NOTE: Do not place your application dependencies here; they belong