Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -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/[email protected]

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
13 changes: 1 addition & 12 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id 'kotlin-android'
id 'kotlin-kapt'
id 'androidx.navigation.safeargs'
id 'dagger.hilt.android.plugin'
}

android {
Expand Down Expand Up @@ -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"
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/com/carlosjimz87/funwithflags/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 0 additions & 25 deletions app/src/main/java/com/carlosjimz87/funwithflags/ServiceLocator.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -26,11 +18,11 @@ import timber.log.Timber

class DetailsFragment : BaseFragment(), OnMapReadyCallback {
private var mMap: GoogleMap? = null
private val detailsViewModel by viewModels<DetailsViewModel>{
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(
Expand All @@ -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)
Expand Down
Loading