This commit is contained in:
Erik Cavazos 2023-09-09 16:09:22 -06:00
parent 3c146ee603
commit 761a076e52
8 changed files with 64 additions and 11 deletions

View File

@ -18,7 +18,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.isolaatti" applicationId "com.isolaatti"
minSdk 23 minSdk 24
targetSdk 33 targetSdk 33
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:name=".MyApplication" android:name=".MyApplication"
android:allowBackup="true" android:allowBackup="true"

View File

@ -1,29 +1,26 @@
package com.isolaatti package com.isolaatti
import android.app.Activity
import android.app.Application import android.app.Application
import android.os.Bundle import android.net.ConnectivityManager
import com.isolaatti.auth.data.AuthRepositoryImpl import com.isolaatti.connectivity.ConnectivityCallbackImpl
import com.isolaatti.auth.data.local.TokenStorage
import com.isolaatti.auth.data.remote.AuthApi
import com.isolaatti.auth.domain.AuthRepository
import com.isolaatti.connectivity.RetrofitClient
import dagger.Provides
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import javax.inject.Singleton
@HiltAndroidApp @HiltAndroidApp
class MyApplication : Application() { class MyApplication : Application() {
private val activityLifecycleCallbacks = ActivityLifecycleCallbacks() private val activityLifecycleCallbacks = ActivityLifecycleCallbacks()
lateinit var connectivityCallbackImpl: ConnectivityCallbackImpl
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
registerActivityLifecycleCallbacks(activityLifecycleCallbacks) registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
connectivityCallbackImpl = ConnectivityCallbackImpl()
getSystemService(ConnectivityManager::class.java).registerDefaultNetworkCallback(connectivityCallbackImpl)
} }
override fun onTerminate() { override fun onTerminate() {
super.onTerminate() super.onTerminate()
unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks) unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks)
getSystemService(ConnectivityManager::class.java).unregisterNetworkCallback(connectivityCallbackImpl)
} }
} }

View File

@ -5,13 +5,17 @@ import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.isolaatti.R import com.isolaatti.R
import com.isolaatti.connectivity.ConnectivityCallbackImpl
import com.isolaatti.connectivity.NetworkStatus
import com.isolaatti.home.HomeActivity import com.isolaatti.home.HomeActivity
import com.isolaatti.login.LogInActivity import com.isolaatti.login.LogInActivity
import com.isolaatti.utils.Resource import com.isolaatti.utils.Resource
@ -22,6 +26,9 @@ abstract class IsolaattiBaseActivity : AppCompatActivity() {
val errorViewModel: ErrorMessageViewModel by viewModels() val errorViewModel: ErrorMessageViewModel by viewModels()
private var snackbarNetworkStatus: Snackbar? = null
private var connectionHasBeenLost: Boolean = false
private val errorObserver: Observer<Resource.Error.ErrorType> = Observer { private val errorObserver: Observer<Resource.Error.ErrorType> = Observer {
when(it) { when(it) {
Resource.Error.ErrorType.AuthError -> showReAuthDialog() Resource.Error.ErrorType.AuthError -> showReAuthDialog()
@ -33,6 +40,21 @@ abstract class IsolaattiBaseActivity : AppCompatActivity() {
} }
} }
private val connectivityObserver: Observer<Boolean> = Observer { networkAvailable ->
val view: View = window.decorView.findViewById(android.R.id.content) ?: return@Observer
if(!networkAvailable) {
connectionHasBeenLost = true
snackbarNetworkStatus = Snackbar.make(view, R.string.network_conn_lost, Snackbar.LENGTH_INDEFINITE)
snackbarNetworkStatus?.show()
} else if(connectionHasBeenLost) {
snackbarNetworkStatus?.dismiss()
snackbarNetworkStatus = Snackbar.make(view, R.string.network_conn_restored, Snackbar.LENGTH_SHORT)
snackbarNetworkStatus?.show()
connectionHasBeenLost = false
}
}
private val signInActivityResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult -> private val signInActivityResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
if(activityResult.resultCode == Activity.RESULT_OK) { if(activityResult.resultCode == Activity.RESULT_OK) {
onRetry() onRetry()
@ -77,6 +99,9 @@ abstract class IsolaattiBaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
errorViewModel.error.observe(this, errorObserver) errorViewModel.error.observe(this, errorObserver)
NetworkStatus.networkIsAvailable.observe(this, connectivityObserver)
Log.d("IsolaattiBaseActivity", errorViewModel.toString()) Log.d("IsolaattiBaseActivity", errorViewModel.toString())
} }
} }

View File

@ -0,0 +1,21 @@
package com.isolaatti.connectivity
import android.net.ConnectivityManager
import android.net.Network
class ConnectivityCallbackImpl : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
NetworkStatus.networkIsAvailable.postValue(true)
}
override fun onLost(network: Network) {
super.onLost(network)
NetworkStatus.networkIsAvailable.postValue(false)
}
override fun onUnavailable() {
super.onUnavailable()
NetworkStatus.networkIsAvailable.postValue(false)
}
}

View File

@ -1,5 +1,7 @@
package com.isolaatti.connectivity package com.isolaatti.connectivity
import androidx.lifecycle.MutableLiveData
object NetworkStatus { object NetworkStatus {
var networkIsAvailable: Boolean = true val networkIsAvailable: MutableLiveData<Boolean> = MutableLiveData()
} }

View File

@ -15,6 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.isolaatti.BuildConfig import com.isolaatti.BuildConfig
import com.isolaatti.R import com.isolaatti.R
import com.isolaatti.common.Dialogs import com.isolaatti.common.Dialogs
import com.isolaatti.common.ErrorMessageViewModel
import com.isolaatti.databinding.FragmentDiscussionsBinding import com.isolaatti.databinding.FragmentDiscussionsBinding
import com.isolaatti.followers.domain.FollowingState import com.isolaatti.followers.domain.FollowingState
import com.isolaatti.home.FeedFragment import com.isolaatti.home.FeedFragment
@ -48,6 +49,7 @@ class ProfileMainFragment : Fragment() {
lateinit var viewBinding: FragmentDiscussionsBinding lateinit var viewBinding: FragmentDiscussionsBinding
private val viewModel: ProfileViewModel by viewModels() private val viewModel: ProfileViewModel by viewModels()
val optionsViewModel: BottomSheetPostOptionsViewModel by activityViewModels() val optionsViewModel: BottomSheetPostOptionsViewModel by activityViewModels()
val errorViewModel: ErrorMessageViewModel by activityViewModels()
private var userId: Int? = null private var userId: Int? = null
lateinit var postsAdapter: PostsRecyclerViewAdapter lateinit var postsAdapter: PostsRecyclerViewAdapter
@ -213,6 +215,9 @@ class ProfileMainFragment : Fragment() {
viewBinding.swipeToRefresh.isRefreshing = false viewBinding.swipeToRefresh.isRefreshing = false
} }
} }
viewModel.errorLoading.observe(viewLifecycleOwner) {
errorViewModel.error.postValue(it)
}
} }
private fun getData() { private fun getData() {

View File

@ -75,4 +75,6 @@
<string name="comment_posted">Comment posted!</string> <string name="comment_posted">Comment posted!</string>
<string name="comment_failed_to_post">Comment failed to post</string> <string name="comment_failed_to_post">Comment failed to post</string>
<string name="edit_comment">Edit comment</string> <string name="edit_comment">Edit comment</string>
<string name="network_conn_lost">Network connection lost</string>
<string name="network_conn_restored">Network connection restored</string>
</resources> </resources>