diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/MeetingPresenterModule.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/MeetingPresenterModule.java index 97753a3f..4489b697 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/MeetingPresenterModule.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/MeetingPresenterModule.java @@ -3,6 +3,7 @@ import java.util.Comparator; import java.util.List; +import br.org.cesar.discordtime.stickysessions.data.remote.wrapper.INetworkWrapper; import br.org.cesar.discordtime.stickysessions.domain.model.Meeting; import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase; import br.org.cesar.discordtime.stickysessions.navigation.router.IRouter; @@ -18,8 +19,8 @@ public class MeetingPresenterModule { @Provides public MeetingContract.Presenter providesMeetingPresenter( IObservableUseCase, List> listMeetings, - IRouter router, IBundleFactory bundleFactory + IRouter router, INetworkWrapper networkWrapper, IBundleFactory bundleFactory ) { - return new MeetingPresenter(listMeetings, router, bundleFactory); + return new MeetingPresenter(listMeetings, router, networkWrapper, bundleFactory); } } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingContract.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingContract.kt index 5c2a3c2d..b1e301e2 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingContract.kt +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingContract.kt @@ -11,6 +11,7 @@ interface MeetingContract { fun detachView() fun onResume() fun enterOnMeeting(meetingItem: MeetingItem) + fun onRetryNetworkClick() } interface View { @@ -21,5 +22,9 @@ interface MeetingContract { fun getName(): String @Throws(InvalidViewNameException::class) fun goNext(route: Route, bundle: IBundle) + fun isMeetingsEmpty(): Boolean + fun showNetworkError() + fun hideNetworkError() + fun showNetworkErrorIcon() } } \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingPresenter.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingPresenter.kt index 689d2a02..1d0f9bf2 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingPresenter.kt +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/meeting/MeetingPresenter.kt @@ -1,5 +1,6 @@ package br.org.cesar.discordtime.stickysessions.presentation.meeting +import br.org.cesar.discordtime.stickysessions.data.remote.wrapper.INetworkWrapper import br.org.cesar.discordtime.stickysessions.domain.model.Meeting import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase import br.org.cesar.discordtime.stickysessions.navigation.router.IRouter @@ -12,6 +13,7 @@ import java.util.* class MeetingPresenter( private val listMeetings: IObservableUseCase, MutableList>, private val router: IRouter, + private val networkWrapper: INetworkWrapper, private val bundleFactory: IBundleFactory) : MeetingContract.Presenter { @@ -20,17 +22,14 @@ class MeetingPresenter( override fun attachView(view: MeetingContract.View) { mView = view } + override fun detachView() { mView = null listMeetings.dispose() } + override fun onResume() { - mView?.let { view -> - view.startLoadingMeetings() - listMeetings.execute( - MeetingsObserver(), - MeetingsComparator()) - } + loadMeetings() } override fun enterOnMeeting(meetingItem: MeetingItem) { @@ -42,6 +41,10 @@ class MeetingPresenter( } } + override fun onRetryNetworkClick() { + loadMeetings() + } + private inner class MeetingsComparator: Comparator { // descending order m2 > m1 override fun compare(m1: Meeting, m2: Meeting): Int { @@ -91,4 +94,19 @@ class MeetingPresenter( numOfParticipants = meeting.participants.size ) } + + private fun loadMeetings() { + when { + networkWrapper.isConnected -> mView?.let { view -> + view.hideNetworkError() + view.startLoadingMeetings() + listMeetings.execute( + MeetingsObserver(), + MeetingsComparator()) + } + mView?.isMeetingsEmpty()!! -> mView?.showNetworkError() + else -> mView?.showNetworkErrorIcon() + } + } + } \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/meeting/MeetingActivity.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/meeting/MeetingActivity.kt index e7326e3a..75cad6f9 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/meeting/MeetingActivity.kt +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/meeting/MeetingActivity.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.os.Bundle import android.util.Log import android.view.View +import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import androidx.appcompat.app.AppCompatActivity @@ -30,6 +31,7 @@ class MeetingActivity : AppCompatActivity(), MeetingContract.View { lateinit var mViewStarter: IViewStarter lateinit var mProgressBar: ProgressBar lateinit var mAdapter: MeetingItemAdapter + lateinit var mNoNetworkContainer: View override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -37,6 +39,7 @@ class MeetingActivity : AppCompatActivity(), MeetingContract.View { (application as StickySessionApplication).inject(this) mProgressBar = findViewById(R.id.progressbar) + mNoNetworkContainer = findViewById(R.id.no_network_container) configureToolbar() configureRecycleView() } @@ -47,6 +50,9 @@ class MeetingActivity : AppCompatActivity(), MeetingContract.View { val toolbarTitle = findViewById(R.id.toolbar_title) toolbarTitle.setText(R.string.toolbar_title_meetings) + + val imageView = toolbar.findViewById(R.id.iv_no_network) + imageView.setOnClickListener { view -> onRetryClick(view) } } @SuppressLint("CheckResult") @@ -103,6 +109,32 @@ class MeetingActivity : AppCompatActivity(), MeetingContract.View { mViewStarter.goNext(this, route.to, route.shouldClearStack, bundle) } + override fun isMeetingsEmpty(): Boolean { + return mAdapter.meetingItems.isEmpty() + } + + override fun showNetworkError() { + mNoNetworkContainer.visibility = View.VISIBLE + } + + override fun showNetworkErrorIcon() { + val toolbar = findViewById(R.id.toolbar) + val imageView = toolbar.findViewById(R.id.iv_no_network) + imageView.visibility = View.VISIBLE + } + + override fun hideNetworkError() { + mNoNetworkContainer.visibility = View.GONE + + val toolbar = findViewById(R.id.toolbar) + val imageView = toolbar.findViewById(R.id.iv_no_network) + imageView.visibility = View.GONE + } + + fun onRetryClick(view: View) { + mPresenter.onRetryNetworkClick() + } + companion object { const val TAG = "MeetingActivity" } diff --git a/app/src/main/res/drawable/ic_cloud_off_black_24dp.xml b/app/src/main/res/drawable/ic_cloud_off_black_24dp.xml new file mode 100644 index 00000000..1e753cf4 --- /dev/null +++ b/app/src/main/res/drawable/ic_cloud_off_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_meeting.xml b/app/src/main/res/layout/activity_meeting.xml index 1e0686d5..487f1e36 100644 --- a/app/src/main/res/layout/activity_meeting.xml +++ b/app/src/main/res/layout/activity_meeting.xml @@ -31,4 +31,54 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/toolbar" /> + + + + + + +