diff --git a/app/build.gradle b/app/build.gradle index f3b6630..364a4d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -65,6 +65,8 @@ dependencies { implementation "androidx.preference:preference-ktx:1.1.1" + implementation 'com.jakewharton.timber:timber:5.0.1' + testImplementation "junit:junit:4.13.2" androidTestImplementation "androidx.test.ext:junit:1.1.3" diff --git a/app/src/main/java/gq/kirmanak/mealie/MainActivity.kt b/app/src/main/java/gq/kirmanak/mealie/MainActivity.kt index 8127803..0be5194 100644 --- a/app/src/main/java/gq/kirmanak/mealie/MainActivity.kt +++ b/app/src/main/java/gq/kirmanak/mealie/MainActivity.kt @@ -4,11 +4,13 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealie.databinding.MainActivityBinding +import timber.log.Timber @AndroidEntryPoint class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + Timber.v("onCreate() called with: savedInstanceState = $savedInstanceState") val binding = MainActivityBinding.inflate(layoutInflater) setContentView(binding.root) } diff --git a/app/src/main/java/gq/kirmanak/mealie/MealieApp.kt b/app/src/main/java/gq/kirmanak/mealie/MealieApp.kt index efcfabe..1aaeb06 100644 --- a/app/src/main/java/gq/kirmanak/mealie/MealieApp.kt +++ b/app/src/main/java/gq/kirmanak/mealie/MealieApp.kt @@ -2,6 +2,13 @@ package gq.kirmanak.mealie import android.app.Application import dagger.hilt.android.HiltAndroidApp +import timber.log.Timber @HiltAndroidApp -class MealieApp : Application() \ No newline at end of file +class MealieApp : Application() { + override fun onCreate() { + super.onCreate() + if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) + Timber.v("onCreate() called") + } +} \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealie/data/RetrofitBuilder.kt b/app/src/main/java/gq/kirmanak/mealie/data/RetrofitBuilder.kt index ab0ec63..72d772b 100644 --- a/app/src/main/java/gq/kirmanak/mealie/data/RetrofitBuilder.kt +++ b/app/src/main/java/gq/kirmanak/mealie/data/RetrofitBuilder.kt @@ -5,11 +5,13 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import okhttp3.MediaType import retrofit2.Retrofit +import timber.log.Timber import javax.inject.Inject @ExperimentalSerializationApi class RetrofitBuilder @Inject constructor() { fun buildRetrofit(baseUrl: String): Retrofit { + Timber.v("buildRetrofit() called with: baseUrl = $baseUrl") val url = if (baseUrl.startsWith("http")) baseUrl else "https://$baseUrl" val contentType = MediaType.get("application/json") return Retrofit.Builder() diff --git a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthDataSourceImpl.kt index f8f4712..f64ab4b 100644 --- a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthDataSourceImpl.kt @@ -3,6 +3,7 @@ package gq.kirmanak.mealie.data.auth import gq.kirmanak.mealie.data.RetrofitBuilder import kotlinx.serialization.ExperimentalSerializationApi import retrofit2.create +import timber.log.Timber import javax.inject.Inject @ExperimentalSerializationApi @@ -14,12 +15,15 @@ class AuthDataSourceImpl @Inject constructor( password: String, baseUrl: String ): Result { + Timber.v("authenticate() called with: username = $username, password = $password, baseUrl = $baseUrl") val authService = retrofitBuilder.buildRetrofit(baseUrl).create() val response = try { authService.getToken(username, password) } catch (e: Exception) { + Timber.e("Authenticate() exception", e) return Result.failure(e) } + Timber.d("authenticate() response is $response") return Result.success(response.accessToken) } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthRepoImpl.kt b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthRepoImpl.kt index cf5b3e4..8f0a383 100644 --- a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthRepoImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthRepoImpl.kt @@ -1,19 +1,27 @@ package gq.kirmanak.mealie.data.auth +import timber.log.Timber import javax.inject.Inject class AuthRepoImpl @Inject constructor( private val dataSource: AuthDataSource, private val storage: AuthStorage ) : AuthRepo { - override suspend fun isAuthenticated(): Boolean = storage.isAuthenticated() + override suspend fun isAuthenticated(): Boolean { + Timber.v("isAuthenticated") + val authenticated = storage.isAuthenticated() + Timber.d("isAuthenticated() response $authenticated") + return authenticated + } override suspend fun authenticate( username: String, password: String, baseUrl: String ): Throwable? { + Timber.v("authenticate() called with: username = $username, password = $password, baseUrl = $baseUrl") val authResult = dataSource.authenticate(username, password, baseUrl) + Timber.d("authenticate result is $authResult") if (authResult.isFailure) return authResult.exceptionOrNull() val token = checkNotNull(authResult.getOrNull()) storage.storeToken(token) diff --git a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthStorageImpl.kt b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthStorageImpl.kt index 666eed0..2b51fdc 100644 --- a/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthStorageImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealie/data/auth/AuthStorageImpl.kt @@ -6,6 +6,7 @@ import androidx.preference.PreferenceManager import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import timber.log.Timber import javax.inject.Inject private const val TOKEN_KEY = "AUTH_TOKEN" @@ -15,10 +16,14 @@ class AuthStorageImpl @Inject constructor(@ApplicationContext private val contex get() = PreferenceManager.getDefaultSharedPreferences(context) override suspend fun isAuthenticated(): Boolean = withContext(Dispatchers.IO) { - sharedPreferences.getString(TOKEN_KEY, null) != null + Timber.v("isAuthenticated() called") + val token = sharedPreferences.getString(TOKEN_KEY, null) + Timber.d("isAuthenticated: token is $token") + token != null } override suspend fun storeToken(token: String) { + Timber.d("storeToken() called with: token = $token") sharedPreferences.edit().putString(TOKEN_KEY, token).apply() } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationFragment.kt b/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationFragment.kt index b0d010a..ebf1c57 100644 --- a/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationFragment.kt @@ -1,7 +1,6 @@ package gq.kirmanak.mealie.ui.auth import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -13,6 +12,7 @@ import androidx.lifecycle.lifecycleScope import com.google.android.material.textfield.TextInputLayout import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealie.databinding.FragmentAuthenticationBinding +import timber.log.Timber private const val TAG = "AuthenticationFragment" @@ -25,6 +25,7 @@ class AuthenticationFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + Timber.v("onCreate() called with: savedInstanceState = $savedInstanceState") checkIfAuthenticatedAlready() } @@ -33,18 +34,19 @@ class AuthenticationFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { + Timber.v("onCreateView() called with: inflater = $inflater, container = $container, savedInstanceState = $savedInstanceState") _binding = FragmentAuthenticationBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.button.setOnClickListener { - onLoginClicked() - } + Timber.v("onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState") + binding.button.setOnClickListener { onLoginClicked() } } private fun checkIfAuthenticatedAlready() { + Timber.v("checkIfAuthenticatedAlready() called") lifecycleScope.launchWhenCreated { Toast.makeText( requireContext(), @@ -56,6 +58,7 @@ class AuthenticationFragment : Fragment() { } private fun onLoginClicked() { + Timber.v("onLoginClicked() called") val email: String val pass: String val url: String @@ -72,7 +75,6 @@ class AuthenticationFragment : Fragment() { } lifecycleScope.launchWhenResumed { val exception = viewModel.authenticate(email, pass, url) - Log.e(TAG, "onLoginClicked: ", exception) Toast.makeText( requireContext(), "Exception is ${exception?.message ?: "null"}", @@ -86,7 +88,9 @@ class AuthenticationFragment : Fragment() { inputLayout: TextInputLayout, errorText: () -> String ): String? { + Timber.v("checkIfInputIsEmpty() called with: input = " + input + ", inputLayout = " + inputLayout + ", errorText = " + errorText) val text = input.text?.toString() + Timber.d("Input text is \"$text\"") if (text.isNullOrBlank()) { inputLayout.error = errorText() return null @@ -96,6 +100,7 @@ class AuthenticationFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() + Timber.v("onDestroyView() called") _binding = null } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationViewModel.kt b/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationViewModel.kt index c19fec8..df457f0 100644 --- a/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationViewModel.kt +++ b/app/src/main/java/gq/kirmanak/mealie/ui/auth/AuthenticationViewModel.kt @@ -3,15 +3,29 @@ package gq.kirmanak.mealie.ui.auth import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel import gq.kirmanak.mealie.data.auth.AuthRepo +import timber.log.Timber import javax.inject.Inject @HiltViewModel class AuthenticationViewModel @Inject constructor( private val authRepo: AuthRepo ) : ViewModel() { - suspend fun isAuthenticated(): Boolean = authRepo.isAuthenticated() + init { + Timber.v("constructor called") + } + + suspend fun isAuthenticated(): Boolean { + Timber.v("isAuthenticated() called") + val result = authRepo.isAuthenticated() + Timber.d("isAuthenticated() returned: $result") + return result + } suspend fun authenticate(username: String, password: String, baseUrl: String): Throwable? { - return authRepo.authenticate(username, password, baseUrl) + Timber.v("authenticate() called with: username = $username, password = $password, baseUrl = $baseUrl") + val result = authRepo.authenticate(username, password, baseUrl) + if (result == null) Timber.d("authenticate() returns null") + else Timber.e("authenticate() returns error", result) + return result } } \ No newline at end of file