Changes for first launches & proper back nav

This commit is contained in:
Sylvain Berfini 2023-11-17 17:40:32 +01:00
parent c491f18ba5
commit a1374d228e
9 changed files with 97 additions and 37 deletions

View file

@ -48,6 +48,13 @@ class CorePreferences @UiThread constructor(private val context: Context) {
config.setBool("app", "debug", value)
}
@get:WorkerThread @set:WorkerThread
var firstLaunch: Boolean
get() = config.getBool("app", "first_6.0_launch", true)
set(value) {
config.setBool("app", "first_6.0_launch", value)
}
@get:WorkerThread @set:WorkerThread
var defaultFragment: Int
get() = config.getInt("app", "default_page", -1)

View file

@ -19,34 +19,73 @@
*/
package org.linphone.ui.assistant
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.PersistableBundle
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.annotation.DrawableRes
import androidx.annotation.UiThread
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import org.linphone.LinphoneApplication
import androidx.navigation.findNavController
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantActivityBinding
import org.linphone.ui.assistant.fragment.PermissionsFragmentDirections
import org.linphone.utils.AppUtils
import org.linphone.utils.slideInToastFromTopForDuration
@UiThread
class AssistantActivity : AppCompatActivity() {
companion object {
private const val TAG = "[Assistant Activity]"
val PERMISSIONS = arrayOf(
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
)
}
private lateinit var binding: AssistantActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, true)
super.onCreate(savedInstanceState)
while (!LinphoneApplication.coreContext.isReady()) {
while (!coreContext.isReady()) {
Thread.sleep(20)
}
binding = DataBindingUtil.setContentView(this, R.layout.assistant_activity)
binding.lifecycleOwner = this
coreContext.postOnCoreThread { core ->
if (core.accountList.isEmpty()) {
Log.i("$TAG No account configured, disabling back gesture")
coreContext.postOnMainThread {
// Disable back gesture / button
onBackPressedDispatcher.addCallback { }
}
}
}
}
override fun onPostCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onPostCreate(savedInstanceState, persistentState)
if (!areAllPermissionsGranted()) {
Log.w("$TAG Not all required permissions are granted, showing Permissions fragment")
val action = PermissionsFragmentDirections.actionGlobalPermissionsFragment()
binding.assistantNavContainer.findNavController().navigate(action)
}
}
fun showGreenToast(message: String, @DrawableRes icon: Int) {
@ -68,4 +107,13 @@ class AssistantActivity : AppCompatActivity() {
lifecycleScope
)
}
private fun areAllPermissionsGranted(): Boolean {
for (permission in PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false
}
}
return true
}
}

View file

@ -25,7 +25,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.annotation.UiThread
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
@ -34,6 +33,7 @@ import androidx.navigation.navGraphViewModels
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantLoginFragmentBinding
@ -56,12 +56,6 @@ class LoginFragment : Fragment() {
R.id.assistant_nav_graph
)
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
goBack()
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -77,13 +71,8 @@ class LoginFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback
)
binding.setBackClickListener {
goBack()
requireActivity().finish()
}
binding.setRegisterClickListener {
@ -156,10 +145,6 @@ class LoginFragment : Fragment() {
}
}
private fun goBack() {
requireActivity().finish()
}
private fun goToRegisterFragment() {
val action = LoginFragmentDirections.actionLoginFragmentToRegisterFragment()
findNavController().navigate(action)
@ -190,8 +175,7 @@ class LoginFragment : Fragment() {
it.consume {
Log.i("$TAG Conditions & Privacy policy have been accepted")
coreContext.postOnCoreThread {
// TODO FIXME: uncomment
// corePreferences.conditionsAndPrivacyPolicyAccepted = true
corePreferences.conditionsAndPrivacyPolicyAccepted = true
}
dialog.dismiss()

View file

@ -32,18 +32,12 @@ import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantPermissionsFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
@UiThread
class PermissionsFragment : Fragment() {
companion object {
private const val TAG = "[Permissions Fragment]"
private val PERMISSIONS = arrayOf(
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
)
}
private lateinit var binding: AssistantPermissionsFragmentBinding
@ -94,7 +88,7 @@ class PermissionsFragment : Fragment() {
binding.setGrantAllClickListener {
Log.i("$TAG Requesting all permissions")
requestPermissionLauncher.launch(
PERMISSIONS
AssistantActivity.PERMISSIONS
)
}
@ -113,7 +107,7 @@ class PermissionsFragment : Fragment() {
}
private fun areAllPermissionsGranted(): Boolean {
for (permission in PERMISSIONS) {
for (permission in AssistantActivity.PERMISSIONS) {
if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
return false
}

View file

@ -43,6 +43,8 @@ class AccountLoginViewModel @UiThread constructor() : ViewModel() {
private const val TAG = "[Account Login ViewModel]"
}
val showBackButton = MutableLiveData<Boolean>()
val username = MutableLiveData<String>()
val password = MutableLiveData<String>()
@ -55,9 +57,13 @@ class AccountLoginViewModel @UiThread constructor() : ViewModel() {
val registrationInProgress = MutableLiveData<Boolean>()
val accountLoggedInEvent = MutableLiveData<Event<Boolean>>()
val accountLoggedInEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val accountLoginErrorEvent = MutableLiveData<Event<String>>()
val accountLoginErrorEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
var conditionsAndPrivacyPolicyAccepted = false
@ -111,7 +117,9 @@ class AccountLoginViewModel @UiThread constructor() : ViewModel() {
showPassword.value = false
registrationInProgress.value = false
coreContext.postOnCoreThread {
coreContext.postOnCoreThread { core ->
// Prevent user from leaving assistant if no account was configured yet
showBackButton.postValue(core.accountList.isNotEmpty())
conditionsAndPrivacyPolicyAccepted = corePreferences.conditionsAndPrivacyPolicyAccepted
}

View file

@ -50,8 +50,10 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MainActivityBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.main.viewmodel.MainViewModel
import org.linphone.ui.main.viewmodel.SharedMainViewModel
import org.linphone.ui.welcome.WelcomeActivity
import org.linphone.utils.AppUtils
import org.linphone.utils.FileUtils
import org.linphone.utils.LinphoneUtils
@ -173,8 +175,20 @@ class MainActivity : AppCompatActivity() {
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
// TODO FIXME: uncomment
// startActivity(Intent(this, WelcomeActivity::class.java))
coreContext.postOnCoreThread { core ->
if (corePreferences.firstLaunch) {
Log.i("$TAG First time Linphone 6.0 has been started, showing Welcome activity")
corePreferences.firstLaunch = false
coreContext.postOnMainThread {
startActivity(Intent(this, WelcomeActivity::class.java))
}
} else if (core.accountList.isEmpty()) {
Log.w("$TAG No account found, showing Assistant activity")
coreContext.postOnMainThread {
startActivity(Intent(this, AssistantActivity::class.java))
}
}
}
coreContext.greenToastToShowEvent.observe(this) {
it.consume { pair ->

View file

@ -22,6 +22,7 @@ package org.linphone.ui.welcome
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
@ -59,6 +60,9 @@ class WelcomeActivity : AppCompatActivity() {
Thread.sleep(20)
}
// Disable back gesture / button
onBackPressedDispatcher.addCallback { }
binding = DataBindingUtil.setContentView(this, R.layout.welcome_activity)
binding.lifecycleOwner = this

View file

@ -45,6 +45,7 @@
android:layout_height="@dimen/top_bar_height"
android:padding="15dp"
android:src="@drawable/caret_left"
android:visibility="@{viewModel.showBackButton ? View.VISIBLE : View.INVISIBLE, default=invisible}"
app:tint="@color/gray_main2_500"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

View file

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/assistant_nav_graph"
app:startDestination="@id/permissionsFragment">
app:startDestination="@id/loginFragment">
<fragment
android:id="@+id/loginFragment"
@ -145,6 +145,6 @@
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:launchSingleTop="true" />
</fragment>
</fragment><action android:id="@+id/action_global_permissionsFragment" app:destination="@id/permissionsFragment"/>
</navigation>