Merge pull request #639 from Merkost/grid_view_favorites

Grid view favorites
This commit is contained in:
Tibor Kaputa 2023-07-20 09:42:29 +02:00 committed by GitHub
commit 44a81dc7cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 236 additions and 92 deletions

View File

@ -12,7 +12,7 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
compileSdkVersion 33 compileSdk 33
defaultConfig { defaultConfig {
applicationId "com.simplemobiletools.dialer" applicationId "com.simplemobiletools.dialer"
@ -47,7 +47,7 @@ android {
} }
} }
flavorDimensions "variants" flavorDimensions = ["variants"]
productFlavors { productFlavors {
core {} core {}
fdroid {} fdroid {}

View File

@ -263,7 +263,7 @@ class DialpadActivity : SimpleActivity() {
if (hasRussianLocale) { if (hasRussianLocale) {
var currConvertedName = "" var currConvertedName = ""
convertedName.toLowerCase().forEach { char -> convertedName.lowercase(Locale.getDefault()).forEach { char ->
val convertedChar = russianCharsMap.getOrElse(char) { char } val convertedChar = russianCharsMap.getOrElse(char) { char }
currConvertedName += convertedChar currConvertedName += convertedChar
} }
@ -279,13 +279,18 @@ class DialpadActivity : SimpleActivity() {
try { try {
val name = filtered[position].getNameToDisplay() val name = filtered[position].getNameToDisplay()
val character = if (name.isNotEmpty()) name.substring(0, 1) else "" val character = if (name.isNotEmpty()) name.substring(0, 1) else ""
FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault())) FastScrollItemIndicator.Text(character.uppercase(Locale.getDefault()))
} catch (e: Exception) { } catch (e: Exception) {
FastScrollItemIndicator.Text("") FastScrollItemIndicator.Text("")
} }
}) })
ContactsAdapter(this, filtered, dialpad_list, null, text) { ContactsAdapter(
activity = this,
contacts = filtered,
recyclerView = dialpad_list,
highlightText = text
) {
val contact = it as Contact val contact = it as Contact
if (config.showCallConfirmation) { if (config.showCallConfirmation) {
CallConfirmationDialog(this@DialpadActivity, contact.getNameToDisplay()) { CallConfirmationDialog(this@DialpadActivity, contact.getNameToDisplay()) {
@ -316,7 +321,7 @@ class DialpadActivity : SimpleActivity() {
CallConfirmationDialog(this, number) { CallConfirmationDialog(this, number) {
callContactWithSim(number, handleIndex == 0) callContactWithSim(number, handleIndex == 0)
} }
}else{ } else {
callContactWithSim(number, handleIndex == 0) callContactWithSim(number, handleIndex == 0)
} }
} else { } else {
@ -324,7 +329,7 @@ class DialpadActivity : SimpleActivity() {
CallConfirmationDialog(this, number) { CallConfirmationDialog(this, number) {
startCallIntent(number) startCallIntent(number)
} }
}else{ } else {
startCallIntent(number) startCallIntent(number)
} }
} }
@ -406,12 +411,14 @@ class DialpadActivity : SimpleActivity() {
}, longPressTimeout) }, longPressTimeout)
} }
} }
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
stopDialpadTone(char) stopDialpadTone(char)
if (longClickable) { if (longClickable) {
longPressHandler.removeCallbacksAndMessages(null) longPressHandler.removeCallbacksAndMessages(null)
} }
} }
MotionEvent.ACTION_MOVE -> { MotionEvent.ACTION_MOVE -> {
val viewContainsTouchEvent = if (event.rawX.isNaN() || event.rawY.isNaN()) { val viewContainsTouchEvent = if (event.rawX.isNaN() || event.rawY.isNaN()) {
false false

View File

@ -16,11 +16,14 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.simplemobiletools.commons.dialogs.ChangeViewTypeDialog
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.commons.models.contacts.Contact
import com.simplemobiletools.dialer.BuildConfig import com.simplemobiletools.dialer.BuildConfig
import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.R
@ -31,9 +34,7 @@ import com.simplemobiletools.dialer.extensions.config
import com.simplemobiletools.dialer.extensions.launchCreateNewContactIntent import com.simplemobiletools.dialer.extensions.launchCreateNewContactIntent
import com.simplemobiletools.dialer.fragments.FavoritesFragment import com.simplemobiletools.dialer.fragments.FavoritesFragment
import com.simplemobiletools.dialer.fragments.MyViewPagerFragment import com.simplemobiletools.dialer.fragments.MyViewPagerFragment
import com.simplemobiletools.dialer.helpers.OPEN_DIAL_PAD_AT_LAUNCH import com.simplemobiletools.dialer.helpers.*
import com.simplemobiletools.dialer.helpers.RecentsHelper
import com.simplemobiletools.dialer.helpers.tabsList
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_contacts.* import kotlinx.android.synthetic.main.fragment_contacts.*
import kotlinx.android.synthetic.main.fragment_favorites.* import kotlinx.android.synthetic.main.fragment_favorites.*
@ -43,6 +44,7 @@ import me.grantland.widget.AutofitHelper
class MainActivity : SimpleActivity() { class MainActivity : SimpleActivity() {
private var launchedDialer = false private var launchedDialer = false
private var storedShowTabs = 0 private var storedShowTabs = 0
private var storedFontSize = 0
private var storedStartNameWithSurname = false private var storedStartNameWithSurname = false
var cachedContacts = ArrayList<Contact>() var cachedContacts = ArrayList<Contact>()
@ -120,6 +122,13 @@ class MainActivity : SimpleActivity() {
refreshItems(true) refreshItems(true)
} }
val configFontSize = config.fontSize
if (storedFontSize != configFontSize) {
getAllFragments().forEach {
it?.fontSizeChanged()
}
}
checkShortcuts() checkShortcuts()
Handler().postDelayed({ Handler().postDelayed({
recents_fragment?.refreshItems() recents_fragment?.refreshItems()
@ -169,6 +178,8 @@ class MainActivity : SimpleActivity() {
findItem(R.id.clear_call_history).isVisible = currentFragment == recents_fragment findItem(R.id.clear_call_history).isVisible = currentFragment == recents_fragment
findItem(R.id.sort).isVisible = currentFragment != recents_fragment findItem(R.id.sort).isVisible = currentFragment != recents_fragment
findItem(R.id.create_new_contact).isVisible = currentFragment == contacts_fragment findItem(R.id.create_new_contact).isVisible = currentFragment == contacts_fragment
findItem(R.id.change_view_type).isVisible = currentFragment == favorites_fragment
findItem(R.id.column_count).isVisible = currentFragment == favorites_fragment && config.viewType == VIEW_TYPE_GRID
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations)
} }
} }
@ -196,6 +207,8 @@ class MainActivity : SimpleActivity() {
R.id.filter -> showFilterDialog() R.id.filter -> showFilterDialog()
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
R.id.settings -> launchSettings() R.id.settings -> launchSettings()
R.id.change_view_type -> changeViewType()
R.id.column_count -> changeColumnCount()
R.id.about -> launchAbout() R.id.about -> launchAbout()
else -> return@setOnMenuItemClickListener false else -> return@setOnMenuItemClickListener false
} }
@ -203,6 +216,28 @@ class MainActivity : SimpleActivity() {
} }
} }
private fun changeColumnCount() {
val items = (CONTACTS_GRID_MIN_COLUMNS_COUNT..CONTACTS_GRID_MAX_COLUMNS_COUNT).map {
RadioItem(it, resources.getQuantityString(R.plurals.column_counts, it, it))
}
val currentColumnCount = config.contactsGridColumnCount
RadioGroupDialog(this, ArrayList(items), currentColumnCount) {
val newColumnCount = it as Int
if (currentColumnCount != newColumnCount) {
config.contactsGridColumnCount = newColumnCount
favorites_fragment?.columnCountChanged()
}
}
}
private fun changeViewType() {
ChangeViewTypeDialog(this) {
refreshMenuItems()
favorites_fragment?.refreshItems()
}
}
private fun updateMenuColors() { private fun updateMenuColors() {
updateStatusbarColor(getProperBackgroundColor()) updateStatusbarColor(getProperBackgroundColor())
main_menu.updateColors() main_menu.updateColors()

View File

@ -7,13 +7,11 @@ import android.graphics.drawable.Icon
import android.net.Uri import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
import android.util.TypedValue import android.util.TypedValue
import android.view.Menu import android.view.*
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -21,10 +19,7 @@ import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FeatureLockedDialog import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.isOreoPlus
import com.simplemobiletools.commons.interfaces.ItemMoveCallback import com.simplemobiletools.commons.interfaces.ItemMoveCallback
import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract
import com.simplemobiletools.commons.interfaces.StartReorderDragListener import com.simplemobiletools.commons.interfaces.StartReorderDragListener
@ -43,25 +38,33 @@ class ContactsAdapter(
activity: SimpleActivity, activity: SimpleActivity,
var contacts: MutableList<Contact>, var contacts: MutableList<Contact>,
recyclerView: MyRecyclerView, recyclerView: MyRecyclerView,
val refreshItemsListener: RefreshItemsListener? = null,
highlightText: String = "", highlightText: String = "",
val showDeleteButton: Boolean = true, private val refreshItemsListener: RefreshItemsListener? = null,
var viewType: Int = VIEW_TYPE_LIST,
private val showDeleteButton: Boolean = true,
private val enableDrag: Boolean = false, private val enableDrag: Boolean = false,
private val allowLongClick: Boolean = true, private val allowLongClick: Boolean = true,
itemClick: (Any) -> Unit itemClick: (Any) -> Unit
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract { ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick),
ItemTouchHelperContract, MyRecyclerView.MyZoomListener {
private var textToHighlight = highlightText private var textToHighlight = highlightText
private var fontSize = activity.getTextSize() var fontSize: Float = activity.getTextSize()
private var touchHelper: ItemTouchHelper? = null private var touchHelper: ItemTouchHelper? = null
private var startReorderDragListener: StartReorderDragListener? = null private var startReorderDragListener: StartReorderDragListener? = null
var onDragEndListener: (() -> Unit)? = null var onDragEndListener: (() -> Unit)? = null
var onSpanCountListener: (Int) -> Unit = {}
init { init {
setupDragListener(true) setupDragListener(true)
if (recyclerView.layoutManager is GridLayoutManager) {
setupZoomListener(this)
}
if (enableDrag) { if (enableDrag) {
touchHelper = ItemTouchHelper(ItemMoveCallback(this)) touchHelper = ItemTouchHelper(ItemMoveCallback(this, viewType == VIEW_TYPE_GRID))
touchHelper!!.attachToRecyclerView(recyclerView) touchHelper!!.attachToRecyclerView(recyclerView)
startReorderDragListener = object : StartReorderDragListener { startReorderDragListener = object : StartReorderDragListener {
@ -124,7 +127,17 @@ class ContactsAdapter(
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_contact_without_number, parent) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layout = when (viewType) {
VIEW_TYPE_GRID -> R.layout.item_contact_without_number_grid
else -> R.layout.item_contact_without_number
}
return createViewHolder(layout, parent)
}
override fun getItemViewType(position: Int): Int {
return viewType
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val contact = contacts[position] val contact = contacts[position]
@ -333,4 +346,27 @@ class ContactsAdapter(
override fun onRowClear(myViewHolder: ViewHolder?) { override fun onRowClear(myViewHolder: ViewHolder?) {
onDragEndListener?.invoke() onDragEndListener?.invoke()
} }
override fun zoomIn() {
val layoutManager = recyclerView.layoutManager
if (layoutManager is GridLayoutManager) {
val currentSpanCount = layoutManager.spanCount
val newSpanCount = (currentSpanCount - 1).coerceIn(CONTACTS_GRID_MIN_COLUMNS_COUNT, CONTACTS_GRID_MAX_COLUMNS_COUNT)
layoutManager.spanCount = newSpanCount
recyclerView.requestLayout()
onSpanCountListener(newSpanCount)
}
}
override fun zoomOut() {
val layoutManager = recyclerView.layoutManager
if (layoutManager is GridLayoutManager) {
val currentSpanCount = layoutManager.spanCount
val newSpanCount = (currentSpanCount + 1).coerceIn(CONTACTS_GRID_MIN_COLUMNS_COUNT, CONTACTS_GRID_MAX_COLUMNS_COUNT)
layoutManager.spanCount = newSpanCount
recyclerView.requestLayout()
onSpanCountListener(newSpanCount)
}
}
} }

View File

@ -38,7 +38,7 @@ class RecentCallsAdapter(
private lateinit var outgoingCallIcon: Drawable private lateinit var outgoingCallIcon: Drawable
private lateinit var incomingCallIcon: Drawable private lateinit var incomingCallIcon: Drawable
private lateinit var incomingMissedCallIcon: Drawable private lateinit var incomingMissedCallIcon: Drawable
private var fontSize = activity.getTextSize() var fontSize: Float = activity.getTextSize()
private val areMultipleSIMsAvailable = activity.areMultipleSIMsAvailable() private val areMultipleSIMsAvailable = activity.areMultipleSIMsAvailable()
private val redColor = resources.getColor(R.color.md_red_700) private val redColor = resources.getColor(R.color.md_red_700)
private var textToHighlight = "" private var textToHighlight = ""
@ -279,6 +279,7 @@ class RecentCallsAdapter(
private fun setupView(view: View, call: RecentCall) { private fun setupView(view: View, call: RecentCall) {
view.apply { view.apply {
val currentFontSize = fontSize
item_recents_holder.isSelected = selectedKeys.contains(call.id) item_recents_holder.isSelected = selectedKeys.contains(call.id)
val name = findContactByCall(call)?.getNameToDisplay() ?: call.name val name = findContactByCall(call)?.getNameToDisplay() ?: call.name
var nameToShow = SpannableString(name) var nameToShow = SpannableString(name)
@ -302,20 +303,20 @@ class RecentCallsAdapter(
item_recents_name.apply { item_recents_name.apply {
text = nameToShow text = nameToShow
setTextColor(textColor) setTextColor(textColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize)
} }
item_recents_date_time.apply { item_recents_date_time.apply {
text = call.startTS.formatDateOrTime(context, refreshItemsListener != null, false) text = call.startTS.formatDateOrTime(context, refreshItemsListener != null, false)
setTextColor(if (call.type == Calls.MISSED_TYPE) redColor else textColor) setTextColor(if (call.type == Calls.MISSED_TYPE) redColor else textColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize * 0.8f)
} }
item_recents_duration.apply { item_recents_duration.apply {
text = call.duration.getFormattedDuration() text = call.duration.getFormattedDuration()
setTextColor(textColor) setTextColor(textColor)
beVisibleIf(call.type != Calls.MISSED_TYPE && call.type != Calls.REJECTED_TYPE && call.duration > 0) beVisibleIf(call.type != Calls.MISSED_TYPE && call.type != Calls.REJECTED_TYPE && call.duration > 0)
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize * 0.8f) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize * 0.8f)
if (!showOverflowMenu) { if (!showOverflowMenu) {
item_recents_duration.setPadding(0, 0, durationPadding, 0) item_recents_duration.setPadding(0, 0, durationPadding, 0)
} }

View File

@ -15,7 +15,7 @@ import com.simplemobiletools.dialer.extensions.launchCreateNewContactIntent
import com.simplemobiletools.dialer.extensions.startContactDetailsIntent import com.simplemobiletools.dialer.extensions.startContactDetailsIntent
import com.simplemobiletools.dialer.interfaces.RefreshItemsListener import com.simplemobiletools.dialer.interfaces.RefreshItemsListener
import kotlinx.android.synthetic.main.fragment_letters_layout.view.* import kotlinx.android.synthetic.main.fragment_letters_layout.view.*
import java.util.* import java.util.Locale
class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener { class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener {
private var allContacts = ArrayList<Contact>() private var allContacts = ArrayList<Contact>()
@ -82,7 +82,7 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
} }
private fun gotContacts(contacts: ArrayList<Contact>) { private fun gotContacts(contacts: ArrayList<Contact>) {
setupLetterFastscroller(contacts) setupLetterFastScroller(contacts)
if (contacts.isEmpty()) { if (contacts.isEmpty()) {
fragment_placeholder.beVisible() fragment_placeholder.beVisible()
fragment_placeholder_2.beVisible() fragment_placeholder_2.beVisible()
@ -94,7 +94,12 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
val currAdapter = fragment_list.adapter val currAdapter = fragment_list.adapter
if (currAdapter == null) { if (currAdapter == null) {
ContactsAdapter(activity as SimpleActivity, contacts, fragment_list, this) { ContactsAdapter(
activity = activity as SimpleActivity,
contacts = contacts,
recyclerView = fragment_list,
refreshItemsListener = this
) {
val contact = it as Contact val contact = it as Contact
activity?.startContactDetailsIntent(contact) activity?.startContactDetailsIntent(contact)
}.apply { }.apply {
@ -110,12 +115,12 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
} }
} }
private fun setupLetterFastscroller(contacts: ArrayList<Contact>) { private fun setupLetterFastScroller(contacts: ArrayList<Contact>) {
letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> letter_fastscroller.setupWithRecyclerView(fragment_list, { position ->
try { try {
val name = contacts[position].getNameToDisplay() val name = contacts[position].getNameToDisplay()
val character = if (name.isNotEmpty()) name.substring(0, 1) else "" val character = if (name.isNotEmpty()) name.substring(0, 1) else ""
FastScrollItemIndicator.Text(character.toUpperCase(Locale.getDefault()).normalizeString()) FastScrollItemIndicator.Text(character.uppercase(Locale.getDefault()).normalizeString())
} catch (e: Exception) { } catch (e: Exception) {
FastScrollItemIndicator.Text("") FastScrollItemIndicator.Text("")
} }
@ -125,35 +130,36 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
override fun onSearchClosed() { override fun onSearchClosed() {
fragment_placeholder.beVisibleIf(allContacts.isEmpty()) fragment_placeholder.beVisibleIf(allContacts.isEmpty())
(fragment_list.adapter as? ContactsAdapter)?.updateItems(allContacts) (fragment_list.adapter as? ContactsAdapter)?.updateItems(allContacts)
setupLetterFastscroller(allContacts) setupLetterFastScroller(allContacts)
} }
override fun onSearchQueryChanged(text: String) { override fun onSearchQueryChanged(text: String) {
val shouldNormalize = text.normalizeString() == text val shouldNormalize = text.normalizeString() == text
val filtered = allContacts.filter { val filtered = allContacts.filter {
getProperText(it.getNameToDisplay(), shouldNormalize).contains(text, true) || getProperText(it.getNameToDisplay(), shouldNormalize).contains(text, true) ||
getProperText(it.nickname, shouldNormalize).contains(text, true) || getProperText(it.nickname, shouldNormalize).contains(text, true) ||
it.phoneNumbers.any { it.phoneNumbers.any {
text.normalizePhoneNumber().isNotEmpty() && it.normalizedNumber.contains(text.normalizePhoneNumber(), true) text.normalizePhoneNumber().isNotEmpty() && it.normalizedNumber.contains(text.normalizePhoneNumber(), true)
} || } ||
it.emails.any { it.value.contains(text, true) } || it.emails.any { it.value.contains(text, true) } ||
it.addresses.any { getProperText(it.value, shouldNormalize).contains(text, true) } || it.addresses.any { getProperText(it.value, shouldNormalize).contains(text, true) } ||
it.IMs.any { it.value.contains(text, true) } || it.IMs.any { it.value.contains(text, true) } ||
getProperText(it.notes, shouldNormalize).contains(text, true) || getProperText(it.notes, shouldNormalize).contains(text, true) ||
getProperText(it.organization.company, shouldNormalize).contains(text, true) || getProperText(it.organization.company, shouldNormalize).contains(text, true) ||
getProperText(it.organization.jobPosition, shouldNormalize).contains(text, true) || getProperText(it.organization.jobPosition, shouldNormalize).contains(text, true) ||
it.websites.any { it.contains(text, true) } it.websites.any { it.contains(text, true) }
} as ArrayList } as ArrayList
filtered.sortBy { filtered.sortBy {
val nameToDisplay = it.getNameToDisplay() val nameToDisplay = it.getNameToDisplay()
!getProperText(nameToDisplay, shouldNormalize).startsWith(text, true) && !nameToDisplay.contains(text, true) !getProperText(nameToDisplay, shouldNormalize).startsWith(text, true) && !nameToDisplay.contains(text, true)
} }
fragment_placeholder.beVisibleIf(filtered.isEmpty()) fragment_placeholder.beVisibleIf(filtered.isEmpty())
(fragment_list.adapter as? ContactsAdapter)?.updateItems(filtered, text) (fragment_list.adapter as? ContactsAdapter)?.updateItems(filtered, text)
setupLetterFastscroller(filtered) setupLetterFastScroller(filtered)
} }
private fun requestReadContactsPermission() { private fun requestReadContactsPermission() {
activity?.handlePermission(PERMISSION_READ_CONTACTS) { activity?.handlePermission(PERMISSION_READ_CONTACTS) {
if (it) { if (it) {

View File

@ -7,11 +7,10 @@ import com.reddit.indicatorfastscroll.FastScrollItemIndicator
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.CallConfirmationDialog import com.simplemobiletools.commons.dialogs.CallConfirmationDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.helpers.MyContactsContentProvider
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.commons.models.contacts.Contact
import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.commons.views.MyLinearLayoutManager
import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.R
import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.activities.SimpleActivity
import com.simplemobiletools.dialer.adapters.ContactsAdapter import com.simplemobiletools.dialer.adapters.ContactsAdapter
@ -84,46 +83,66 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa
fragment_placeholder.beGone() fragment_placeholder.beGone()
fragment_list.beVisible() fragment_list.beVisible()
val currAdapter = fragment_list.adapter updateListAdapter()
if (currAdapter == null) { }
ContactsAdapter( }
activity = activity as SimpleActivity,
contacts = contacts, private fun updateListAdapter() {
recyclerView = fragment_list, val viewType = context.config.viewType
refreshItemsListener = this, setViewType(viewType)
showDeleteButton = false,
enableDrag = true, val currAdapter = fragment_list.adapter as ContactsAdapter?
) { if (currAdapter == null) {
if (context.config.showCallConfirmation) { ContactsAdapter(
CallConfirmationDialog(activity as SimpleActivity, (it as Contact).getNameToDisplay()) { activity = activity as SimpleActivity,
activity?.apply { contacts = allContacts,
initiateCall(it) { launchCallIntent(it) } recyclerView = fragment_list,
} refreshItemsListener = this,
} viewType = viewType,
} else { showDeleteButton = false,
enableDrag = true,
) {
if (context.config.showCallConfirmation) {
CallConfirmationDialog(activity as SimpleActivity, (it as Contact).getNameToDisplay()) {
activity?.apply { activity?.apply {
initiateCall(it as Contact) { launchCallIntent(it) } initiateCall(it) { launchCallIntent(it) }
} }
} }
}.apply { } else {
fragment_list.adapter = this activity?.apply {
initiateCall(it as Contact) { launchCallIntent(it) }
}
}
}.apply {
fragment_list.adapter = this
onDragEndListener = { onDragEndListener = {
val adapter = fragment_list?.adapter val adapter = fragment_list?.adapter
if (adapter is ContactsAdapter) { if (adapter is ContactsAdapter) {
val items = adapter.contacts val items = adapter.contacts
saveCustomOrderToPrefs(items) saveCustomOrderToPrefs(items)
setupLetterFastScroller(items) setupLetterFastScroller(items)
}
} }
} }
if (context.areSystemAnimationsEnabled) { onSpanCountListener = { newSpanCount ->
fragment_list.scheduleLayoutAnimation() context.config.contactsGridColumnCount = newSpanCount
} }
} else {
(currAdapter as ContactsAdapter).updateItems(contacts)
} }
if (context.areSystemAnimationsEnabled) {
fragment_list.scheduleLayoutAnimation()
}
} else {
currAdapter.viewType = viewType
currAdapter.updateItems(allContacts)
}
}
fun columnCountChanged() {
(fragment_list.layoutManager as MyGridLayoutManager).spanCount = context!!.config.contactsGridColumnCount
fragment_list?.adapter?.apply {
notifyItemRangeChanged(0, allContacts.size)
} }
} }
@ -178,4 +197,17 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa
(fragment_list.adapter as? ContactsAdapter)?.updateItems(contacts, text) (fragment_list.adapter as? ContactsAdapter)?.updateItems(contacts, text)
setupLetterFastScroller(contacts) setupLetterFastScroller(contacts)
} }
private fun setViewType(viewType: Int) {
val spanCount = context.config.contactsGridColumnCount
val layoutManager = if (viewType == VIEW_TYPE_GRID) {
letter_fastscroller.beGone()
MyGridLayoutManager(context, spanCount)
} else {
letter_fastscroller.beVisible()
MyLinearLayoutManager(context)
}
fragment_list.layoutManager = layoutManager
}
} }

View File

@ -6,15 +6,17 @@ import android.widget.RelativeLayout
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.getProperPrimaryColor import com.simplemobiletools.commons.extensions.getProperPrimaryColor
import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.extensions.getProperTextColor
import com.simplemobiletools.commons.extensions.getTextSize
import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME
import com.simplemobiletools.commons.helpers.SORT_BY_SURNAME import com.simplemobiletools.commons.helpers.SORT_BY_SURNAME
import com.simplemobiletools.dialer.activities.MainActivity import com.simplemobiletools.dialer.activities.MainActivity
import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.activities.SimpleActivity
import com.simplemobiletools.dialer.adapters.ContactsAdapter import com.simplemobiletools.dialer.adapters.ContactsAdapter
import com.simplemobiletools.dialer.adapters.RecentCallsAdapter
import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.extensions.config
import com.simplemobiletools.dialer.helpers.Config import com.simplemobiletools.dialer.helpers.Config
import kotlinx.android.synthetic.main.fragment_letters_layout.view.* import kotlinx.android.synthetic.main.fragment_letters_layout.view.fragment_list
import kotlinx.android.synthetic.main.fragment_recents.view.* import kotlinx.android.synthetic.main.fragment_recents.view.recents_list
abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) { abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) {
protected var activity: SimpleActivity? = null protected var activity: SimpleActivity? = null
@ -45,6 +47,20 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
(recents_list?.adapter as? MyRecyclerViewAdapter)?.finishActMode() (recents_list?.adapter as? MyRecyclerViewAdapter)?.finishActMode()
} }
fun fontSizeChanged() {
if (this is RecentsFragment) {
(recents_list?.adapter as? RecentCallsAdapter)?.apply {
fontSize = activity.getTextSize()
notifyDataSetChanged()
}
} else {
(fragment_list?.adapter as? ContactsAdapter)?.apply {
fontSize = activity.getTextSize()
notifyDataSetChanged()
}
}
}
abstract fun setupFragment() abstract fun setupFragment()
abstract fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int) abstract fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int)

View File

@ -19,6 +19,7 @@ const val DIALPAD_VIBRATION = "dialpad_vibration"
const val DIALPAD_BEEPS = "dialpad_beeps" const val DIALPAD_BEEPS = "dialpad_beeps"
const val HIDE_DIALPAD_NUMBERS = "hide_dialpad_numbers" const val HIDE_DIALPAD_NUMBERS = "hide_dialpad_numbers"
const val ALWAYS_SHOW_FULLSCREEN = "always_show_fullscreen" const val ALWAYS_SHOW_FULLSCREEN = "always_show_fullscreen"
const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_CALL_HISTORY const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_CALL_HISTORY
val tabsList = arrayListOf(TAB_CONTACTS, TAB_FAVORITES, TAB_CALL_HISTORY) val tabsList = arrayListOf(TAB_CONTACTS, TAB_FAVORITES, TAB_CALL_HISTORY)

View File

@ -24,6 +24,16 @@
android:icon="@drawable/ic_delete_vector" android:icon="@drawable/ic_delete_vector"
android:title="@string/clear_call_history" android:title="@string/clear_call_history"
app:showAsAction="always" /> app:showAsAction="always" />
<item
android:id="@+id/change_view_type"
android:icon="@drawable/ic_change_view_vector"
android:title="@string/change_view_type"
app:showAsAction="ifRoom" />
<item
android:id="@+id/column_count"
android:icon="@drawable/ic_column_count_vector"
android:title="@string/column_count"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/settings" android:id="@+id/settings"
android:icon="@drawable/ic_settings_cog_vector" android:icon="@drawable/ic_settings_cog_vector"