mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 01:39:22 +02:00
Refactor navigation to avoid overriding onBackPressed
This commit is contained in:
parent
09e6a30ee3
commit
b5a5bc276e
10 changed files with 205 additions and 159 deletions
|
@ -31,6 +31,7 @@ import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavDestination
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import io.timelimit.android.Application
|
import io.timelimit.android.Application
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
|
@ -51,13 +52,7 @@ import io.timelimit.android.ui.main.ActivityViewModelHolder
|
||||||
import io.timelimit.android.ui.main.AuthenticatedUser
|
import io.timelimit.android.ui.main.AuthenticatedUser
|
||||||
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
||||||
import io.timelimit.android.ui.manage.parent.ManageParentFragmentArgs
|
import io.timelimit.android.ui.manage.parent.ManageParentFragmentArgs
|
||||||
import io.timelimit.android.ui.manage.parent.link.LinkParentMailFragment
|
|
||||||
import io.timelimit.android.ui.manage.parent.password.restore.RestoreParentPasswordFragment
|
|
||||||
import io.timelimit.android.ui.overview.main.MainFragment
|
|
||||||
import io.timelimit.android.ui.parentmode.ParentModeFragment
|
|
||||||
import io.timelimit.android.ui.payment.ActivityPurchaseModel
|
import io.timelimit.android.ui.payment.ActivityPurchaseModel
|
||||||
import io.timelimit.android.ui.setup.SetupTermsFragment
|
|
||||||
import io.timelimit.android.ui.setup.parent.SetupParentModeFragment
|
|
||||||
import io.timelimit.android.ui.util.SyncStatusModel
|
import io.timelimit.android.ui.util.SyncStatusModel
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
|
@ -101,7 +96,6 @@ class MainActivity : AppCompatActivity(), ActivityViewModelHolder, U2fManager.De
|
||||||
}
|
}
|
||||||
|
|
||||||
private val currentNavigatorFragment = MutableLiveData<Fragment?>()
|
private val currentNavigatorFragment = MutableLiveData<Fragment?>()
|
||||||
private val application: Application by lazy { getApplication() as Application }
|
|
||||||
private val syncModel: SyncStatusModel by lazy {
|
private val syncModel: SyncStatusModel by lazy {
|
||||||
ViewModelProviders.of(this).get(SyncStatusModel::class.java)
|
ViewModelProviders.of(this).get(SyncStatusModel::class.java)
|
||||||
}
|
}
|
||||||
|
@ -147,13 +141,11 @@ class MainActivity : AppCompatActivity(), ActivityViewModelHolder, U2fManager.De
|
||||||
}
|
}
|
||||||
|
|
||||||
// up button
|
// up button
|
||||||
val shouldShowBackButtonForNavigatorFragment = currentNavigatorFragment.map { fragment ->
|
getNavController().addOnDestinationChangedListener(object: NavController.OnDestinationChangedListener {
|
||||||
(!(fragment is MainFragment)) && (!(fragment is SetupTermsFragment)) && (!(fragment is ParentModeFragment))
|
override fun onDestinationChanged(controller: NavController, destination: NavDestination, arguments: Bundle?) {
|
||||||
|
supportActionBar!!.setDisplayHomeAsUpEnabled(controller.previousBackStackEntry != null)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
val shouldShowUpButton = shouldShowBackButtonForNavigatorFragment
|
|
||||||
|
|
||||||
shouldShowUpButton.observe(this, Observer { supportActionBar!!.setDisplayHomeAsUpEnabled(it) })
|
|
||||||
|
|
||||||
// init if not yet done
|
// init if not yet done
|
||||||
DefaultAppLogic.with(this)
|
DefaultAppLogic.with(this)
|
||||||
|
@ -183,6 +175,33 @@ class MainActivity : AppCompatActivity(), ActivityViewModelHolder, U2fManager.De
|
||||||
syncModel.statusText.observe(this, Observer { supportActionBar!!.subtitle = it })
|
syncModel.statusText.observe(this, Observer { supportActionBar!!.subtitle = it })
|
||||||
|
|
||||||
handleParameters(intent)
|
handleParameters(intent)
|
||||||
|
|
||||||
|
val hasDeviceId = getActivityViewModel().logic.deviceId.map { it != null }.ignoreUnchanged()
|
||||||
|
val hasParentKey = getActivityViewModel().logic.database.config().getParentModeKeyLive().map { it != null }.ignoreUnchanged()
|
||||||
|
|
||||||
|
hasDeviceId.observe(this) {
|
||||||
|
val rootDestination = getNavController().backQueue.getOrNull(1)?.destination?.id
|
||||||
|
|
||||||
|
if (!it) getActivityViewModel().logOut()
|
||||||
|
|
||||||
|
if (
|
||||||
|
it && rootDestination != R.id.overviewFragment ||
|
||||||
|
!it && rootDestination == R.id.overviewFragment
|
||||||
|
) {
|
||||||
|
restartContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasParentKey.observe(this) {
|
||||||
|
val rootDestination = getNavController().backQueue.getOrNull(1)?.destination?.id
|
||||||
|
|
||||||
|
if (
|
||||||
|
it && rootDestination != R.id.parentModeFragment ||
|
||||||
|
!it && rootDestination == R.id.parentModeFragment
|
||||||
|
) {
|
||||||
|
restartContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem) = when {
|
override fun onOptionsItemSelected(item: MenuItem) = when {
|
||||||
|
@ -259,29 +278,26 @@ class MainActivity : AppCompatActivity(), ActivityViewModelHolder, U2fManager.De
|
||||||
|
|
||||||
if (handleParameters(intent)) return
|
if (handleParameters(intent)) return
|
||||||
|
|
||||||
val currentFragment = currentNavigatorFragment.value
|
|
||||||
|
|
||||||
// at these screens, some users restart the App
|
// at these screens, some users restart the App
|
||||||
// if they want to continue after opening the mail
|
// if they want to continue after opening the mail
|
||||||
// because they don't understand how to use the list of running Apps ...
|
// because they don't understand how to use the list of running Apps ...
|
||||||
// Due to that, on the relevant screens, the App does not
|
// Due to that, on the relevant screens, the App does not
|
||||||
// go back to the start when opening it again
|
// go back to the start when opening it again
|
||||||
if (
|
val isImportantScreen = when (getNavController().currentDestination?.id) {
|
||||||
currentFragment is SetupParentModeFragment ||
|
R.id.setupParentModeFragment -> true
|
||||||
currentFragment is RestoreParentPasswordFragment ||
|
R.id.restoreParentPasswordFragment -> true
|
||||||
currentFragment is LinkParentMailFragment
|
R.id.linkParentMailFragment -> true
|
||||||
) {
|
else -> false
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNavController().popBackStack(R.id.overviewFragment, true)
|
if (!isImportantScreen) restartContent()
|
||||||
getNavController().handleDeepLink(
|
}
|
||||||
getNavController().createDeepLink()
|
|
||||||
.setDestination(R.id.overviewFragment)
|
private fun restartContent() {
|
||||||
.createTaskStackBuilder()
|
while (getNavController().popBackStack()) {/* do nothing */}
|
||||||
.intents
|
|
||||||
.first()
|
getNavController().clearBackStack(R.id.launchFragment)
|
||||||
)
|
getNavController().navigate(R.id.launchFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getActivityViewModel(): ActivityViewModel {
|
override fun getActivityViewModel(): ActivityViewModel {
|
||||||
|
@ -296,15 +312,6 @@ class MainActivity : AppCompatActivity(), ActivityViewModelHolder, U2fManager.De
|
||||||
return getNavHostFragment().navController
|
return getNavHostFragment().navController
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
if (currentNavigatorFragment.value is SetupTermsFragment || currentNavigatorFragment.value is ParentModeFragment) {
|
|
||||||
// hack to prevent the user from going to the launch screen of the App if it is not set up
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
super.onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showAuthenticationScreen() {
|
override fun showAuthenticationScreen() {
|
||||||
if (supportFragmentManager.findFragmentByTag(AUTH_DIALOG_TAG) == null) {
|
if (supportFragmentManager.findFragmentByTag(AUTH_DIALOG_TAG) == null) {
|
||||||
NewLoginFragment().showSafe(supportFragmentManager, AUTH_DIALOG_TAG)
|
NewLoginFragment().showSafe(supportFragmentManager, AUTH_DIALOG_TAG)
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package io.timelimit.android.ui.launch
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import io.timelimit.android.R
|
||||||
|
import io.timelimit.android.extensions.safeNavigate
|
||||||
|
import io.timelimit.android.ui.obsolete.ObsoleteDialogFragment
|
||||||
|
import io.timelimit.android.ui.overview.main.MainFragmentDirections
|
||||||
|
|
||||||
|
class LaunchFragment: Fragment() {
|
||||||
|
private val model by viewModels<LaunchModel>()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
ObsoleteDialogFragment.show(requireActivity(), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.circular_progress_indicator, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val navigation = Navigation.findNavController(view)
|
||||||
|
|
||||||
|
model.action.observe(viewLifecycleOwner) {
|
||||||
|
when (it) {
|
||||||
|
LaunchModel.Action.Setup -> navigation.safeNavigate(LaunchFragmentDirections.actionLaunchFragmentToSetupTermsFragment(), R.id.launchFragment)
|
||||||
|
LaunchModel.Action.Overview -> navigation.safeNavigate(LaunchFragmentDirections.actionLaunchFragmentToOverviewFragment(), R.id.launchFragment)
|
||||||
|
is LaunchModel.Action.Child -> {
|
||||||
|
navigation.safeNavigate(LaunchFragmentDirections.actionLaunchFragmentToOverviewFragment(), R.id.launchFragment)
|
||||||
|
navigation.safeNavigate(MainFragmentDirections.actionOverviewFragmentToManageChildFragment(it.id, fromRedirect = true), R.id.overviewFragment)
|
||||||
|
}
|
||||||
|
LaunchModel.Action.DeviceSetup -> {
|
||||||
|
navigation.safeNavigate(LaunchFragmentDirections.actionLaunchFragmentToOverviewFragment(), R.id.launchFragment)
|
||||||
|
navigation.safeNavigate(MainFragmentDirections.actionOverviewFragmentToSetupDeviceFragment(), R.id.overviewFragment)
|
||||||
|
}
|
||||||
|
LaunchModel.Action.ParentMode -> navigation.safeNavigate(LaunchFragmentDirections.actionLaunchFragmentToParentModeFragment(), R.id.launchFragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package io.timelimit.android.ui.launch
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import io.timelimit.android.async.Threads
|
||||||
|
import io.timelimit.android.coroutines.executeAndWait
|
||||||
|
import io.timelimit.android.data.model.UserType
|
||||||
|
import io.timelimit.android.livedata.castDown
|
||||||
|
import io.timelimit.android.livedata.waitUntilValueMatches
|
||||||
|
import io.timelimit.android.logic.DefaultAppLogic
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class LaunchModel(application: Application): AndroidViewModel(application) {
|
||||||
|
private val actionInternal = MutableLiveData<Action>()
|
||||||
|
private val logic = DefaultAppLogic.with(application)
|
||||||
|
|
||||||
|
val action = actionInternal.castDown()
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
logic.isInitialized.waitUntilValueMatches { it == true }
|
||||||
|
|
||||||
|
actionInternal.value = Threads.database.executeAndWait {
|
||||||
|
val hasDeviceId = logic.database.config().getOwnDeviceIdSync() != null
|
||||||
|
val hasParentKey = logic.database.config().getParentModeKeySync() != null
|
||||||
|
|
||||||
|
if (hasDeviceId) {
|
||||||
|
val config = logic.database.derivedDataDao().getUserAndDeviceRelatedDataSync()
|
||||||
|
|
||||||
|
if (config?.userRelatedData?.user?.type == UserType.Child) Action.Child(config.userRelatedData.user.id)
|
||||||
|
else if (config?.userRelatedData == null) Action.DeviceSetup
|
||||||
|
else Action.Overview
|
||||||
|
}
|
||||||
|
else if (hasParentKey) Action.ParentMode
|
||||||
|
else Action.Setup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class Action {
|
||||||
|
object Setup: Action()
|
||||||
|
object Overview: Action()
|
||||||
|
data class Child(val id: String): Action()
|
||||||
|
object DeviceSetup: Action()
|
||||||
|
object ParentMode: Action()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,30 +19,19 @@ import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
import io.timelimit.android.async.Threads
|
|
||||||
import io.timelimit.android.coroutines.executeAndWait
|
|
||||||
import io.timelimit.android.coroutines.runAsync
|
|
||||||
import io.timelimit.android.data.model.UserType
|
|
||||||
import io.timelimit.android.extensions.safeNavigate
|
import io.timelimit.android.extensions.safeNavigate
|
||||||
import io.timelimit.android.livedata.*
|
import io.timelimit.android.livedata.*
|
||||||
import io.timelimit.android.logic.AppLogic
|
|
||||||
import io.timelimit.android.logic.DefaultAppLogic
|
|
||||||
import io.timelimit.android.ui.fragment.SingleFragmentWrapper
|
import io.timelimit.android.ui.fragment.SingleFragmentWrapper
|
||||||
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
||||||
import io.timelimit.android.ui.manage.device.add.AddDeviceFragment
|
import io.timelimit.android.ui.manage.device.add.AddDeviceFragment
|
||||||
import io.timelimit.android.ui.obsolete.ObsoleteDialogFragment
|
|
||||||
import io.timelimit.android.ui.overview.about.AboutFragmentParentHandlers
|
import io.timelimit.android.ui.overview.about.AboutFragmentParentHandlers
|
||||||
import io.timelimit.android.ui.overview.overview.OverviewFragment
|
import io.timelimit.android.ui.overview.overview.OverviewFragment
|
||||||
import io.timelimit.android.ui.overview.overview.OverviewFragmentParentHandlers
|
import io.timelimit.android.ui.overview.overview.OverviewFragmentParentHandlers
|
||||||
|
|
||||||
class MainFragment : SingleFragmentWrapper(), OverviewFragmentParentHandlers, AboutFragmentParentHandlers, FragmentWithCustomTitle {
|
class MainFragment : SingleFragmentWrapper(), OverviewFragmentParentHandlers, AboutFragmentParentHandlers, FragmentWithCustomTitle {
|
||||||
private val logic: AppLogic by lazy { DefaultAppLogic.with(requireContext()) }
|
|
||||||
private var didRedirectToUserScreen = false
|
|
||||||
override val showAuthButton: Boolean = true
|
override val showAuthButton: Boolean = true
|
||||||
|
|
||||||
override fun createChildFragment(): Fragment = OverviewFragment()
|
override fun createChildFragment(): Fragment = OverviewFragment()
|
||||||
|
@ -53,60 +42,6 @@ class MainFragment : SingleFragmentWrapper(), OverviewFragmentParentHandlers, Ab
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
logic.isInitialized.switchMap { isInitialized ->
|
|
||||||
if (isInitialized) {
|
|
||||||
logic.database.config().getOwnDeviceId().map { it == null }
|
|
||||||
} else {
|
|
||||||
liveDataFromNonNullValue(false)
|
|
||||||
}
|
|
||||||
}.observe(viewLifecycleOwner, Observer { shouldShowSetup ->
|
|
||||||
if (shouldShowSetup == true) {
|
|
||||||
runAsync {
|
|
||||||
val hasParentKey = Threads.database.executeAndWait { logic.database.config().getParentModeKeySync() != null }
|
|
||||||
|
|
||||||
if (isAdded && !parentFragmentManager.isStateSaved) {
|
|
||||||
if (hasParentKey) {
|
|
||||||
logic.platformIntegration.disableDeviceAdmin()
|
|
||||||
|
|
||||||
navigation.safeNavigate(
|
|
||||||
MainFragmentDirections.actionOverviewFragmentToParentModeFragment(),
|
|
||||||
R.id.overviewFragment
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
navigation.safeNavigate(
|
|
||||||
MainFragmentDirections.actionOverviewFragmentToSetupTermsFragment(),
|
|
||||||
R.id.overviewFragment
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (savedInstanceState == null && !didRedirectToUserScreen) {
|
|
||||||
didRedirectToUserScreen = true
|
|
||||||
|
|
||||||
runAsync {
|
|
||||||
val user = logic.deviceUserEntry.waitForNullableValue()
|
|
||||||
|
|
||||||
if (user?.type == UserType.Child) {
|
|
||||||
if (isAdded && !parentFragmentManager.isStateSaved) {
|
|
||||||
openManageChildScreen(user.id, fromRedirect = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user != null) {
|
|
||||||
if (isAdded && !parentFragmentManager.isStateSaved) {
|
|
||||||
ObsoleteDialogFragment.show(requireActivity(), false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun openAddDeviceScreen() {
|
override fun openAddDeviceScreen() {
|
||||||
AddDeviceFragment().show(parentFragmentManager)
|
AddDeviceFragment().show(parentFragmentManager)
|
||||||
}
|
}
|
||||||
|
@ -118,11 +53,9 @@ class MainFragment : SingleFragmentWrapper(), OverviewFragmentParentHandlers, Ab
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openManageChildScreen(childId: String) = openManageChildScreen(childId = childId, fromRedirect = false)
|
override fun openManageChildScreen(childId: String) {
|
||||||
|
|
||||||
private fun openManageChildScreen(childId: String, fromRedirect: Boolean) {
|
|
||||||
navigation.safeNavigate(
|
navigation.safeNavigate(
|
||||||
MainFragmentDirections.actionOverviewFragmentToManageChildFragment(childId = childId, fromRedirect = fromRedirect),
|
MainFragmentDirections.actionOverviewFragmentToManageChildFragment(childId = childId, fromRedirect = false),
|
||||||
R.id.overviewFragment
|
R.id.overviewFragment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2021 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,8 +21,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import io.timelimit.android.BuildConfig
|
import io.timelimit.android.BuildConfig
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
import io.timelimit.android.databinding.FragmentUninstallBinding
|
import io.timelimit.android.databinding.FragmentUninstallBinding
|
||||||
|
@ -43,7 +41,6 @@ class UninstallFragment : Fragment(), FragmentWithCustomTitle {
|
||||||
private val activity: ActivityViewModelHolder by lazy { getActivity() as ActivityViewModelHolder }
|
private val activity: ActivityViewModelHolder by lazy { getActivity() as ActivityViewModelHolder }
|
||||||
private val auth: ActivityViewModel by lazy { activity.getActivityViewModel() }
|
private val auth: ActivityViewModel by lazy { activity.getActivityViewModel() }
|
||||||
private var showBackdoorButton = false
|
private var showBackdoorButton = false
|
||||||
private lateinit var navigation: NavController
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -52,8 +49,6 @@ class UninstallFragment : Fragment(), FragmentWithCustomTitle {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
navigation = Navigation.findNavController(container!!)
|
|
||||||
|
|
||||||
val binding = FragmentUninstallBinding.inflate(inflater, container, false)
|
val binding = FragmentUninstallBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
binding.uninstall.isEnabled = binding.checkConfirm.isChecked
|
binding.uninstall.isEnabled = binding.checkConfirm.isChecked
|
||||||
|
@ -74,10 +69,6 @@ class UninstallFragment : Fragment(), FragmentWithCustomTitle {
|
||||||
|
|
||||||
binding.showBackdoorButton = showBackdoorButton
|
binding.showBackdoorButton = showBackdoorButton
|
||||||
|
|
||||||
auth.logic.deviceId.observe(viewLifecycleOwner) {
|
|
||||||
if (it == null) { navigation.popBackStack() }
|
|
||||||
}
|
|
||||||
|
|
||||||
AuthenticationFab.manageAuthenticationFab(
|
AuthenticationFab.manageAuthenticationFab(
|
||||||
fab = binding.fab,
|
fab = binding.fab,
|
||||||
fragment = this,
|
fragment = this,
|
||||||
|
|
|
@ -81,7 +81,6 @@ class SetupLocalModeFragment : Fragment() {
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
val binding = FragmentSetupLocalModeBinding.inflate(inflater, container, false)
|
val binding = FragmentSetupLocalModeBinding.inflate(inflater, container, false)
|
||||||
val navigation = Navigation.findNavController(container!!)
|
|
||||||
|
|
||||||
binding.setPasswordView.allowNoPassword.value = true
|
binding.setPasswordView.allowNoPassword.value = true
|
||||||
|
|
||||||
|
@ -97,8 +96,6 @@ class SetupLocalModeFragment : Fragment() {
|
||||||
model.status.observe(viewLifecycleOwner) {
|
model.status.observe(viewLifecycleOwner) {
|
||||||
if (it == SetupLocalModeModel.Status.Done) {
|
if (it == SetupLocalModeModel.Status.Done) {
|
||||||
MustReadFragment.newInstance(R.string.must_read_child_manipulation).show(fragmentManager!!)
|
MustReadFragment.newInstance(R.string.must_read_child_manipulation).show(fragmentManager!!)
|
||||||
|
|
||||||
navigation.popBackStack(R.id.overviewFragment, false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,6 @@ class SetupSelectModeFragment : Fragment() {
|
||||||
SetupSelectModeFragmentDirections.actionSetupSelectModeFragmentToSetupParentModeFragment(),
|
SetupSelectModeFragmentDirections.actionSetupSelectModeFragmentToSetupParentModeFragment(),
|
||||||
R.id.setupSelectModeFragment
|
R.id.setupSelectModeFragment
|
||||||
)
|
)
|
||||||
} else if (requestCode == REQUEST_SETUP_PARENT_MODE && resultCode == Activity.RESULT_OK) {
|
|
||||||
navigation.popBackStack(R.id.overviewFragment, false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,13 +22,10 @@ import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
import io.timelimit.android.databinding.SetupRemoteChildFragmentBinding
|
import io.timelimit.android.databinding.SetupRemoteChildFragmentBinding
|
||||||
import io.timelimit.android.extensions.safeNavigate
|
|
||||||
import io.timelimit.android.extensions.setOnEnterListenr
|
import io.timelimit.android.extensions.setOnEnterListenr
|
||||||
import io.timelimit.android.ui.overview.main.MainFragmentDirections
|
|
||||||
|
|
||||||
class SetupRemoteChildFragment : Fragment() {
|
class SetupRemoteChildFragment : Fragment() {
|
||||||
private val model: SetupRemoteChildViewModel by lazy {
|
private val model: SetupRemoteChildViewModel by lazy {
|
||||||
|
@ -65,18 +62,6 @@ class SetupRemoteChildFragment : Fragment() {
|
||||||
}.let { }
|
}.let { }
|
||||||
})
|
})
|
||||||
|
|
||||||
model.isSetupDone.observe(this, Observer {
|
|
||||||
if (it!!) {
|
|
||||||
val navigation = Navigation.findNavController(binding.root)
|
|
||||||
|
|
||||||
navigation.popBackStack(R.id.overviewFragment, false)
|
|
||||||
navigation.safeNavigate(
|
|
||||||
MainFragmentDirections.actionOverviewFragmentToSetupDeviceFragment(),
|
|
||||||
R.id.overviewFragment
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.lifecycle.observe
|
import androidx.lifecycle.observe
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
import io.timelimit.android.async.Threads
|
import io.timelimit.android.async.Threads
|
||||||
import io.timelimit.android.coroutines.executeAndWait
|
import io.timelimit.android.coroutines.executeAndWait
|
||||||
|
@ -195,12 +194,6 @@ class SetupParentModeFragment : Fragment(), AuthenticateByMailFragmentListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
model.isSetupDone.observe(this, Observer {
|
|
||||||
if (it!!) {
|
|
||||||
Navigation.findNavController(binding.root).popBackStack(R.id.overviewFragment, false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
UpdateConsentCard.bind(
|
UpdateConsentCard.bind(
|
||||||
view = binding.update,
|
view = binding.update,
|
||||||
lifecycleOwner = viewLifecycleOwner,
|
lifecycleOwner = viewLifecycleOwner,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
app:startDestination="@id/overviewFragment">
|
app:startDestination="@id/launchFragment">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/overviewFragment"
|
android:id="@+id/overviewFragment"
|
||||||
|
@ -37,13 +37,6 @@
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
android:id="@+id/action_overviewFragment_to_addUserFragment"
|
android:id="@+id/action_overviewFragment_to_addUserFragment"
|
||||||
app:destination="@id/addUserFragment" />
|
app:destination="@id/addUserFragment" />
|
||||||
<action
|
|
||||||
app:enterAnim="@anim/nav_default_enter_anim"
|
|
||||||
app:exitAnim="@anim/nav_default_exit_anim"
|
|
||||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
|
||||||
android:id="@+id/action_overviewFragment_to_setupTermsFragment"
|
|
||||||
app:destination="@id/setupTermsFragment" />
|
|
||||||
<action
|
<action
|
||||||
app:enterAnim="@anim/nav_default_enter_anim"
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
app:exitAnim="@anim/nav_default_exit_anim"
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
@ -86,9 +79,6 @@
|
||||||
app:exitAnim="@anim/nav_default_exit_anim"
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||||
<action
|
|
||||||
android:id="@+id/action_overviewFragment_to_parentModeFragment"
|
|
||||||
app:destination="@id/parentModeFragment" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_overviewFragment_to_aboutFragmentWrapped"
|
android:id="@+id/action_overviewFragment_to_aboutFragmentWrapped"
|
||||||
app:destination="@id/aboutFragmentWrapped"
|
app:destination="@id/aboutFragmentWrapped"
|
||||||
|
@ -622,4 +612,24 @@
|
||||||
android:id="@+id/diagnoseCryptoFragment"
|
android:id="@+id/diagnoseCryptoFragment"
|
||||||
android:name="io.timelimit.android.ui.diagnose.DiagnoseCryptoFragment"
|
android:name="io.timelimit.android.ui.diagnose.DiagnoseCryptoFragment"
|
||||||
android:label="DiagnoseCryptoFragment" />
|
android:label="DiagnoseCryptoFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/launchFragment"
|
||||||
|
android:name="io.timelimit.android.ui.launch.LaunchFragment"
|
||||||
|
android:label="LaunchFragment">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_launchFragment_to_overviewFragment"
|
||||||
|
app:destination="@id/overviewFragment"
|
||||||
|
app:popUpTo="@id/launchFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_launchFragment_to_setupTermsFragment"
|
||||||
|
app:destination="@id/setupTermsFragment"
|
||||||
|
app:popUpTo="@id/launchFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_launchFragment_to_parentModeFragment"
|
||||||
|
app:destination="@id/parentModeFragment"
|
||||||
|
app:popUpTo="@id/launchFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
</fragment>
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue