Added back sip-linphone & sips-linphone URI handlers + added linphone-sso URI handler & activity + factorized showToast methods

This commit is contained in:
Sylvain Berfini 2024-04-18 15:46:59 +02:00
parent 7607607857
commit b6001544f1
39 changed files with 401 additions and 317 deletions

View file

@ -98,6 +98,8 @@
<data android:scheme="tel" />
<data android:scheme="sip" />
<data android:scheme="sips" />
<data android:scheme="sip-linphone" />
<data android:scheme="sips-linphone" />
<data android:scheme="linphone-config" />
</intent-filter>
@ -113,6 +115,21 @@
android:launchMode="singleTask"
android:resizeableActivity="true" />
<activity
android:name=".ui.assistant.SingleSignOnActivity"
android:launchMode="singleTask"
android:resizeableActivity="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="linphone-sso" />
</intent-filter>
</activity>
<activity
android:name=".ui.call.CallActivity"
android:theme="@style/Theme.LinphoneInCall"

View file

@ -22,17 +22,29 @@ package org.linphone.ui
import android.annotation.SuppressLint
import android.content.res.Configuration
import android.os.Bundle
import android.view.ViewGroup
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.core.view.children
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.compatibility.Compatibility
import org.linphone.core.tools.Log
import org.linphone.utils.ToastUtils
import org.linphone.utils.slideInToastFromTop
import org.linphone.utils.slideInToastFromTopForDuration
open class GenericActivity : AppCompatActivity() {
companion object {
private const val TAG = "[Generic Activity]"
}
private lateinit var toastsArea: ViewGroup
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, true)
@ -57,4 +69,125 @@ open class GenericActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
}
fun setUpToastsArea(viewGroup: ViewGroup) {
toastsArea = viewGroup
}
fun showGreenToast(
message: String,
@DrawableRes icon: Int,
duration: Long = 4000,
doNotTint: Boolean = false
) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val greenToast = ToastUtils.getGreenToast(
this@GenericActivity,
toastsArea,
message,
icon,
doNotTint
)
toastsArea.addView(greenToast.root)
greenToast.root.slideInToastFromTopForDuration(
toastsArea as ViewGroup,
lifecycleScope,
duration
)
}
}
}
fun showBlueToast(
message: String,
@DrawableRes icon: Int,
duration: Long = 4000,
doNotTint: Boolean = false
) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val blueToast = ToastUtils.getBlueToast(
this@GenericActivity,
toastsArea,
message,
icon,
doNotTint
)
toastsArea.addView(blueToast.root)
blueToast.root.slideInToastFromTopForDuration(
toastsArea as ViewGroup,
lifecycleScope,
duration
)
}
}
}
fun showRedToast(
message: String,
@DrawableRes icon: Int,
duration: Long = 4000,
doNotTint: Boolean = false
) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val redToast = ToastUtils.getRedToast(
this@GenericActivity,
toastsArea,
message,
icon,
doNotTint
)
toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTopForDuration(
toastsArea as ViewGroup,
lifecycleScope,
duration
)
}
}
}
fun showPersistentRedToast(
message: String,
@DrawableRes icon: Int,
tag: String,
doNotTint: Boolean = false
) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val redToast =
ToastUtils.getRedToast(
this@GenericActivity,
toastsArea,
message,
icon,
doNotTint
)
redToast.root.tag = tag
toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTop(
toastsArea as ViewGroup,
true
)
}
}
}
fun removePersistentRedToast(tag: String) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
for (child in toastsArea.children) {
if (child.tag == tag) {
toastsArea.removeView(child)
}
}
}
}
}
}

View file

@ -23,12 +23,10 @@ import android.content.pm.PackageManager
import android.os.Bundle
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.annotation.DrawableRes
import androidx.annotation.UiThread
import androidx.core.content.ContextCompat
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
@ -37,8 +35,6 @@ import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantActivityBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.fragment.PermissionsFragmentDirections
import org.linphone.utils.ToastUtils
import org.linphone.utils.slideInToastFromTopForDuration
@UiThread
class AssistantActivity : GenericActivity() {
@ -54,6 +50,8 @@ class AssistantActivity : GenericActivity() {
binding = DataBindingUtil.setContentView(this, R.layout.assistant_activity)
binding.lifecycleOwner = this
setUpToastsArea(binding.toastsArea)
coreContext.postOnCoreThread { core ->
if (core.accountList.isEmpty()) {
Log.i("$TAG No account configured, disabling back gesture")
@ -73,26 +71,6 @@ class AssistantActivity : GenericActivity() {
}
}
fun showGreenToast(message: String, @DrawableRes icon: Int) {
val greenToast = ToastUtils.getGreenToast(this, binding.toastsArea, message, icon)
binding.toastsArea.addView(greenToast.root)
greenToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
fun showRedToast(message: String, @DrawableRes icon: Int) {
val redToast = ToastUtils.getRedToast(this, binding.toastsArea, message, icon)
binding.toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
private fun areAllPermissionsGranted(): Boolean {
for (permission in Compatibility.getAllRequiredPermissionsArray()) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* 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, either version 3 of the License, or
* (at your option) any later version.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.assistant
import android.os.Bundle
import androidx.annotation.UiThread
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantSingleSignOnActivityBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.viewmodel.SingleSignOnViewModel
@UiThread
class SingleSignOnActivity : GenericActivity() {
companion object {
private const val TAG = "[Single Sign On Activity]"
}
private lateinit var binding: AssistantSingleSignOnActivityBinding
private lateinit var viewModel: SingleSignOnViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = run {
ViewModelProvider(this)[SingleSignOnViewModel::class.java]
}
binding = DataBindingUtil.setContentView(this, R.layout.assistant_single_sign_on_activity)
binding.lifecycleOwner = this
setUpToastsArea(binding.toastsArea)
if (intent != null) {
Log.i(
"$TAG Handling intent action [${intent.action}], type [${intent.type}] and data [${intent.data}]"
)
val uri = intent.data?.toString() ?: ""
if (uri.startsWith("linphone-sso:")) {
val ssoUrl = uri.replace("linphone-sso:", "https:")
Log.i("$TAG Setting SSO URL [$ssoUrl]")
viewModel.singleSignOnUrl.value = ssoUrl
}
}
}
}

View file

@ -37,7 +37,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantLandingFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.model.AcceptConditionsAndPolicyDialogModel
import org.linphone.ui.assistant.viewmodel.LandingViewModel
import org.linphone.utils.DialogUtils
@ -132,14 +132,14 @@ class LandingFragment : Fragment() {
viewModel.accountLoginErrorEvent.observe(viewLifecycleOwner) {
it.consume { message ->
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
}
viewModel.redirectToDigestAuthEvent.observe(viewLifecycleOwner) {
/*viewModel.redirectToDigestAuthEvent.observe(viewLifecycleOwner) {
it.consume { address ->
goToLoginFragment(address)
}
@ -149,10 +149,10 @@ class LandingFragment : Fragment() {
it.consume { address ->
goToSingleSignOnFragment(address)
}
}
}*/
}
private fun goToLoginFragment(identity: String) {
/*private fun goToLoginFragment(identity: String) {
Log.i(
"$TAG Going to Linphone credentials based authentication fragment for SIP account [$identity]"
)
@ -162,9 +162,9 @@ class LandingFragment : Fragment() {
private fun goToSingleSignOnFragment(identity: String) {
Log.i("$TAG Going to Single Sign On fragment for SIP account [$identity]")
val action = LandingFragmentDirections.actionLandingFragmentToSingleSignOnFragment(identity)
val action = LandingFragmentDirections.actionLandingFragmentToSingleSignOnFragment()
findNavController().navigate(action)
}
}*/
private fun goToRegisterFragment() {
val action = LandingFragmentDirections.actionLandingFragmentToRegisterFragment()

View file

@ -37,7 +37,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantLoginFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.viewmodel.AccountLoginViewModel
import org.linphone.utils.PhoneNumberUtils
@ -106,7 +106,7 @@ class LoginFragment : Fragment() {
viewModel.accountLoginErrorEvent.observe(viewLifecycleOwner) {
it.consume { message ->
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)

View file

@ -35,7 +35,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantQrCodeScannerFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.viewmodel.QrCodeViewModel
@UiThread
@ -84,7 +84,7 @@ class QrCodeScannerFragment : Fragment() {
viewModel.qrCodeFoundEvent.observe(viewLifecycleOwner) {
it.consume { isValid ->
if (!isValid) {
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
getString(R.string.toast_assistant_qr_code_invalid),
R.drawable.warning_circle
)

View file

@ -41,7 +41,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantRegisterFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.model.ConfirmPhoneNumberDialogModel
import org.linphone.ui.assistant.viewmodel.AccountCreationViewModel
import org.linphone.utils.DialogUtils
@ -130,7 +130,7 @@ class RegisterFragment : Fragment() {
viewModel.pushNotificationsAvailable.observe(viewLifecycleOwner) { available ->
if (!available) {
val text = getString(R.string.assistant_account_register_unavailable_no_push_toast)
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
text,
R.drawable.warning_circle
)
@ -160,7 +160,7 @@ class RegisterFragment : Fragment() {
viewModel.errorHappenedEvent.observe(viewLifecycleOwner) {
it.consume { error ->
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
error,
R.drawable.warning_circle
)

View file

@ -28,13 +28,12 @@ import androidx.annotation.UiThread
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import net.openid.appauth.AuthorizationException
import net.openid.appauth.AuthorizationResponse
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantSingleSignOnFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.viewmodel.SingleSignOnViewModel
@UiThread
@ -49,8 +48,6 @@ class SingleSignOnFragment : Fragment() {
private lateinit var viewModel: SingleSignOnViewModel
private val args: SingleSignOnFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -65,12 +62,15 @@ class SingleSignOnFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner
viewModel = ViewModelProvider(this)[SingleSignOnViewModel::class.java]
viewModel = requireActivity().run {
ViewModelProvider(this)[SingleSignOnViewModel::class.java]
}
binding.viewModel = viewModel
val identity = args.sipIdentity
Log.i("$TAG SIP Identity found in arguments is [$identity]")
viewModel.preFilledUser = identity
viewModel.singleSignOnUrl.observe(viewLifecycleOwner) { url ->
Log.i("$TAG SSO URL found [$url], setting it up")
viewModel.setUp()
}
viewModel.singleSignOnProcessCompletedEvent.observe(viewLifecycleOwner) {
it.consume {
@ -88,15 +88,17 @@ class SingleSignOnFragment : Fragment() {
viewModel.onErrorEvent.observe(viewLifecycleOwner) {
it.consume { errorMessage ->
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
errorMessage,
R.drawable.warning_circle
)
findNavController().popBackStack()
try {
findNavController().popBackStack()
} catch (ise: IllegalStateException) {
// Excepted in SingleSignOnActivity as no NavController is set
}
}
}
viewModel.setUp()
}
@Deprecated("Deprecated in Java")

View file

@ -36,7 +36,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantThirdPartySipAccountLoginFragmentBinding
import org.linphone.ui.assistant.AssistantActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.assistant.viewmodel.ThirdPartySipAccountLoginViewModel
import org.linphone.utils.PhoneNumberUtils
@ -111,7 +111,7 @@ class ThirdPartySipAccountLoginFragment : Fragment() {
viewModel.accountLoginErrorEvent.observe(viewLifecycleOwner) {
it.consume { message ->
(requireActivity() as AssistantActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)

View file

@ -23,7 +23,6 @@ import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.utils.Event
class LandingViewModel @UiThread constructor() : AccountLoginViewModel() {
companion object {
@ -38,13 +37,13 @@ class LandingViewModel @UiThread constructor() : AccountLoginViewModel() {
val hideThirdPartyAccount = MutableLiveData<Boolean>()
val redirectToDigestAuthEvent: MutableLiveData<Event<String>> by lazy {
/*val redirectToDigestAuthEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val redirectToSingleSignOnEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
}*/
var conditionsAndPrivacyPolicyAccepted = false

View file

@ -44,13 +44,14 @@ class SingleSignOnViewModel : ViewModel() {
companion object {
private const val TAG = "[Single Sign On ViewModel]"
private const val WELL_KNOWN = "https://sso.onhexagone.com/realms/ONHEXAGONE/.well-known/openid-configuration"
private const val CLIENT_ID = "linphone"
private const val REDIRECT_URI = "org.linphone:/openidcallback"
}
val singleSignOnProcessCompletedEvent = MutableLiveData<Event<Boolean>>()
val singleSignOnUrl = MutableLiveData<String>()
val startAuthIntentEvent: MutableLiveData<Event<Intent>> by lazy {
MutableLiveData<Event<Intent>>()
}
@ -59,7 +60,7 @@ class SingleSignOnViewModel : ViewModel() {
MutableLiveData<Event<String>>()
}
var preFilledUser: String = ""
private var preFilledUser: String = ""
private lateinit var authState: AuthState
private lateinit var authService: AuthorizationService
@ -93,7 +94,7 @@ class SingleSignOnViewModel : ViewModel() {
private fun singleSignOn() {
Log.i("$TAG Fetch from issuer")
AuthorizationServiceConfiguration.fetchFromUrl(
Uri.parse(WELL_KNOWN),
Uri.parse(singleSignOnUrl.value),
AuthorizationServiceConfiguration.RetrieveConfigurationCallback { serviceConfiguration, ex ->
if (ex != null) {
Log.e("$TAG Failed to fetch configuration")

View file

@ -23,14 +23,11 @@ import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.DrawableRes
import androidx.annotation.UiThread
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.children
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@ -58,9 +55,6 @@ import org.linphone.ui.call.model.AudioDeviceModel
import org.linphone.ui.call.viewmodel.CallsViewModel
import org.linphone.ui.call.viewmodel.CurrentCallViewModel
import org.linphone.ui.call.viewmodel.SharedCallViewModel
import org.linphone.utils.ToastUtils
import org.linphone.utils.slideInToastFromTop
import org.linphone.utils.slideInToastFromTopForDuration
@UiThread
class CallActivity : GenericActivity() {
@ -106,6 +100,8 @@ class CallActivity : GenericActivity() {
binding = DataBindingUtil.setContentView(this, R.layout.call_activity)
binding.lifecycleOwner = this
setUpToastsArea(binding.toastsArea)
lifecycleScope.launch(Dispatchers.Main) {
WindowInfoTracker
.getOrCreate(this@CallActivity)
@ -327,78 +323,6 @@ class CallActivity : GenericActivity() {
}
}
fun showBlueToast(message: String, @DrawableRes icon: Int, doNotTint: Boolean = false) {
val blueToast = ToastUtils.getBlueToast(this, binding.toastsArea, message, icon, doNotTint)
binding.toastsArea.addView(blueToast.root)
blueToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
fun showRedToast(
message: String,
@DrawableRes icon: Int,
duration: Long = 4000,
doNotTint: Boolean = false
) {
val redToast = ToastUtils.getRedToast(this, binding.toastsArea, message, icon, doNotTint)
binding.toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope,
duration
)
}
fun showPersistentRedToast(
message: String,
@DrawableRes icon: Int,
tag: String,
doNotTint: Boolean = false
) {
val redToast = ToastUtils.getRedToast(this, binding.toastsArea, message, icon, doNotTint)
redToast.root.tag = tag
binding.toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTop(
binding.toastsArea as ViewGroup,
true
)
}
fun removePersistentRedToast(tag: String) {
for (child in binding.toastsArea.children) {
if (child.tag == tag) {
binding.toastsArea.removeView(child)
}
}
}
fun showGreenToast(
message: String,
@DrawableRes icon: Int,
duration: Long = 4000,
doNotTint: Boolean = false
) {
val greenToast = ToastUtils.getGreenToast(
this,
binding.toastsArea,
message,
icon,
doNotTint
)
binding.toastsArea.addView(greenToast.root)
greenToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope,
duration
)
}
private fun navigateToActiveCall(notInConference: Boolean) {
val navController = findNavController(R.id.call_nav_container)
val action = when (navController.currentDestination?.id) {

View file

@ -40,6 +40,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.CallActiveFragmentBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.call.CallActivity
import org.linphone.ui.call.model.ZrtpSasConfirmationDialogModel
import org.linphone.ui.call.viewmodel.CallsViewModel
@ -242,7 +243,7 @@ class ActiveCallFragment : GenericCallFragment() {
dialog.dismiss()
if (verified) {
(requireActivity() as CallActivity).showBlueToast(
(requireActivity() as GenericActivity).showBlueToast(
getString(R.string.toast_call_can_be_trusted),
R.drawable.trusted,
doNotTint = true
@ -312,7 +313,7 @@ class ActiveCallFragment : GenericCallFragment() {
if (isRemoteRecording) {
Log.i("$TAG Showing [$displayName] is recording toast")
val message = getString(R.string.call_remote_is_recording, displayName)
(requireActivity() as CallActivity).showPersistentRedToast(
(requireActivity() as GenericActivity).showPersistentRedToast(
message,
R.drawable.record_fill,
toastTag
@ -349,7 +350,7 @@ class ActiveCallFragment : GenericCallFragment() {
callViewModel.chatRoomCreationErrorEvent.observe(viewLifecycleOwner) {
it.consume { error ->
(requireActivity() as CallActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
error,
R.drawable.warning_circle
)

View file

@ -57,7 +57,7 @@ import org.linphone.core.ChatMessage
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatBubbleLongPressMenuBinding
import org.linphone.databinding.ChatConversationFragmentBinding
import org.linphone.ui.call.CallActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.ConversationScrollListener
import org.linphone.ui.main.chat.adapter.ConversationEventAdapter
import org.linphone.ui.main.chat.adapter.MessageBottomSheetAdapter
@ -264,7 +264,7 @@ class ConversationFragment : GenericCallFragment() {
Log.e("$TAG Failed to find conversation, going back")
findNavController().popBackStack()
val message = getString(R.string.toast_cant_find_conversation_to_display)
(requireActivity() as CallActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
@ -364,7 +364,7 @@ class ConversationFragment : GenericCallFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as CallActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
@ -402,7 +402,7 @@ class ConversationFragment : GenericCallFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as CallActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
@ -410,7 +410,7 @@ class ConversationFragment : GenericCallFragment() {
it.consume {
val message = getString(R.string.conversation_message_deleted_toast)
val icon = R.drawable.trash_simple
(requireActivity() as CallActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
}
}
binding.sendArea.messageToSend.setControlEnterListener(object :

View file

@ -29,12 +29,9 @@ import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import android.view.Gravity
import android.view.ViewGroup
import androidx.annotation.DrawableRes
import androidx.annotation.MainThread
import androidx.annotation.UiThread
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.children
import androidx.core.view.doOnAttach
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
@ -43,11 +40,9 @@ import androidx.navigation.NavController
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
@ -65,9 +60,6 @@ import org.linphone.utils.DialogUtils
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.ToastUtils
import org.linphone.utils.slideInToastFromTop
import org.linphone.utils.slideInToastFromTopForDuration
@UiThread
class MainActivity : GenericActivity() {
@ -98,6 +90,8 @@ class MainActivity : GenericActivity() {
binding = DataBindingUtil.setContentView(this, R.layout.main_activity)
binding.lifecycleOwner = this
setUpToastsArea(binding.toastsArea)
while (!coreContext.isReady()) {
Thread.sleep(50)
}
@ -293,102 +287,6 @@ class MainActivity : GenericActivity() {
return findNavController(R.id.main_nav_host_fragment)
}
fun showGreenToast(message: String, @DrawableRes icon: Int) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val greenToast = ToastUtils.getGreenToast(
this@MainActivity,
binding.toastsArea,
message,
icon
)
binding.toastsArea.addView(greenToast.root)
greenToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
}
}
fun showBlueToast(message: String, @DrawableRes icon: Int) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val blueToast = ToastUtils.getBlueToast(
this@MainActivity,
binding.toastsArea,
message,
icon
)
binding.toastsArea.addView(blueToast.root)
blueToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
}
}
fun showRedToast(message: String, @DrawableRes icon: Int) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val redToast = ToastUtils.getRedToast(
this@MainActivity,
binding.toastsArea,
message,
icon
)
binding.toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTopForDuration(
binding.toastsArea as ViewGroup,
lifecycleScope
)
}
}
}
private fun showPersistentRedToast(
message: String,
@DrawableRes icon: Int,
tag: String,
doNotTint: Boolean = false
) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
val redToast =
ToastUtils.getRedToast(
this@MainActivity,
binding.toastsArea,
message,
icon,
doNotTint
)
redToast.root.tag = tag
binding.toastsArea.addView(redToast.root)
redToast.root.slideInToastFromTop(
binding.toastsArea as ViewGroup,
true
)
}
}
}
private fun removePersistentRedToast(tag: String) {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
for (child in binding.toastsArea.children) {
if (child.tag == tag) {
binding.toastsArea.removeView(child)
}
}
}
}
}
@MainThread
private fun handleIntent(intent: Intent, isNewIntent: Boolean) {
Log.i(
@ -627,9 +525,15 @@ class MainActivity : GenericActivity() {
Log.i("$TAG Found URI [$uri] as data for intent [${intent.action}]")
val sipUriToCall = if (uri.startsWith("tel:")) {
uri.substring("tel:".length)
} else if (uri.startsWith("sip-linphone:")) {
uri.replace("sip-linphone:", "sip:")
} else {
uri
}.replace("%40", "@") // Unescape @ character if needed
if (uri.startsWith("sips-linphone:")) {
uri.replace("sips-linphone:", "sips:")
} else {
uri
}.replace("%40", "@") // Unescape @ character if needed
}
coreContext.postOnCoreThread {
val address = coreContext.core.interpretUrl(

View file

@ -35,7 +35,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatDocumentsFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.adapter.ConversationsFilesAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationDocumentsListViewModel
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
@ -157,7 +157,7 @@ class ConversationDocumentsListFragment : SlidingPaneChildFragment() {
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
}

View file

@ -74,6 +74,7 @@ import org.linphone.core.tools.Log
import org.linphone.databinding.ChatBubbleLongPressMenuBinding
import org.linphone.databinding.ChatConversationFragmentBinding
import org.linphone.databinding.ChatConversationPopupMenuBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.ConversationScrollListener
import org.linphone.ui.main.chat.adapter.ConversationEventAdapter
@ -403,7 +404,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
Log.e("$TAG Failed to find conversation, going back")
goBack()
val message = getString(R.string.toast_cant_find_conversation_to_display)
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
@ -575,7 +576,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
@ -645,7 +646,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
@ -653,7 +654,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
it.consume {
val message = getString(R.string.conversation_message_deleted_toast)
val icon = R.drawable.trash_simple
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
sharedViewModel.forceRefreshConversations.value = Event(true)
}
}

View file

@ -36,7 +36,7 @@ import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatInfoFragmentBinding
import org.linphone.databinding.ChatParticipantAdminPopupMenuBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.adapter.ConversationParticipantsAdapter
import org.linphone.ui.main.chat.model.ParticipantModel
import org.linphone.ui.main.chat.viewmodel.ConversationInfoViewModel
@ -116,7 +116,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
Log.e("$TAG Failed to find conversation, going back")
goBack()
val message = getString(R.string.toast_cant_find_conversation_to_display)
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
@ -135,7 +135,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
sharedViewModel.forceRefreshConversationInfo.value = Event(true)
goBack()
val message = getString(R.string.toast_group_conversation_left)
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
message,
R.drawable.chat_teardrop_text
)
@ -148,7 +148,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
sharedViewModel.forceRefreshConversationEvents.value = Event(true)
goBack()
val message = getString(R.string.toast_conversation_history_deleted)
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
message,
R.drawable.chat_teardrop_text
)
@ -181,7 +181,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
}
}
@ -189,7 +189,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
@ -261,7 +261,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
} else {
Log.e("$TAG Can't go to contact page, friend ref key is null or empty!")
val message = getString(R.string.toast_cant_find_contact_to_display)
(requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
}
@ -275,7 +278,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
} else {
Log.e("$TAG Can't add empty/null SIP URI to contacts!")
val message = getString(R.string.toast_no_address_to_add_to_contact)
(requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
}
@ -340,7 +346,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
} else {
Log.e("$TAG Can't go to contact page, friend ref key is null or empty!")
val message = getString(R.string.toast_cant_find_contact_to_display)
(requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
popupWindow.dismiss()
}
@ -355,7 +364,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
} else {
Log.e("$TAG Can't add empty/null SIP URI to contacts!")
val message = getString(R.string.toast_no_address_to_add_to_contact)
(requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
popupWindow.dismiss()
}

View file

@ -36,7 +36,7 @@ import androidx.recyclerview.widget.RecyclerView
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatMediaFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.adapter.ConversationsFilesAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
@ -166,7 +166,7 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
}

View file

@ -36,7 +36,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatListFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.adapter.ConversationsListAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationsListViewModel
import org.linphone.ui.main.fragment.AbstractTopBarFragment
@ -250,7 +250,7 @@ class ConversationsListFragment : AbstractTopBarFragment() {
// Do not consume it yet
val message = getString(R.string.toast_message_waiting_to_be_forwarded)
val icon = R.drawable.forward
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
Log.i("$TAG Found a message waiting to be forwarded")
}
}
@ -264,7 +264,7 @@ class ConversationsListFragment : AbstractTopBarFragment() {
filesToShare.size.toString()
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
Log.i("$TAG Found [$count] files waiting to be shared")
}
}
@ -273,7 +273,7 @@ class ConversationsListFragment : AbstractTopBarFragment() {
if (textToShare.isNotEmpty()) {
val message = getString(R.string.toast_text_waiting_to_be_shared)
val icon = R.drawable.file_text
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
Log.i("$TAG Found text waiting to be shared")
}
}

View file

@ -32,7 +32,7 @@ import org.linphone.core.Address
import org.linphone.core.Friend
import org.linphone.core.tools.Log
import org.linphone.databinding.StartChatFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.viewmodel.StartConversationViewModel
import org.linphone.ui.main.fragment.GenericAddressPickerFragment
import org.linphone.ui.main.fragment.GroupSetOrEditSubjectDialogModel
@ -105,7 +105,10 @@ class StartConversationFragment : GenericAddressPickerFragment() {
viewModel.chatRoomCreationErrorEvent.observe(viewLifecycleOwner) {
it.consume { error ->
Log.i("$TAG Conversation creation error, showing red toast")
(requireActivity() as MainActivity).showRedToast(error, R.drawable.warning_circle)
(requireActivity() as GenericActivity).showRedToast(
error,
R.drawable.warning_circle
)
}
}

View file

@ -44,7 +44,7 @@ import org.linphone.R
import org.linphone.core.Factory
import org.linphone.core.tools.Log
import org.linphone.databinding.ContactFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.main.contacts.model.TrustCallDialogModel
import org.linphone.ui.main.contacts.viewmodel.ContactViewModel
@ -246,7 +246,7 @@ class ContactFragment : SlidingPaneChildFragment() {
} else {
getString(R.string.toast_phone_number_copied_to_clipboard)
}
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
message,
R.drawable.check
)

View file

@ -40,6 +40,7 @@ import org.linphone.BR
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ContactNewOrEditFragmentBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.contacts.model.NewOrEditNumberOrAddressModel
import org.linphone.ui.main.contacts.viewmodel.ContactNewOrEditViewModel
@ -154,7 +155,7 @@ class EditContactFragment : SlidingPaneChildFragment() {
it.consume { refKey ->
if (refKey.isNotEmpty()) {
Log.i("$TAG Changes were applied, going back to details page")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.contact_editor_saved_changes_toast),
R.drawable.info
)
@ -162,7 +163,7 @@ class EditContactFragment : SlidingPaneChildFragment() {
backPressedCallback.isEnabled = false
findNavController().popBackStack()
} else {
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
getString(R.string.contact_editor_error_saving_changes_toast),
R.drawable.warning_circle
)

View file

@ -39,6 +39,7 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ContactNewOrEditFragmentBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.contacts.model.NewOrEditNumberOrAddressModel
import org.linphone.ui.main.contacts.viewmodel.ContactNewOrEditViewModel
@ -142,12 +143,12 @@ class NewContactFragment : GenericFragment() {
findNavController().popBackStack()
sharedViewModel.showContactEvent.value = Event(refKey)
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.contact_editor_saved_contact_toast),
R.drawable.info
)
} else {
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
getString(R.string.contact_editor_error_saving_contact_toast),
R.drawable.warning_circle
)

View file

@ -21,7 +21,7 @@ import kotlinx.coroutines.launch
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.FileViewerFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.file_media_viewer.adapter.PdfPagesListAdapter
import org.linphone.ui.main.file_media_viewer.viewmodel.FileViewModel
import org.linphone.ui.main.fragment.GenericFragment
@ -143,7 +143,7 @@ class FileViewerFragment : GenericFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showGreenToast(message, icon)
(requireActivity() as GenericActivity).showGreenToast(message, icon)
}
}
@ -151,7 +151,7 @@ class FileViewerFragment : GenericFragment() {
it.consume { pair ->
val message = pair.first
val icon = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
}

View file

@ -38,7 +38,7 @@ import kotlinx.coroutines.withContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.FileMediaViewerFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel
import org.linphone.ui.main.file_media_viewer.adapter.MediaListAdapter
import org.linphone.ui.main.fragment.GenericFragment
@ -179,7 +179,7 @@ class MediaListViewerFragment : GenericFragment() {
val message = AppUtils.getString(
R.string.toast_file_successfully_exported_to_media_store
)
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
message,
R.drawable.check
)
@ -188,7 +188,7 @@ class MediaListViewerFragment : GenericFragment() {
val message = AppUtils.getString(
R.string.toast_export_file_to_media_store_error
)
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)

View file

@ -31,7 +31,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.HelpDebugFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.help.viewmodel.HelpViewModel
@ -66,7 +66,7 @@ class DebugFragment : GenericFragment() {
viewModel.debugLogsCleanedEvent.observe(viewLifecycleOwner) {
it.consume {
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.help_troubleshooting_debug_logs_cleaned_toast_message),
R.drawable.info
)
@ -106,7 +106,7 @@ class DebugFragment : GenericFragment() {
viewModel.uploadDebugLogsErrorEvent.observe(viewLifecycleOwner) {
it.consume {
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
getString(R.string.help_troubleshooting_debug_logs_upload_error_toast_message),
R.drawable.warning_circle
)

View file

@ -12,7 +12,7 @@ import androidx.navigation.navGraphViewModels
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.HelpFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.help.viewmodel.HelpViewModel
import org.linphone.ui.main.history.model.ConfirmationDialogModel
@ -99,7 +99,7 @@ class HelpFragment : GenericFragment() {
viewModel.versionUpToDateEvent.observe(viewLifecycleOwner) {
it.consume {
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.help_version_up_to_date_toast_message),
R.drawable.info
)
@ -108,7 +108,7 @@ class HelpFragment : GenericFragment() {
viewModel.errorEvent.observe(viewLifecycleOwner) {
it.consume {
(requireActivity() as MainActivity).showRedToast(
(requireActivity() as GenericActivity).showRedToast(
getString(R.string.help_error_checking_version_toast_message),
R.drawable.warning_circle
)

View file

@ -39,7 +39,7 @@ import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.HistoryContactFragmentBinding
import org.linphone.databinding.HistoryContactPopupMenuBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.ui.main.history.adapter.ContactHistoryListAdapter
import org.linphone.ui.main.history.model.ConfirmationDialogModel
@ -138,7 +138,7 @@ class HistoryContactFragment : SlidingPaneChildFragment() {
it.consume {
sharedViewModel.forceRefreshCallLogsListEvent.value = Event(true)
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.toast_call_history_deleted),
R.drawable.check
)
@ -175,7 +175,7 @@ class HistoryContactFragment : SlidingPaneChildFragment() {
val label = "SIP address"
clipboard.setPrimaryClip(ClipData.newPlainText(label, value))
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.toast_sip_address_copied_to_clipboard),
R.drawable.check
)

View file

@ -43,7 +43,7 @@ import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.HistoryListFragmentBinding
import org.linphone.databinding.HistoryListPopupMenuBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.AbstractTopBarFragment
import org.linphone.ui.main.history.adapter.HistoryListAdapter
import org.linphone.ui.main.history.model.ConfirmationDialogModel
@ -203,7 +203,7 @@ class HistoryListFragment : AbstractTopBarFragment() {
listViewModel.historyDeletedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.w("$TAG All call logs have been deleted")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.toast_call_history_deleted),
R.drawable.check
)
@ -279,7 +279,7 @@ class HistoryListFragment : AbstractTopBarFragment() {
val label = "SIP address"
clipboard.setPrimaryClip(ClipData.newPlainText(label, value))
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.toast_sip_address_copied_to_clipboard),
R.drawable.check
)

View file

@ -36,7 +36,7 @@ import com.google.android.material.timepicker.TimeFormat
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MeetingEditFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.ui.main.meetings.viewmodel.ScheduleMeetingViewModel
import org.linphone.utils.Event
@ -168,7 +168,7 @@ class EditMeetingFragment : SlidingPaneChildFragment() {
viewModel.conferenceCreatedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Conference was scheduled, leaving fragment and ask list to refresh")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.meeting_info_updated_toast),
R.drawable.check
)

View file

@ -41,7 +41,7 @@ import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MeetingFragmentBinding
import org.linphone.databinding.MeetingPopupMenuBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.ui.main.history.model.ConfirmationDialogModel
import org.linphone.ui.main.meetings.viewmodel.MeetingViewModel
@ -147,7 +147,7 @@ class MeetingFragment : SlidingPaneChildFragment() {
viewModel.conferenceInfoDeletedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Meeting info has been deleted successfully")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.meeting_info_deleted_toast),
R.drawable.trash_simple
)
@ -159,7 +159,7 @@ class MeetingFragment : SlidingPaneChildFragment() {
viewModel.conferenceCancelledEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Meeting has been cancelled successfully, deleting it")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.meeting_info_cancelled_toast),
R.drawable.trash_simple
)
@ -208,7 +208,7 @@ class MeetingFragment : SlidingPaneChildFragment() {
val label = "Meeting SIP address"
clipboard.setPrimaryClip(ClipData.newPlainText(label, meetingSipUri))
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.toast_meeting_address_copied_to_clipboard),
R.drawable.check
)

View file

@ -37,9 +37,9 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MeetingWaitingRoomFragmentBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.call.fragment.AudioDevicesMenuDialogFragment
import org.linphone.ui.call.model.AudioDeviceModel
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.meetings.viewmodel.MeetingWaitingRoomViewModel
@ -140,7 +140,7 @@ class MeetingWaitingRoomFragment : GenericFragment() {
R.string.toast_failed_to_join_conference
)
val icon = R.drawable.warning_circle
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}

View file

@ -36,7 +36,7 @@ import com.google.android.material.timepicker.TimeFormat
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MeetingScheduleFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.meetings.viewmodel.ScheduleMeetingViewModel
import org.linphone.utils.Event
@ -170,7 +170,7 @@ class ScheduleMeetingFragment : GenericFragment() {
viewModel.conferenceCreatedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Conference was scheduled, leaving fragment and ask list to refresh")
(requireActivity() as MainActivity).showGreenToast(
(requireActivity() as GenericActivity).showGreenToast(
getString(R.string.meeting_info_created_toast),
R.drawable.check
)

View file

@ -9,7 +9,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.navArgs
import org.linphone.core.tools.Log
import org.linphone.databinding.SettingsContactsCarddavBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.settings.viewmodel.CardDavViewModel
@ -66,7 +66,7 @@ class CardDavAddressBookConfigurationFragment : GenericFragment() {
it.consume { pair ->
val icon = pair.first
val message = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
}

View file

@ -9,7 +9,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.navArgs
import org.linphone.core.tools.Log
import org.linphone.databinding.SettingsContactsLdapBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.GenericActivity
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.settings.viewmodel.LdapViewModel
@ -65,7 +65,7 @@ class LdapServerConfigurationFragment : GenericFragment() {
it.consume { pair ->
val icon = pair.first
val message = pair.second
(requireActivity() as MainActivity).showRedToast(message, icon)
(requireActivity() as GenericActivity).showRedToast(message, icon)
}
}
}

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.assistant.AssistantActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/sso_fragment"
android:name="org.linphone.ui.assistant.fragment.SingleSignOnFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<LinearLayout
android:id="@+id/toasts_area"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/toast_top_margin"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
app:layout_constraintWidth_max="@dimen/toast_max_width"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View file

@ -190,10 +190,6 @@
android:id="@+id/singleSignOnFragment"
android:name="org.linphone.ui.assistant.fragment.SingleSignOnFragment"
android:label="SingleSignOnFragment"
tools:layout="@layout/assistant_single_sign_on_fragment">
<argument
android:name="sipIdentity"
app:argType="string" />
</fragment>
tools:layout="@layout/assistant_single_sign_on_fragment" />
</navigation>