@@ -15,14 +15,50 @@ import android.view.MotionEvent
1515import android.view.View
1616import android.view.ViewConfiguration
1717import androidx.core.content.res.ResourcesCompat
18+ import androidx.core.net.toUri
1819import androidx.core.view.isVisible
19- import org.fossify.commons.extensions.*
20- import org.fossify.commons.helpers.*
20+ import androidx.lifecycle.lifecycleScope
21+ import kotlinx.coroutines.delay
22+ import kotlinx.coroutines.launch
23+ import org.fossify.commons.extensions.applyColorFilter
24+ import org.fossify.commons.extensions.beVisibleIf
25+ import org.fossify.commons.extensions.checkAppSideloading
26+ import org.fossify.commons.extensions.getColorStateList
27+ import org.fossify.commons.extensions.getColoredDrawableWithColor
28+ import org.fossify.commons.extensions.getContrastColor
29+ import org.fossify.commons.extensions.getMyContactsCursor
30+ import org.fossify.commons.extensions.getProperBackgroundColor
31+ import org.fossify.commons.extensions.getProperPrimaryColor
32+ import org.fossify.commons.extensions.getProperTextColor
33+ import org.fossify.commons.extensions.isDefaultDialer
34+ import org.fossify.commons.extensions.launchActivityIntent
35+ import org.fossify.commons.extensions.normalizeString
36+ import org.fossify.commons.extensions.onTextChangeListener
37+ import org.fossify.commons.extensions.performHapticFeedback
38+ import org.fossify.commons.extensions.updateTextColors
39+ import org.fossify.commons.extensions.value
40+ import org.fossify.commons.extensions.viewBinding
41+ import org.fossify.commons.helpers.ContactsHelper
42+ import org.fossify.commons.helpers.KEY_PHONE
43+ import org.fossify.commons.helpers.KeypadHelper
44+ import org.fossify.commons.helpers.LOWER_ALPHA_INT
45+ import org.fossify.commons.helpers.MyContactsContentProvider
46+ import org.fossify.commons.helpers.NavigationIcon
47+ import org.fossify.commons.helpers.REQUEST_CODE_SET_DEFAULT_DIALER
48+ import org.fossify.commons.helpers.isOreoPlus
2149import org.fossify.commons.models.contacts.Contact
2250import org.fossify.phone.R
2351import org.fossify.phone.adapters.ContactsAdapter
2452import org.fossify.phone.databinding.ActivityDialpadBinding
25- import org.fossify.phone.extensions.*
53+ import org.fossify.phone.extensions.addCharacter
54+ import org.fossify.phone.extensions.areMultipleSIMsAvailable
55+ import org.fossify.phone.extensions.boundingBox
56+ import org.fossify.phone.extensions.config
57+ import org.fossify.phone.extensions.disableKeyboard
58+ import org.fossify.phone.extensions.getKeyEvent
59+ import org.fossify.phone.extensions.setupWithContacts
60+ import org.fossify.phone.extensions.startCallWithConfirmationCheck
61+ import org.fossify.phone.extensions.startContactDetailsIntent
2662import org.fossify.phone.helpers.DIALPAD_TONE_LENGTH_MS
2763import org.fossify.phone.helpers.RecentsHelper
2864import org.fossify.phone.helpers.ToneGeneratorHelper
@@ -35,21 +71,39 @@ class DialpadActivity : SimpleActivity() {
3571
3672 private var allContacts = ArrayList <Contact >()
3773 private var speedDialValues = ArrayList <SpeedDial >()
38- private val russianCharsMap = HashMap <Char , Int >()
39- private var hasRussianLocale = false
4074 private var privateCursor: Cursor ? = null
4175 private var toneGeneratorHelper: ToneGeneratorHelper ? = null
4276 private val longPressTimeout = ViewConfiguration .getLongPressTimeout().toLong()
4377 private val longPressHandler = Handler (Looper .getMainLooper())
4478 private val pressedKeys = mutableSetOf<Char >()
4579
80+ private var hasRussianLocale = false
81+ private val russianCharsMap by lazy {
82+ hashMapOf(
83+ ' а' to 2 , ' б' to 2 , ' в' to 2 , ' г' to 2 ,
84+ ' д' to 3 , ' е' to 3 , ' ё' to 3 , ' ж' to 3 , ' з' to 3 ,
85+ ' и' to 4 , ' й' to 4 , ' к' to 4 , ' л' to 4 ,
86+ ' м' to 5 , ' н' to 5 , ' о' to 5 , ' п' to 5 ,
87+ ' р' to 6 , ' с' to 6 , ' т' to 6 , ' у' to 6 ,
88+ ' ф' to 7 , ' х' to 7 , ' ц' to 7 , ' ч' to 7 ,
89+ ' ш' to 8 , ' щ' to 8 , ' ъ' to 8 , ' ы' to 8 ,
90+ ' ь' to 9 , ' э' to 9 , ' ю' to 9 , ' я' to 9
91+ )
92+ }
93+
94+ @Suppress(" LongMethod" )
4695 override fun onCreate (savedInstanceState : Bundle ? ) {
4796 super .onCreate(savedInstanceState)
4897 setContentView(binding.root)
4998 hasRussianLocale = Locale .getDefault().language == " ru"
5099
51100 binding.apply {
52- updateMaterialActivityViews(dialpadCoordinator, dialpadHolder, useTransparentNavigation = true , useTopSearchMenu = false )
101+ updateMaterialActivityViews(
102+ mainCoordinatorLayout = dialpadCoordinator,
103+ nestedView = dialpadHolder,
104+ useTransparentNavigation = true ,
105+ useTopSearchMenu = false
106+ )
53107 setupMaterialScrollListener(dialpadList, dialpadToolbar)
54108 }
55109
@@ -89,7 +143,8 @@ class DialpadActivity : SimpleActivity() {
89143 dialpadAsteriskHolder,
90144 dialpadHashtagHolder
91145 ).forEach {
92- it.background = ResourcesCompat .getDrawable(resources, R .drawable.pill_background, theme)
146+ it.background =
147+ ResourcesCompat .getDrawable(resources, R .drawable.pill_background, theme)
93148 it.background?.alpha = LOWER_ALPHA_INT
94149 }
95150 }
@@ -102,7 +157,6 @@ class DialpadActivity : SimpleActivity() {
102157
103158 binding.dialpadWrapper.apply {
104159 if (hasRussianLocale) {
105- initRussianChars()
106160 dialpad2Letters.append(" \n АБВГ" )
107161 dialpad3Letters.append(" \n ДЕЁЖЗ" )
108162 dialpad4Letters.append(" \n ИЙКЛ" )
@@ -114,7 +168,13 @@ class DialpadActivity : SimpleActivity() {
114168
115169 val fontSize = resources.getDimension(R .dimen.small_text_size)
116170 arrayOf(
117- dialpad2Letters, dialpad3Letters, dialpad4Letters, dialpad5Letters, dialpad6Letters, dialpad7Letters, dialpad8Letters,
171+ dialpad2Letters,
172+ dialpad3Letters,
173+ dialpad4Letters,
174+ dialpad5Letters,
175+ dialpad6Letters,
176+ dialpad7Letters,
177+ dialpad8Letters,
118178 dialpad9Letters
119179 ).forEach {
120180 it.setTextSize(TypedValue .COMPLEX_UNIT_PX , fontSize)
@@ -139,7 +199,8 @@ class DialpadActivity : SimpleActivity() {
139199 binding.apply {
140200 dialpadClearChar.setOnClickListener { clearChar(it) }
141201 dialpadClearChar.setOnLongClickListener { clearInput(); true }
142- dialpadCallButton.setOnClickListener { initCall(dialpadInput.value, 0 ) }
202+ dialpadCallButton.setOnClickListener { initCall(dialpadInput.value) }
203+ dialpadCallButton.setOnLongClickListener { initCallWithSimSelector() }
143204 dialpadInput.onTextChangeListener { dialpadValueChanged(it) }
144205 dialpadInput.requestFocus()
145206 dialpadInput.disableKeyboard()
@@ -150,24 +211,11 @@ class DialpadActivity : SimpleActivity() {
150211 }
151212
152213 val properPrimaryColor = getProperPrimaryColor()
153- val callIconId = if (areMultipleSIMsAvailable()) {
154- val callIcon = resources.getColoredDrawableWithColor(R .drawable.ic_phone_two_vector, properPrimaryColor.getContrastColor())
155- binding.apply {
156- dialpadCallTwoButton.setImageDrawable(callIcon)
157- dialpadCallTwoButton.background.applyColorFilter(properPrimaryColor)
158- dialpadCallTwoButton.beVisible()
159- dialpadCallTwoButton.setOnClickListener {
160- initCall(dialpadInput.value, 1 )
161- }
162- }
163-
164- R .drawable.ic_phone_one_vector
165- } else {
166- R .drawable.ic_phone_vector
167- }
168-
169214 binding.apply {
170- val callIcon = resources.getColoredDrawableWithColor(callIconId, properPrimaryColor.getContrastColor())
215+ val callIcon = resources.getColoredDrawableWithColor(
216+ drawableId = R .drawable.ic_phone_vector,
217+ color = properPrimaryColor.getContrastColor()
218+ )
171219 dialpadCallButton.setImageDrawable(callIcon)
172220 dialpadCallButton.background.applyColorFilter(properPrimaryColor)
173221
@@ -198,7 +246,10 @@ class DialpadActivity : SimpleActivity() {
198246 }
199247
200248 private fun checkDialIntent (): Boolean {
201- return if ((intent.action == Intent .ACTION_DIAL || intent.action == Intent .ACTION_VIEW ) && intent.data != null && intent.dataString?.contains(" tel:" ) == true ) {
249+ return if (
250+ (intent.action == Intent .ACTION_DIAL || intent.action == Intent .ACTION_VIEW )
251+ && intent.data != null && intent.dataString?.contains(" tel:" ) == true
252+ ) {
202253 val number = Uri .decode(intent.dataString).substringAfter(" tel:" )
203254 binding.dialpadInput.setText(number)
204255 binding.dialpadInput.setSelection(number.length)
@@ -231,6 +282,13 @@ class DialpadActivity : SimpleActivity() {
231282 binding.dialpadInput.setText(" " )
232283 }
233284
285+ private fun clearInputWithDelay () {
286+ lifecycleScope.launch {
287+ delay(1000 )
288+ clearInput()
289+ }
290+ }
291+
234292 private fun gotContacts (newContacts : ArrayList <Contact >) {
235293 allContacts = newContacts
236294
@@ -258,7 +316,8 @@ class DialpadActivity : SimpleActivity() {
258316 launchSetDefaultDialerIntent()
259317 }
260318 } else {
261- val intent = Intent (SECRET_CODE_ACTION , Uri .parse(" android_secret_code://$secretCode " ))
319+ val intent =
320+ Intent (SECRET_CODE_ACTION , " android_secret_code://$secretCode " .toUri())
262321 sendBroadcast(intent)
263322 }
264323 return
@@ -294,10 +353,11 @@ class DialpadActivity : SimpleActivity() {
294353 highlightText = text,
295354 itemClick = {
296355 val contact = it as Contact
297- startCallWithConfirmationCheck(contact.getPrimaryNumber() ? : return @ContactsAdapter, contact.getNameToDisplay())
298- Handler ().postDelayed({
299- binding.dialpadInput.setText(" " )
300- }, 1000 )
356+ startCallWithConfirmationCheck(
357+ recipient = contact.getPrimaryNumber() ? : return @ContactsAdapter,
358+ name = contact.getNameToDisplay()
359+ )
360+ clearInputWithDelay()
301361 },
302362 profileIconClick = {
303363 startContactDetailsIntent(it as Contact )
@@ -316,17 +376,10 @@ class DialpadActivity : SimpleActivity() {
316376 }
317377 }
318378
319- private fun initCall (number : String = binding.dialpadInput.value, handleIndex : Int ) {
379+ private fun initCall (number : String = binding.dialpadInput.value) {
320380 if (number.isNotEmpty()) {
321- if (handleIndex != - 1 && areMultipleSIMsAvailable()) {
322- callContactWithSimWithConfirmationCheck(number, number, handleIndex == 0 )
323- } else {
324- startCallWithConfirmationCheck(number, number)
325- }
326-
327- Handler ().postDelayed({
328- binding.dialpadInput.setText(" " )
329- }, 1000 )
381+ startCallWithConfirmationCheck(number, number)
382+ clearInputWithDelay()
330383 } else {
331384 RecentsHelper (this ).getRecentCalls(queryLimit = 1 ) {
332385 val mostRecentNumber = it.firstOrNull()?.phoneNumber
@@ -339,28 +392,31 @@ class DialpadActivity : SimpleActivity() {
339392 }
340393 }
341394
395+ private fun initCallWithSimSelector (): Boolean {
396+ val number = binding.dialpadInput.value
397+ return if (areMultipleSIMsAvailable() && number.isNotEmpty()) {
398+ startCallWithConfirmationCheck(
399+ recipient = number,
400+ name = number,
401+ forceSimSelector = true
402+ )
403+ true
404+ } else {
405+ false
406+ }
407+ }
408+
342409 private fun speedDial (id : Int ): Boolean {
343410 if (binding.dialpadInput.value.length == 1 ) {
344411 val speedDial = speedDialValues.firstOrNull { it.id == id }
345412 if (speedDial?.isValid() == true ) {
346- initCall(speedDial.number, - 1 )
413+ initCall(speedDial.number)
347414 return true
348415 }
349416 }
350417 return false
351418 }
352419
353- private fun initRussianChars () {
354- russianCharsMap[' а' ] = 2 ; russianCharsMap[' б' ] = 2 ; russianCharsMap[' в' ] = 2 ; russianCharsMap[' г' ] = 2
355- russianCharsMap[' д' ] = 3 ; russianCharsMap[' е' ] = 3 ; russianCharsMap[' ё' ] = 3 ; russianCharsMap[' ж' ] = 3 ; russianCharsMap[' з' ] = 3
356- russianCharsMap[' и' ] = 4 ; russianCharsMap[' й' ] = 4 ; russianCharsMap[' к' ] = 4 ; russianCharsMap[' л' ] = 4
357- russianCharsMap[' м' ] = 5 ; russianCharsMap[' н' ] = 5 ; russianCharsMap[' о' ] = 5 ; russianCharsMap[' п' ] = 5
358- russianCharsMap[' р' ] = 6 ; russianCharsMap[' с' ] = 6 ; russianCharsMap[' т' ] = 6 ; russianCharsMap[' у' ] = 6
359- russianCharsMap[' ф' ] = 7 ; russianCharsMap[' х' ] = 7 ; russianCharsMap[' ц' ] = 7 ; russianCharsMap[' ч' ] = 7
360- russianCharsMap[' ш' ] = 8 ; russianCharsMap[' щ' ] = 8 ; russianCharsMap[' ъ' ] = 8 ; russianCharsMap[' ы' ] = 8
361- russianCharsMap[' ь' ] = 9 ; russianCharsMap[' э' ] = 9 ; russianCharsMap[' ю' ] = 9 ; russianCharsMap[' я' ] = 9
362- }
363-
364420 private fun startDialpadTone (char : Char ) {
365421 if (config.dialpadBeeps) {
366422 pressedKeys.add(char)
0 commit comments