Commit 62e66314 authored by Christophe Henry's avatar Christophe Henry

Pressing back button closes the drawer instead of exiting the app

parent 74748ca9
Pipeline #3642 passed with stage
in 0 seconds
package fr.chenry.android.freshrss.activities
import android.app.Activity
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.NoActivityResumedException
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions
......@@ -9,10 +14,15 @@ import androidx.test.espresso.contrib.DrawerMatchers.isOpen
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
import androidx.test.runner.lifecycle.Stage
import fr.chenry.android.freshrss.R
import junit.framework.TestCase.assertFalse
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
......@@ -23,14 +33,41 @@ class MainActivityTest {
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)
@get:Rule
var exceptionRule = ExpectedException.none()
@Test
fun `check-drawer-is-closed-when-adding-a-new-subscription`() {
fun `drawer-is-closed-when-adding-a-new-subscription`() {
// Open drawer
onView(withId(R.id.activity_main_navigation_drawer)).perform(DrawerActions.open())
onView(withId(R.id.activity_main_navigation_drawer)).check(matches(isOpen()))
onView(withText(R.string.title_add_subscription)).perform(click())
onView(withText(android.R.string.ok)).perform(click())
val drawer = getActivityInstance().findViewById<DrawerLayout>((R.id.activity_main_navigation_drawer))
assertFalse(drawer.isDrawerOpen(GravityCompat.START))
}
@Test
fun `drawer-is-closed-before-application-exits`() {
onView(withId(R.id.activity_main_navigation_drawer)).perform(DrawerActions.open())
onView(withId(R.id.activity_main_navigation_drawer)).check(matches(isOpen()))
onView(isRoot()).perform(ViewActions.pressBack())
onView(withId(R.id.activity_main_navigation_drawer)).check(matches(isClosed()))
// We assert that pressing back again exists the app
exceptionRule.expect(NoActivityResumedException::class.java)
onView(isRoot()).perform(ViewActions.pressBack())
}
// See https://stackoverflow.com/a/60341723/3459089
private fun getActivityInstance(): Activity {
val currentActivity = arrayOf<Activity?>(null)
InstrumentationRegistry.getInstrumentation().runOnMainSync {
val resumedActivity = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED)
val it: Iterator<Activity> = resumedActivity.iterator()
currentActivity[0] = it.next()
}
return currentActivity[0]!!
}
}
......@@ -17,8 +17,7 @@ import fr.chenry.android.freshrss.components.navigationdrawer.AddSubscriptionDia
import fr.chenry.android.freshrss.components.subscriptions.MainSubscriptionFragmentDirections
import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.store.viewmodels.AccountVM
import fr.chenry.android.freshrss.utils.BurgerMenuDrawerListener
import fr.chenry.android.freshrss.utils.e
import fr.chenry.android.freshrss.utils.*
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity: AppCompatActivity() {
......@@ -59,8 +58,7 @@ class MainActivity: AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item?.itemId == android.R.id.home && backstackCount == 0) {
val isOpened = drawerLayout.isDrawerOpen(activity_main_navigation_view)
if(isOpened) drawerLayout.closeDrawers()
if(isDrawerOpen()) drawerLayout.closeDrawers()
else drawerLayout.openDrawer(activity_main_navigation_view)
return true
......@@ -82,6 +80,12 @@ class MainActivity: AppCompatActivity() {
fun onSettingsItemClick(@Suppress("UNUSED_PARAMETER") item: MenuItem) =
navigation.navigate(MainSubscriptionFragmentDirections.mainSubscriptionsToSettings())
override fun onBackPressed() =
if(navigation.isTopLevelDestination() && isDrawerOpen()) drawerLayout.closeDrawers()
else super.onBackPressed()
override fun onSupportNavigateUp(): Boolean =
navigation.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
private fun isDrawerOpen() = drawerLayout.isDrawerOpen(activity_main_navigation_view)
}
......@@ -18,27 +18,26 @@ class BurgerMenuDrawerListener(
private val navigation: NavController
): DrawerLayout.DrawerListener {
private val drawable = HamburgerCrossDrawable(supportActionBar.themedContext)
private val isTopLevelDest: Boolean
inline get() = navigation.currentDestination?.id == navigation.graph.startDestination
override fun onDrawerStateChanged(newState: Int) {
if(isTopLevelDest) supportActionBar.setHomeAsUpIndicator(drawable)
if(navigation.isTopLevelDestination()) supportActionBar.setHomeAsUpIndicator(drawable)
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
if(isTopLevelDest) setPosition(slideOffset)
if(navigation.isTopLevelDestination()) setPosition(slideOffset)
}
override fun onDrawerClosed(drawerView: View) {
if(isTopLevelDest) {
if(navigation.isTopLevelDestination()) {
supportActionBar.setHomeActionContentDescription(R.string.navigation_drawer_open)
setPosition(0f)
}
}
override fun onDrawerOpened(drawerView: View) {
if(isTopLevelDest) {
if(navigation.isTopLevelDestination()) {
supportActionBar.setHomeActionContentDescription(R.string.navigation_drawer_close)
setPosition(1f)
}
......
......@@ -4,6 +4,7 @@ import android.content.Context
import android.net.ConnectivityManager
import android.net.Uri
import android.util.Log
import androidx.navigation.NavController
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.joda.JodaModule
......@@ -16,10 +17,7 @@ import nl.komponents.kovenant.Kovenant.deferred
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.task
import org.apache.commons.text.StringEscapeUtils
import org.joda.time.DateTimeZone
import org.joda.time.LocalDateTime
import java.net.URL
import java.util.TimeZone
import kotlin.reflect.full.companionObjectInstance
val JACKSON_OBJECT_MAPPER: ObjectMapper = ObjectMapper().registerKotlinModule()
......@@ -124,7 +122,5 @@ fun <T> List<T>.firstOrElse(other: T): T {
return if (isEmpty()) other else this[0]
}
fun LocalDateTime.toUserDateTime() =
this.toDateTime(DateTimeZone.UTC)
.withZone(DateTimeZone.forTimeZone(TimeZone.getDefault()))
.toLocalDateTime()
fun NavController.isTopLevelDestination(): Boolean =
this.currentDestination?.id == this.graph.startDestination
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment