mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Dial pad: clean some code, remove useless method and allow cursor
This commit is contained in:
parent
856481e6bc
commit
3a8a8d5b78
4 changed files with 123 additions and 105 deletions
|
@ -61,6 +61,7 @@ class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCa
|
|||
arguments = Bundle().apply {
|
||||
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, showActions)
|
||||
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, showActions)
|
||||
putBoolean(DialPadFragment.EXTRA_CURSOR_VISIBLE, false)
|
||||
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country)
|
||||
}
|
||||
callback = DialPadFragmentCallbackWrapper(this@CallDialPadBottomSheet.callback)
|
||||
|
@ -88,10 +89,6 @@ class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCa
|
|||
|
||||
private inner class DialPadFragmentCallbackWrapper(val callback: DialPadFragment.Callback?): DialPadFragment.Callback {
|
||||
|
||||
override fun onDigitAppended(digit: String) {
|
||||
callback?.onDigitAppended(digit)
|
||||
}
|
||||
|
||||
override fun onOkClicked(formatted: String?, raw: String?) {
|
||||
callback?.onOkClicked(formatted, raw)
|
||||
dismiss()
|
||||
|
|
|
@ -16,8 +16,18 @@
|
|||
|
||||
package im.vector.app.features.call.dialpad
|
||||
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.telephony.PhoneNumberFormattingTextWatcher
|
||||
import android.telephony.PhoneNumberUtils
|
||||
import android.text.Editable
|
||||
import android.text.InputType
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
import android.text.method.DialerKeyListener
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -26,24 +36,20 @@ import androidx.core.widget.ImageViewCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import com.android.dialer.dialpadview.DialpadView
|
||||
import com.android.dialer.dialpadview.DigitsEditText
|
||||
import com.google.i18n.phonenumbers.AsYouTypeFormatter
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
class DialPadFragment : Fragment() {
|
||||
class DialPadFragment : Fragment(), TextWatcher {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
private var digits: DigitsEditText? = null
|
||||
private var formatter: AsYouTypeFormatter? = null
|
||||
private var input = ""
|
||||
private lateinit var digits: DigitsEditText
|
||||
private var regionCode: String = DEFAULT_REGION_CODE
|
||||
private var formatAsYouType = true
|
||||
private var enableStar = true
|
||||
private var enablePound = true
|
||||
private var enablePlus = true
|
||||
private var cursorVisible = false
|
||||
private var cursorVisible = true
|
||||
private var enableDelete = true
|
||||
private var enableFabOk = true
|
||||
|
||||
|
@ -55,70 +61,77 @@ class DialPadFragment : Fragment() {
|
|||
val view = inflater.inflate(R.layout.dialpad_fragment, container, false)
|
||||
val dialpadView = view.findViewById<View>(R.id.dialpad_view) as DialpadView
|
||||
dialpadView.findViewById<View>(R.id.dialpad_key_voicemail).isVisible = false
|
||||
digits = dialpadView.digits as? DigitsEditText
|
||||
digits?.isCursorVisible = cursorVisible
|
||||
digits?.setTextColor(ThemeUtils.getColor(requireContext(), R.attr.vctr_content_primary))
|
||||
dialpadView.findViewById<View>(R.id.zero).setOnClickListener { append('0') }
|
||||
if (enablePlus) {
|
||||
dialpadView.findViewById<View>(R.id.zero).setOnLongClickListener {
|
||||
append('+')
|
||||
true
|
||||
}
|
||||
}
|
||||
dialpadView.findViewById<View>(R.id.one).setOnClickListener { append('1') }
|
||||
dialpadView.findViewById<View>(R.id.two).setOnClickListener { append('2') }
|
||||
dialpadView.findViewById<View>(R.id.three).setOnClickListener { append('3') }
|
||||
dialpadView.findViewById<View>(R.id.four).setOnClickListener { append('4') }
|
||||
dialpadView.findViewById<View>(R.id.four).setOnClickListener { append('4') }
|
||||
dialpadView.findViewById<View>(R.id.five).setOnClickListener { append('5') }
|
||||
dialpadView.findViewById<View>(R.id.six).setOnClickListener { append('6') }
|
||||
dialpadView.findViewById<View>(R.id.seven).setOnClickListener { append('7') }
|
||||
dialpadView.findViewById<View>(R.id.eight).setOnClickListener { append('8') }
|
||||
dialpadView.findViewById<View>(R.id.nine).setOnClickListener { append('9') }
|
||||
digits = dialpadView.digits as DigitsEditText
|
||||
digits.isCursorVisible = cursorVisible
|
||||
digits.inputType = InputType.TYPE_CLASS_PHONE
|
||||
digits.keyListener = DialerKeyListener.getInstance()
|
||||
digits.setTextColor(ThemeUtils.getColor(requireContext(), R.attr.vctr_content_primary))
|
||||
digits.addTextChangedListener(PhoneNumberFormattingTextWatcher(if (formatAsYouType) regionCode else ""))
|
||||
digits.addTextChangedListener(this)
|
||||
dialpadView.findViewById<View>(R.id.zero).setOnClickListener { keyPressed(KeyEvent.KEYCODE_0, "0") }
|
||||
dialpadView.findViewById<View>(R.id.one).setOnClickListener { keyPressed(KeyEvent.KEYCODE_1,"1") }
|
||||
dialpadView.findViewById<View>(R.id.two).setOnClickListener { keyPressed(KeyEvent.KEYCODE_2,"2") }
|
||||
dialpadView.findViewById<View>(R.id.three).setOnClickListener { keyPressed(KeyEvent.KEYCODE_3,"3") }
|
||||
dialpadView.findViewById<View>(R.id.four).setOnClickListener { keyPressed(KeyEvent.KEYCODE_4,"4") }
|
||||
dialpadView.findViewById<View>(R.id.five).setOnClickListener { keyPressed(KeyEvent.KEYCODE_5,"5") }
|
||||
dialpadView.findViewById<View>(R.id.six).setOnClickListener { keyPressed(KeyEvent.KEYCODE_6,"6") }
|
||||
dialpadView.findViewById<View>(R.id.seven).setOnClickListener { keyPressed(KeyEvent.KEYCODE_7,"7") }
|
||||
dialpadView.findViewById<View>(R.id.eight).setOnClickListener { keyPressed(KeyEvent.KEYCODE_8,"8") }
|
||||
dialpadView.findViewById<View>(R.id.nine).setOnClickListener { keyPressed(KeyEvent.KEYCODE_9,"9") }
|
||||
if (enableStar) {
|
||||
dialpadView.findViewById<View>(R.id.star).setOnClickListener { append('*') }
|
||||
dialpadView.findViewById<View>(R.id.star).setOnClickListener { keyPressed(KeyEvent.KEYCODE_STAR,"*") }
|
||||
} else {
|
||||
dialpadView.findViewById<View>(R.id.star).isVisible = false
|
||||
}
|
||||
if (enablePound) {
|
||||
dialpadView.findViewById<View>(R.id.pound).setOnClickListener { append('#') }
|
||||
dialpadView.findViewById<View>(R.id.pound).setOnClickListener { keyPressed(KeyEvent.KEYCODE_POUND,"#") }
|
||||
} else {
|
||||
dialpadView.findViewById<View>(R.id.pound).isVisible = false
|
||||
}
|
||||
if (enablePlus) {
|
||||
dialpadView.findViewById<View>(R.id.zero).setOnLongClickListener {
|
||||
keyPressed(KeyEvent.KEYCODE_PLUS, "+")
|
||||
true
|
||||
}
|
||||
}
|
||||
if (enableDelete) {
|
||||
dialpadView.deleteButton.setOnClickListener { poll() }
|
||||
dialpadView.deleteButton.setOnClickListener { keyPressed(KeyEvent.KEYCODE_DEL, null) }
|
||||
dialpadView.deleteButton.setOnLongClickListener {
|
||||
clear()
|
||||
true
|
||||
}
|
||||
val tintColor = ThemeUtils.getColor(requireContext(), im.vector.app.R.attr.vctr_content_secondary)
|
||||
val tintColor = ThemeUtils.getColor(requireContext(), R.attr.vctr_content_secondary)
|
||||
ImageViewCompat.setImageTintList(dialpadView.deleteButton, ColorStateList.valueOf(tintColor))
|
||||
} else {
|
||||
dialpadView.deleteButton.isVisible = false
|
||||
}
|
||||
|
||||
// if region code is null, no formatting is performed
|
||||
formatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(if (formatAsYouType) regionCode else "")
|
||||
|
||||
val fabOk = view.findViewById<View>(R.id.fab_ok)
|
||||
if (enableFabOk) {
|
||||
fabOk.setOnClickListener {
|
||||
callback?.onOkClicked(digits?.text.toString(), input)
|
||||
}
|
||||
fabOk.setOnClickListener { onOkClicked() }
|
||||
} else {
|
||||
fabOk.isVisible = false
|
||||
}
|
||||
|
||||
digits?.setOnTextContextMenuClickListener {
|
||||
val string = digits?.text.toString()
|
||||
clear()
|
||||
for (element in string) {
|
||||
append(element)
|
||||
}
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
private fun onOkClicked() {
|
||||
val rawInput = getRawInput()
|
||||
if (rawInput.isEmpty()) {
|
||||
val clipboard = (requireContext().getSystemService(Context.CLIPBOARD_SERVICE)) as? ClipboardManager
|
||||
val textToPaste = clipboard?.primaryClip?.getItemAt(0)?.text ?: return
|
||||
val formatted = formatNumber(textToPaste.toString())
|
||||
digits.setText(formatted)
|
||||
digits.setSelection(digits.text!!.length)
|
||||
} else {
|
||||
val formatted = digits.text.toString()
|
||||
callback?.onOkClicked(formatted, rawInput)
|
||||
}
|
||||
}
|
||||
|
||||
fun getRawInput(): String {
|
||||
return PhoneNumberUtils.normalizeNumber(digits.text.toString())
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putString(EXTRA_REGION_CODE, regionCode)
|
||||
|
@ -145,40 +158,40 @@ class DialPadFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun poll() {
|
||||
if (input.isNotEmpty()) {
|
||||
input = input.substring(0, input.length - 1)
|
||||
formatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(regionCode)
|
||||
if (formatAsYouType) {
|
||||
digits?.setText("")
|
||||
for (c in input.toCharArray()) {
|
||||
digits?.setText(formatter?.inputDigit(c))
|
||||
}
|
||||
} else {
|
||||
digits?.setText(input)
|
||||
}
|
||||
private fun keyPressed(keyCode: Int, digitString: String?) {
|
||||
val event = KeyEvent(KeyEvent.ACTION_DOWN, keyCode)
|
||||
// Disable cursor and enable it again after onKeyDown otherwise DigitsEditText force replacing cursor at the end
|
||||
digits.isCursorVisible = false
|
||||
digits.onKeyDown(keyCode, event)
|
||||
digits.isCursorVisible = cursorVisible
|
||||
digitString?.also {
|
||||
callback?.onDigitAppended(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun clear() {
|
||||
formatter?.clear()
|
||||
digits?.setText("")
|
||||
input = ""
|
||||
digits.setText("")
|
||||
}
|
||||
|
||||
private fun append(c: Char) {
|
||||
callback?.onDigitAppended(c.toString())
|
||||
input += c
|
||||
if (formatAsYouType) {
|
||||
digits?.setText(formatter?.inputDigit(c))
|
||||
private fun formatNumber(dialString: String): String {
|
||||
var number = PhoneNumberUtils.extractNetworkPortion(dialString)
|
||||
// Also retrieve the post dial portion of the provided data, so that the entire dial
|
||||
// string can be reconstituted later.
|
||||
val postDial = PhoneNumberUtils.extractPostDialPortion(dialString)
|
||||
if (TextUtils.isEmpty(number)) {
|
||||
return ""
|
||||
}
|
||||
number = PhoneNumberUtils.formatNumber(number, null, regionCode) ?: number
|
||||
return if (TextUtils.isEmpty(postDial)) {
|
||||
number
|
||||
} else {
|
||||
digits?.setText(input)
|
||||
number + postDial
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onOkClicked(formatted: String?, raw: String?) = Unit
|
||||
fun onDigitAppended(digit: String) = Unit
|
||||
fun onOkClicked(formatted: String?, raw: String?) = Unit
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -193,4 +206,21 @@ class DialPadFragment : Fragment() {
|
|||
|
||||
private const val DEFAULT_REGION_CODE = "US"
|
||||
}
|
||||
|
||||
// Text watcher
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
//Noop
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
//Noop
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
if (s.isEmpty()) {
|
||||
digits.clearFocus()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -79,24 +79,20 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>(),
|
|||
waitingView = views.waitingView.waitingView
|
||||
|
||||
callTransferViewModel.observeViewEvents {
|
||||
when (it) {
|
||||
when (it) {
|
||||
is CallTransferViewEvents.Dismiss -> finish()
|
||||
CallTransferViewEvents.Loading -> showWaitingView()
|
||||
is CallTransferViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
|
||||
}
|
||||
}
|
||||
|
||||
sectionsPagerAdapter = CallTransferPagerAdapter(this).register()
|
||||
sectionsPagerAdapter = CallTransferPagerAdapter(this)
|
||||
views.callTransferViewPager.adapter = sectionsPagerAdapter
|
||||
sectionsPagerAdapter.onDialPadOkClicked = { phoneNumber ->
|
||||
val action = CallTransferAction.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber)
|
||||
callTransferViewModel.handle(action)
|
||||
}
|
||||
|
||||
TabLayoutMediator(views.callTransferTabLayout, views.callTransferViewPager) { tab, position ->
|
||||
when (position) {
|
||||
0 -> tab.text = getString(R.string.call_transfer_users_tab_title)
|
||||
1 -> tab.text = getString(R.string.call_dial_pad_title)
|
||||
CallTransferPagerAdapter.USER_LIST_INDEX -> tab.text = getString(R.string.call_transfer_users_tab_title)
|
||||
CallTransferPagerAdapter.DIAL_PAD_INDEX -> tab.text = getString(R.string.call_dial_pad_title)
|
||||
}
|
||||
}.attach()
|
||||
configureToolbar(views.callTransferToolbar)
|
||||
|
@ -106,10 +102,17 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>(),
|
|||
|
||||
private fun setupConnectAction() {
|
||||
views.callTransferConnectAction.debouncedClicks {
|
||||
val selectedUser = sectionsPagerAdapter.userListFragment?.getCurrentState()?.getSelectedMatrixId()?.firstOrNull()
|
||||
if (selectedUser != null) {
|
||||
val action = CallTransferAction.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser)
|
||||
callTransferViewModel.handle(action)
|
||||
when (views.callTransferTabLayout.selectedTabPosition) {
|
||||
CallTransferPagerAdapter.USER_LIST_INDEX -> {
|
||||
val selectedUser = sectionsPagerAdapter.userListFragment?.getCurrentState()?.getSelectedMatrixId()?.firstOrNull() ?: return@debouncedClicks
|
||||
val action = CallTransferAction.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser)
|
||||
callTransferViewModel.handle(action)
|
||||
}
|
||||
CallTransferPagerAdapter.DIAL_PAD_INDEX -> {
|
||||
val phoneNumber = sectionsPagerAdapter.dialPadFragment?.getRawInput() ?: return@debouncedClicks
|
||||
val action = CallTransferAction.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber)
|
||||
callTransferViewModel.handle(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,14 +29,17 @@ import im.vector.app.features.userdirectory.UserListFragmentArgs
|
|||
|
||||
class CallTransferPagerAdapter(
|
||||
private val fragmentActivity: FragmentActivity
|
||||
) : FragmentStateAdapter(fragmentActivity), Restorable {
|
||||
) : FragmentStateAdapter(fragmentActivity) {
|
||||
|
||||
companion object {
|
||||
const val USER_LIST_INDEX = 0
|
||||
const val DIAL_PAD_INDEX = 1
|
||||
}
|
||||
|
||||
val userListFragment: UserListFragment?
|
||||
get() = findFragmentAtPosition(0) as? UserListFragment
|
||||
get() = findFragmentAtPosition(USER_LIST_INDEX) as? UserListFragment
|
||||
val dialPadFragment: DialPadFragment?
|
||||
get() = findFragmentAtPosition(1) as? DialPadFragment
|
||||
|
||||
var onDialPadOkClicked: ((String) -> Unit)? = null
|
||||
get() = findFragmentAtPosition(DIAL_PAD_INDEX) as? DialPadFragment
|
||||
|
||||
override fun getItemCount() = 2
|
||||
|
||||
|
@ -57,10 +60,9 @@ class CallTransferPagerAdapter(
|
|||
(fragment as DialPadFragment).apply {
|
||||
arguments = Bundle().apply {
|
||||
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
|
||||
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true)
|
||||
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, false)
|
||||
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country)
|
||||
}
|
||||
applyCallback()
|
||||
}
|
||||
}
|
||||
return fragment
|
||||
|
@ -70,19 +72,5 @@ class CallTransferPagerAdapter(
|
|||
return fragmentActivity.supportFragmentManager.findFragmentByTag("f$position")
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) = Unit
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
|
||||
dialPadFragment?.applyCallback()
|
||||
}
|
||||
|
||||
private fun DialPadFragment.applyCallback(): DialPadFragment {
|
||||
callback = object : DialPadFragment.Callback {
|
||||
override fun onOkClicked(formatted: String?, raw: String?) {
|
||||
if (raw.isNullOrEmpty()) return
|
||||
onDialPadOkClicked?.invoke(raw)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue