diff --git a/app/build.gradle b/app/build.gradle index e515992..0ba705f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,9 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' + id 'com.google.devtools.ksp' + id 'com.google.dagger.hilt.android' + id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' } android { @@ -30,6 +33,9 @@ android { kotlinOptions { jvmTarget = '17' } + buildFeatures{ + buildConfig = true + } } dependencies { @@ -38,7 +44,20 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.constraintlayout:constraintlayout:2.2.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7' + implementation 'androidx.fragment:fragment-ktx:1.8.5' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7' + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' + implementation "com.squareup.retrofit2:retrofit:2.9.0" + implementation "com.squareup.retrofit2:converter-gson:2.9.0" + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' + + implementation "com.google.dagger:hilt-android:2.53" + ksp "com.google.dagger:hilt-compiler:2.53" } \ No newline at end of file diff --git a/app/src/androidTest/java/ru/otus/basicarchitecture/ExampleInstrumentedTest.kt b/app/src/androidTest/java/ru/otus/basicarchitecture/ExampleInstrumentedTest.kt deleted file mode 100644 index a987f13..0000000 --- a/app/src/androidTest/java/ru/otus/basicarchitecture/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package ru.otus.basicarchitecture - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("ru.otus.basicarchitecture", appContext.packageName) - } -} \ No newline at end of file diff --git a/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/AddressViewModelTest.kt b/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/AddressViewModelTest.kt new file mode 100644 index 0000000..bf30d59 --- /dev/null +++ b/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/AddressViewModelTest.kt @@ -0,0 +1,12 @@ +package ru.otus.basicarchitecture.presentation + +import org.junit.Assert.* + +import org.junit.Test + +class AddressViewModelTest { + + @Test + fun loadSuggestions() { + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/PersonalDataViewModelTest.kt b/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/PersonalDataViewModelTest.kt new file mode 100644 index 0000000..b284190 --- /dev/null +++ b/app/src/androidTest/java/ru/otus/basicarchitecture/presentation/PersonalDataViewModelTest.kt @@ -0,0 +1,5 @@ +package ru.otus.basicarchitecture.presentation + +import org.junit.Assert.* + +class PersonalDataViewModelTest \ No newline at end of file diff --git a/app/src/androidTest/java/utils/RxRule.kt b/app/src/androidTest/java/utils/RxRule.kt new file mode 100644 index 0000000..aed64e0 --- /dev/null +++ b/app/src/androidTest/java/utils/RxRule.kt @@ -0,0 +1,4 @@ +package utils + +class RxRule { +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ea17fa5..22e5df3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,10 @@ + + + val request = chain.request().newBuilder() + .addHeader("Authorization", "Token $AUTH_KEY") + .build() + chain.proceed(request) + } + + private val client: OkHttpClient = OkHttpClient.Builder() + .addInterceptor(headerInterceptor) + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build() + + + @get:Provides + val api: AddressApi = Retrofit.Builder() + .baseUrl(BASE_URL) + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(AddressApi::class.java) +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/basicarchitecture/data/TagsList.kt b/app/src/main/java/ru/otus/basicarchitecture/data/TagsList.kt new file mode 100644 index 0000000..0715cb2 --- /dev/null +++ b/app/src/main/java/ru/otus/basicarchitecture/data/TagsList.kt @@ -0,0 +1,14 @@ +package ru.otus.basicarchitecture.data + +import javax.inject.Inject +class TagsList @Inject constructor() { + val interests = listOf( + "Board games", + "Computer games", + "Hiking", + "Bird watching", + "DIY", + "Reading", + "Parties" + ) +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/basicarchitecture/data/WizardCache.kt b/app/src/main/java/ru/otus/basicarchitecture/data/WizardCache.kt new file mode 100644 index 0000000..6484e0a --- /dev/null +++ b/app/src/main/java/ru/otus/basicarchitecture/data/WizardCache.kt @@ -0,0 +1,15 @@ +package ru.otus.basicarchitecture.data + +import dagger.hilt.android.scopes.ActivityRetainedScoped +import javax.inject.Inject + +@ActivityRetainedScoped +class WizardCache @Inject constructor() { + var name: String = "" + var surname: String = "" + var birthDate: Long = 0 + var city: String = "" + var country: String = "" + var address: String = "" + var interests: List = listOf() +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/basicarchitecture/model/Address.kt b/app/src/main/java/ru/otus/basicarchitecture/model/Address.kt new file mode 100644 index 0000000..e55bb57 --- /dev/null +++ b/app/src/main/java/ru/otus/basicarchitecture/model/Address.kt @@ -0,0 +1,5 @@ +package ru.otus.basicarchitecture.model + +data class AddressSuggestionRequest(val query: String) +data class DadataResponse(val suggestions: List) +data class AddressSuggestion(val value: String) diff --git a/app/src/main/java/ru/otus/basicarchitecture/presentation/AddressFragment.kt b/app/src/main/java/ru/otus/basicarchitecture/presentation/AddressFragment.kt new file mode 100644 index 0000000..d98c8dc --- /dev/null +++ b/app/src/main/java/ru/otus/basicarchitecture/presentation/AddressFragment.kt @@ -0,0 +1,75 @@ +package ru.otus.basicarchitecture.presentation + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.Button +import androidx.fragment.app.Fragment +import com.google.android.material.textfield.MaterialAutoCompleteTextView +import dagger.hilt.android.AndroidEntryPoint +import ru.otus.basicarchitecture.R +import javax.inject.Inject + +@AndroidEntryPoint +class AddressFragment : Fragment() { + + @Inject + lateinit var viewModel: AddressViewModel + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_address, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + view.findViewById(R.id.address) + .addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + viewModel.loadSuggestions(s.toString()) + viewModel.address.value = s.toString() + } + + override fun beforeTextChanged( + s: CharSequence?, + start: Int, + count: Int, + after: Int + ) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + }) + + viewModel.addressSuggestions.observe(viewLifecycleOwner) { suggestions -> + val adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_dropdown_item_1line, + suggestions + ) + val address = view.findViewById(R.id.address) + address.setAdapter(adapter) + + if (suggestions.isNotEmpty()) { + address.showDropDown() + } + } + + view.findViewById