dialpad moved from bottom navigation tab to a separate activity ()

This commit is contained in:
Nikita Fedrunov 2022-08-19 17:55:43 +02:00 committed by GitHub
parent 0629cae183
commit cc49e96d36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 43 deletions
changelog.d
vector/src/main
AndroidManifest.xml
java/im/vector/app/features
res/menu

1
changelog.d/6787.wip Normal file
View file

@ -0,0 +1 @@
[App Layout] Dialpad moved from bottom navigation tab to a separate activity accessed via home screen context menu

View file

@ -348,6 +348,7 @@
<activity android:name=".features.location.LocationSharingActivity" /> <activity android:name=".features.location.LocationSharingActivity" />
<activity android:name=".features.location.live.map.LiveLocationMapViewActivity" /> <activity android:name=".features.location.live.map.LiveLocationMapViewActivity" />
<activity android:name=".features.settings.font.FontScaleSettingActivity"/> <activity android:name=".features.settings.font.FontScaleSettingActivity"/>
<activity android:name=".features.call.dialpad.PstnDialActivity" />
<!-- Services --> <!-- Services -->

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.call.dialpad
import android.os.Bundle
import androidx.appcompat.app.AppCompatDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.createdirect.DirectRoomHelper
import im.vector.app.features.settings.VectorLocale
import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
import javax.inject.Inject
@AndroidEntryPoint
class PstnDialActivity : SimpleFragmentActivity() {
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var directRoomHelper: DirectRoomHelper
@Inject lateinit var session: Session
@Inject lateinit var errorFormatter: ErrorFormatter
private var progress: AppCompatDialog? = null
override fun getTitleRes(): Int = R.string.call
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isFirstCreation()) {
addFragment(
views.container,
createDialPadFragment()
)
}
}
private fun handleStartCallWithPhoneNumber(rawNumber: String) {
lifecycleScope.launch {
try {
showLoadingDialog()
val result = DialPadLookup(session, callManager, directRoomHelper).lookupPhoneNumber(rawNumber)
callManager.startOutgoingCall(result.roomId, result.userId, isVideoCall = false)
dismissLoadingDialog()
finish()
} catch (failure: Throwable) {
dismissLoadingDialog()
displayErrorDialog(failure)
}
}
}
private fun createDialPadFragment(): Fragment {
val fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, DialPadFragment::class.java.name)
return (fragment as DialPadFragment).apply {
arguments = Bundle().apply {
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country)
}
callback = object : DialPadFragment.Callback {
override fun onOkClicked(formatted: String?, raw: String?) {
if (raw.isNullOrEmpty()) return
handleStartCallWithPhoneNumber(raw)
}
}
}
}
private fun showLoadingDialog() {
progress?.dismiss()
progress = MaterialProgressDialog(this)
.show(getString(R.string.please_wait))
}
private fun dismissLoadingDialog() {
progress?.dismiss()
}
private fun displayErrorDialog(throwable: Throwable) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.dialog_title_error)
.setMessage(errorFormatter.toHumanReadable(throwable))
.setPositiveButton(R.string.ok, null)
.show()
}
}

View file

@ -16,13 +16,13 @@
package im.vector.app.features.home package im.vector.app.features.home
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
@ -42,12 +42,11 @@ import im.vector.app.core.ui.views.KeysBackupBanner
import im.vector.app.databinding.FragmentNewHomeDetailBinding import im.vector.app.databinding.FragmentNewHomeDetailBinding
import im.vector.app.features.call.SharedKnownCallsViewModel import im.vector.app.features.call.SharedKnownCallsViewModel
import im.vector.app.features.call.VectorCallActivity import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.dialpad.DialPadFragment import im.vector.app.features.call.dialpad.PstnDialActivity
import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.home.room.list.home.HomeRoomListFragment import im.vector.app.features.home.room.list.home.HomeRoomListFragment
import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.popup.VerificationVectorAlert import im.vector.app.features.popup.VerificationVectorAlert
import im.vector.app.features.settings.VectorLocale
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.settings.VectorSettingsActivity.Companion.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS import im.vector.app.features.settings.VectorSettingsActivity.Companion.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -99,6 +98,10 @@ class NewHomeDetailFragment @Inject constructor(
viewModel.handle(HomeDetailAction.MarkAllRoomsRead) viewModel.handle(HomeDetailAction.MarkAllRoomsRead)
true true
} }
R.id.menu_home_dialpad -> {
startActivity(Intent(requireContext(), PstnDialActivity::class.java))
true
}
else -> false else -> false
} }
} }
@ -107,6 +110,7 @@ class NewHomeDetailFragment @Inject constructor(
withState(viewModel) { state -> withState(viewModel) { state ->
val isRoomList = state.currentTab is HomeTab.RoomList val isRoomList = state.currentTab is HomeTab.RoomList
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms
menu.findItem(R.id.menu_home_dialpad).isVisible = state.showDialPadTab
} }
} }
@ -138,14 +142,10 @@ class NewHomeDetailFragment @Inject constructor(
updateUIForTab(currentTab) updateUIForTab(currentTab)
} }
viewModel.onEach(HomeDetailViewState::showDialPadTab) { showDialPadTab ->
updateTabVisibilitySafely(R.id.bottom_action_dial_pad, showDialPadTab)
}
viewModel.observeViewEvents { viewEvent -> viewModel.observeViewEvents { viewEvent ->
when (viewEvent) { when (viewEvent) {
HomeDetailViewEvents.CallStarted -> handleCallStarted() HomeDetailViewEvents.CallStarted -> Unit
is HomeDetailViewEvents.FailToCall -> showFailure(viewEvent.failure) is HomeDetailViewEvents.FailToCall -> Unit
HomeDetailViewEvents.Loading -> showLoadingDialog() HomeDetailViewEvents.Loading -> showLoadingDialog()
} }
} }
@ -186,12 +186,6 @@ class NewHomeDetailFragment @Inject constructor(
sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace) sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace)
} }
private fun handleCallStarted() {
dismissLoadingDialog()
val fragmentTag = HomeTab.DialPad.toFragmentTag()
(childFragmentManager.findFragmentByTag(fragmentTag) as? DialPadFragment)?.clear()
}
override fun onDestroyView() { override fun onDestroyView() {
currentCallsViewPresenter.unBind() currentCallsViewPresenter.unBind()
super.onDestroyView() super.onDestroyView()
@ -339,30 +333,15 @@ class NewHomeDetailFragment @Inject constructor(
add(R.id.roomListContainer, HomeRoomListFragment::class.java, null, fragmentTag) add(R.id.roomListContainer, HomeRoomListFragment::class.java, null, fragmentTag)
} }
is HomeTab.DialPad -> { is HomeTab.DialPad -> {
add(R.id.roomListContainer, createDialPadFragment(), fragmentTag) throw NotImplementedError("this tab shouldn't exists when app layout is enabled")
} }
} }
} else { } else {
if (tab is HomeTab.DialPad) {
(fragmentToShow as? DialPadFragment)?.applyCallback()
}
attach(fragmentToShow) attach(fragmentToShow)
} }
} }
} }
private fun createDialPadFragment(): Fragment {
val fragment = childFragmentManager.fragmentFactory.instantiate(vectorBaseActivity.classLoader, DialPadFragment::class.java.name)
return (fragment as DialPadFragment).apply {
arguments = Bundle().apply {
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country)
}
applyCallback()
}
}
private fun updateTabVisibilitySafely(tabId: Int, isVisible: Boolean) { private fun updateTabVisibilitySafely(tabId: Int, isVisible: Boolean) {
val wasVisible = views.bottomNavigationView.menu.findItem(tabId).isVisible val wasVisible = views.bottomNavigationView.menu.findItem(tabId).isVisible
views.bottomNavigationView.menu.findItem(tabId).isVisible = isVisible views.bottomNavigationView.menu.findItem(tabId).isVisible = isVisible
@ -439,16 +418,6 @@ class NewHomeDetailFragment @Inject constructor(
} }
} }
private fun DialPadFragment.applyCallback(): DialPadFragment {
callback = object : DialPadFragment.Callback {
override fun onOkClicked(formatted: String?, raw: String?) {
if (raw.isNullOrEmpty()) return
viewModel.handle(HomeDetailAction.StartCallWithPhoneNumber(raw))
}
}
return this
}
override fun onBackPressed(toolbarButton: Boolean) = if (spaceStateHandler.getCurrentSpace() != null) { override fun onBackPressed(toolbarButton: Boolean) = if (spaceStateHandler.getCurrentSpace() != null) {
navigateBack() navigateBack()
true true

View file

@ -1,9 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item <item
android:id="@+id/menu_home_mark_all_as_read" android:id="@+id/menu_home_mark_all_as_read"
android:icon="@drawable/ic_material_done" android:icon="@drawable/ic_material_done"
android:title="@string/action_mark_all_as_read" /> android:title="@string/action_mark_all_as_read" />
</menu> <item
android:id="@+id/menu_home_dialpad"
android:title="@string/call_dial_pad_title"
android:visible="false"
app:showAsAction="never"
tools:visible="true" />
</menu>