From 65c6f4fff1f2b2bd73dbaf859cc1569ff2976436 Mon Sep 17 00:00:00 2001 From: AdityaGaikwad Date: Mon, 6 May 2024 20:59:43 +0530 Subject: [PATCH] Networking setup mvvm setup for onboard live data implementation --- .idea/deploymentTargetDropDown.xml | 13 ++++- app/build.gradle | 22 ++++++++ .../java/com/woka/networking/ApiResponse.kt | 10 ++++ .../java/com/woka/networking/ApiResult.kt | 9 ++++ .../com/woka/networking/RetrofitHelper.kt | 53 +++++++++++++++++++ .../onboard/fragments/LanguageFragment.kt | 7 ++- .../com/woka/onboard/models/LoginResponse.kt | 4 ++ .../java/com/woka/onboard/models/Result.kt | 6 +++ .../woka/onboard/mvvm/OnboardApiService.kt | 14 +++++ .../woka/onboard/mvvm/OnboardRepository.kt | 27 ++++++++++ .../com/woka/onboard/mvvm/OnboardViewModel.kt | 28 ++++++++++ .../com/woka/userPreference/UserPreference.kt | 5 ++ .../main/java/com/woka/utils/ProgressView.kt | 33 ++++++++++++ app/src/main/res/drawable/round_25.xml | 10 ++++ .../main/res/layout/layout_progress_view.xml | 33 ++++++++++++ app/src/main/res/values/strings.xml | 1 + gradle.properties | 8 ++- 17 files changed, 277 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/woka/networking/ApiResponse.kt create mode 100644 app/src/main/java/com/woka/networking/ApiResult.kt create mode 100644 app/src/main/java/com/woka/networking/RetrofitHelper.kt create mode 100644 app/src/main/java/com/woka/onboard/models/LoginResponse.kt create mode 100644 app/src/main/java/com/woka/onboard/models/Result.kt create mode 100644 app/src/main/java/com/woka/onboard/mvvm/OnboardApiService.kt create mode 100644 app/src/main/java/com/woka/onboard/mvvm/OnboardRepository.kt create mode 100644 app/src/main/java/com/woka/onboard/mvvm/OnboardViewModel.kt create mode 100644 app/src/main/java/com/woka/utils/ProgressView.kt create mode 100644 app/src/main/res/drawable/round_25.xml create mode 100644 app/src/main/res/layout/layout_progress_view.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 316d309..37242e7 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -15,7 +15,18 @@ - + + + + + + + + + + + + diff --git a/app/build.gradle b/app/build.gradle index 5ab3ae7..59bfdc3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,9 +19,19 @@ android { buildTypes { release { + buildConfigField "String", "WOKA_STAGINNG_BASE_URL", WOKA_STAGINNG_BASE_URL + buildConfigField "String", "WOKA_USER_NAME", WOKA_USER_NAME + buildConfigField "String", "WOKA_PASSWORD", WOKA_PASSWORD + minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } + + debug{ + buildConfigField "String", "WOKA_STAGINNG_BASE_URL", WOKA_STAGINNG_BASE_URL + buildConfigField "String", "WOKA_USER_NAME", WOKA_USER_NAME + buildConfigField "String", "WOKA_PASSWORD", WOKA_PASSWORD + } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -33,6 +43,7 @@ android { buildFeatures{ viewBinding true + buildConfig true } } @@ -49,6 +60,17 @@ dependencies { // dynamic sizes implementation 'com.intuit.sdp:sdp-android:1.1.1' + // retrofit + def retrofit_version = "2.11.0" + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") + + def lifecycle_version = "2.7.0" + // ViewModel + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" + implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version") + implementation libs.androidx.core.ktx implementation libs.androidx.appcompat implementation libs.material diff --git a/app/src/main/java/com/woka/networking/ApiResponse.kt b/app/src/main/java/com/woka/networking/ApiResponse.kt new file mode 100644 index 0000000..f9cb78a --- /dev/null +++ b/app/src/main/java/com/woka/networking/ApiResponse.kt @@ -0,0 +1,10 @@ +package com.woka.networking + +/* + This is the basic structure of api response + */ +data class ApiResponse( + val success: Int? = null, + val message: String? = null, + val data: T? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/woka/networking/ApiResult.kt b/app/src/main/java/com/woka/networking/ApiResult.kt new file mode 100644 index 0000000..0b92cc6 --- /dev/null +++ b/app/src/main/java/com/woka/networking/ApiResult.kt @@ -0,0 +1,9 @@ +package com.woka.networking + +sealed class ApiResult(data: T? = null, errorMessage: String? = null) { + + class Loading: ApiResult() + class Success(data: T? = null): ApiResult(data) + class Error(errorMessage: String? = null): ApiResult(errorMessage = errorMessage) + +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/networking/RetrofitHelper.kt b/app/src/main/java/com/woka/networking/RetrofitHelper.kt new file mode 100644 index 0000000..5318cc7 --- /dev/null +++ b/app/src/main/java/com/woka/networking/RetrofitHelper.kt @@ -0,0 +1,53 @@ +package com.woka.networking + +import android.annotation.SuppressLint +import android.content.Context +import android.provider.Settings +import com.woka.BuildConfig +import com.woka.WokaApp.Companion.userPrefs +import okhttp3.Credentials +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object RetrofitHelper { + + private var retrofit: Retrofit? = null + + @SuppressLint("HardwareIds") + private fun createRetrofit(): Retrofit{ + val clientBuilder = OkHttpClient.Builder() + + if (BuildConfig.DEBUG){ + clientBuilder.addInterceptor(HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + }) + } + + // adding static headers for api calls + clientBuilder.addInterceptor( + Interceptor { chain -> + val request = chain.request().newBuilder() + + request.addHeader("Accept-Language", if (userPrefs?.appLanguage == "hi") "Hindi" else "English") + request.addHeader("device-id", userPrefs?.deviceId!!) + request.addHeader("Authorization", Credentials.basic(BuildConfig.WOKA_USER_NAME, BuildConfig.WOKA_PASSWORD)) + + chain.proceed(request.build()) + }) + + retrofit = Retrofit.Builder() + .baseUrl(BuildConfig.WOKA_STAGINNG_BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .client(clientBuilder.build()) + .build() + + return retrofit!! + } + + fun getRetrofit(): Retrofit{ + return retrofit ?: createRetrofit() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/onboard/fragments/LanguageFragment.kt b/app/src/main/java/com/woka/onboard/fragments/LanguageFragment.kt index a388fc5..33cbf0d 100644 --- a/app/src/main/java/com/woka/onboard/fragments/LanguageFragment.kt +++ b/app/src/main/java/com/woka/onboard/fragments/LanguageFragment.kt @@ -8,16 +8,15 @@ import android.view.View import android.view.ViewGroup import androidx.core.app.ActivityOptionsCompat import androidx.fragment.app.Fragment -import androidx.navigation.fragment.FragmentNavigatorExtras -import androidx.navigation.fragment.findNavController -import com.woka.R import com.woka.databinding.FragmentLanguageBinding import com.woka.onboard.OnboardActivity +import com.woka.utils.ProgressView import com.woka.utils.changeLocale class LanguageFragment : Fragment() { private lateinit var binding: FragmentLanguageBinding + private lateinit var progressView: ProgressView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -29,12 +28,12 @@ class LanguageFragment : Fragment() { savedInstanceState: Bundle? ): View? { binding = FragmentLanguageBinding.inflate(inflater, container, false) + progressView = ProgressView(requireContext(), "please wait...") return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - clickEvents() } diff --git a/app/src/main/java/com/woka/onboard/models/LoginResponse.kt b/app/src/main/java/com/woka/onboard/models/LoginResponse.kt new file mode 100644 index 0000000..a15c35a --- /dev/null +++ b/app/src/main/java/com/woka/onboard/models/LoginResponse.kt @@ -0,0 +1,4 @@ +package com.woka.onboard.models +data class LoginResponse( + val result: Result +) \ No newline at end of file diff --git a/app/src/main/java/com/woka/onboard/models/Result.kt b/app/src/main/java/com/woka/onboard/models/Result.kt new file mode 100644 index 0000000..f900c1f --- /dev/null +++ b/app/src/main/java/com/woka/onboard/models/Result.kt @@ -0,0 +1,6 @@ +package com.woka.onboard.models + +data class Result( + val already_logged_in: Boolean, + val is_deactive: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/woka/onboard/mvvm/OnboardApiService.kt b/app/src/main/java/com/woka/onboard/mvvm/OnboardApiService.kt new file mode 100644 index 0000000..b9d0200 --- /dev/null +++ b/app/src/main/java/com/woka/onboard/mvvm/OnboardApiService.kt @@ -0,0 +1,14 @@ +package com.woka.onboard.mvvm + +import com.woka.networking.ApiResponse +import com.woka.onboard.models.LoginResponse +import okhttp3.FormBody +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET + +interface OnboardApiService { + + @GET("login") + suspend fun login(@Body body: FormBody): Response> +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/onboard/mvvm/OnboardRepository.kt b/app/src/main/java/com/woka/onboard/mvvm/OnboardRepository.kt new file mode 100644 index 0000000..55c9b63 --- /dev/null +++ b/app/src/main/java/com/woka/onboard/mvvm/OnboardRepository.kt @@ -0,0 +1,27 @@ +package com.woka.onboard.mvvm + +import com.woka.networking.ApiResult +import com.woka.onboard.models.LoginResponse +import okhttp3.FormBody + +class OnboardRepository(private val apiService: OnboardApiService) { + + suspend fun login(userName: String, password: String): ApiResult { + return try { + val response = apiService.login( + FormBody.Builder() + .add("username", userName) + .add("password", password) + .build() + ) + + if (response.body()?.success == 1) + ApiResult.Success(response.body()?.data) + else + ApiResult.Error(errorMessage = response.body()?.message) + } catch (e: Exception) { + ApiResult.Error(errorMessage = e.message) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/onboard/mvvm/OnboardViewModel.kt b/app/src/main/java/com/woka/onboard/mvvm/OnboardViewModel.kt new file mode 100644 index 0000000..877e274 --- /dev/null +++ b/app/src/main/java/com/woka/onboard/mvvm/OnboardViewModel.kt @@ -0,0 +1,28 @@ +package com.woka.onboard.mvvm + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.woka.networking.ApiResult +import com.woka.networking.RetrofitHelper +import com.woka.onboard.models.LoginResponse +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class OnboardViewModel: ViewModel(){ + + private val repository: OnboardRepository = OnboardRepository(RetrofitHelper.getRetrofit().create(OnboardApiService::class.java)) + + private val _signInLiveData = MutableLiveData>() + val signInLiveData: LiveData> + get() = _signInLiveData + + fun login(userName: String, password: String){ + viewModelScope.launch { + _signInLiveData.postValue(ApiResult.Loading()) + delay(6000) + _signInLiveData.postValue(ApiResult.Success()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/userPreference/UserPreference.kt b/app/src/main/java/com/woka/userPreference/UserPreference.kt index b7931fe..263edd1 100644 --- a/app/src/main/java/com/woka/userPreference/UserPreference.kt +++ b/app/src/main/java/com/woka/userPreference/UserPreference.kt @@ -1,8 +1,11 @@ package com.woka.userPreference +import android.annotation.SuppressLint import android.content.Context import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences +import android.provider.Settings +import android.provider.Settings.Secure class UserPreference(context: Context) { @@ -12,6 +15,8 @@ class UserPreference(context: Context) { } private val userPrefs: SharedPreferences = context.getSharedPreferences(USER_PREFERENCE, MODE_PRIVATE) + @SuppressLint("HardwareIds") + val deviceId: String = Secure.getString(context.contentResolver, Secure.ANDROID_ID) var appLanguage: String get() = userPrefs.getString(APP_LANGUAGE, "en")?:"en" diff --git a/app/src/main/java/com/woka/utils/ProgressView.kt b/app/src/main/java/com/woka/utils/ProgressView.kt new file mode 100644 index 0000000..9929bc5 --- /dev/null +++ b/app/src/main/java/com/woka/utils/ProgressView.kt @@ -0,0 +1,33 @@ +package com.woka.utils + +import android.app.Dialog +import android.content.Context +import android.content.ContextWrapper +import android.view.LayoutInflater +import com.woka.databinding.LayoutProgressViewBinding + +class ProgressView(context: Context, title: String): ContextWrapper(context) { + + private val dialog: Dialog = Dialog(this) + private var binding: LayoutProgressViewBinding = LayoutProgressViewBinding.inflate(LayoutInflater.from(this)) + + init { + // init dialog + dialog.setContentView(binding.root) + dialog.setCancelable(false) + // transparent background + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) + + // init views + binding.title.text = title + } + + fun show() = dialog.show() + + fun hide() = dialog.dismiss() + + fun setTitle(title: String) { + binding.title.text = title + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable/round_25.xml b/app/src/main/res/drawable/round_25.xml new file mode 100644 index 0000000..a7fcb2c --- /dev/null +++ b/app/src/main/res/drawable/round_25.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_progress_view.xml b/app/src/main/res/layout/layout_progress_view.xml new file mode 100644 index 0000000..85bf585 --- /dev/null +++ b/app/src/main/res/layout/layout_progress_view.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86624c4..08a459a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -68,4 +68,5 @@ RESET PASSWORD back_btn Enter your password + Please wait... \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 20e2a01..50cce35 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,10 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true + + +# BASE URLS +WOKA_STAGINNG_BASE_URL="https://wokaland.com/admin/api/" +WOKA_USER_NAME="admin" +WOKA_PASSWORD="Woka@1234" \ No newline at end of file