Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd368ddd authored by moezbhatti's avatar moezbhatti Committed by Moez Bhatti
Browse files

Show button to add new contact

parent 73a36740
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import androidx.lifecycle.ViewModelProviders
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.jakewharton.rxbinding2.view.clicks
import com.jakewharton.rxbinding2.widget.editorActions
import com.jakewharton.rxbinding2.widget.textChanges
import com.moez.QKSMS.R
import com.moez.QKSMS.common.Navigator
@@ -86,9 +87,9 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
    @Inject lateinit var viewModelFactory: ViewModelProvider.Factory

    override val activityVisibleIntent: Subject<Boolean> = PublishSubject.create()
    override val queryChangedIntent: Observable<CharSequence> by lazy { chipsAdapter.textChanges }
    override val queryBackspaceIntent: Observable<*> by lazy { chipsAdapter.backspaces }
    override val queryEditorActionIntent: Observable<Int> by lazy { chipsAdapter.actions }
    override val queryChangedIntent: Observable<CharSequence> by lazy { search.textChanges() }
    override val queryBackspaceIntent: Observable<*> by lazy { search.backspaces }
    override val queryEditorActionIntent: Observable<Int> by lazy { search.editorActions() }
    override val chipSelectedIntent: Subject<ComposeItem> by lazy { contactsAdapter.itemSelected }
    override val chipDeletedIntent: Subject<Contact> by lazy { chipsAdapter.chipDeleted }
    override val menuReadyIntent: Observable<Unit> = menu.map { Unit }
@@ -191,14 +192,16 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
        toolbarSubtitle.text = getString(R.string.compose_subtitle_results, state.searchSelectionPosition, state.searchResults)

        toolbarTitle.setVisible(!state.editingMode)
        chips.setVisible(state.editingMode)
        contacts.setVisible(state.contactsVisible)
        composeBar.setVisible(!state.contactsVisible && !state.loading)
        chips.setVisible(state.editingMode && !state.searching)
        search.setVisible(state.editingMode && state.searching)
        contacts.setVisible(state.editingMode && state.searching)
        composeBar.setVisible(!state.searching && !state.loading)

        // Don't set the adapters unless needed
        if (state.editingMode && chips.adapter == null) chips.adapter = chipsAdapter
        if (state.editingMode && contacts.adapter == null) contacts.adapter = contactsAdapter

        toolbar.menu.findItem(R.id.add)?.isVisible = state.editingMode && !state.searching
        toolbar.menu.findItem(R.id.call)?.isVisible = !state.editingMode && state.selectedMessages == 0 && state.query.isEmpty()
        toolbar.menu.findItem(R.id.info)?.isVisible = !state.editingMode && state.selectedMessages == 0 && state.query.isEmpty()
        toolbar.menu.findItem(R.id.copy)?.isVisible = !state.editingMode && state.selectedMessages == 1
+1 −1
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ import io.realm.RealmResults
data class ComposeState(
    val hasError: Boolean = false,
    val editingMode: Boolean = false,
    val searching: Boolean = false,
    val composeItems: List<ComposeItem> = ArrayList(),
    val contactsVisible: Boolean = false,
    val selectedConversation: Long = 0,
    val selectedContacts: List<Contact> = ArrayList(),
    val sendAsGroup: Boolean = true,
+7 −8
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ class ComposeViewModel @Inject constructor(
    private val syncContacts: ContactSync
) : QkViewModel<ComposeView, ComposeState>(ComposeState(
        editingMode = threadId == 0L && address.isBlank(),
        searching = threadId == 0L && address.isBlank(),
        selectedConversation = threadId,
        query = query)
) {
@@ -243,17 +244,13 @@ class ComposeViewModel @Inject constructor(
    override fun bindView(view: ComposeView) {
        super.bindView(view)

        // Set the contact suggestions list to visible at all times when in editing mode and there are no contacts
        // selected yet, and also visible while in editing mode and there is text entered in the query field
        Observables
                .combineLatest(view.queryChangedIntent, selectedContacts) { query, selectedContacts ->
                    selectedContacts.isEmpty() || query.isNotEmpty()
                }
        // Set the contact suggestions list to visible when the add button is pressed
        view.optionsItemIntent
                .filter { it == R.id.add }
                .skipUntil(state.filter { state -> state.editingMode })
                .takeUntil(state.filter { state -> !state.editingMode })
                .distinctUntilChanged()
                .autoDisposable(view.scope())
                .subscribe { contactsVisible -> newState { copy(contactsVisible = contactsVisible && editingMode) } }
                .subscribe { newState { copy(searching = true) } }

        // Update the list of contact suggestions based on the query input, while also filtering out any contacts
        // that have already been selected
@@ -318,6 +315,7 @@ class ComposeViewModel @Inject constructor(
                .withLatestFrom(state) { _, state -> state }
                .autoDisposable(view.scope())
                .subscribe { state ->
                    newState { copy(searching = false) }
                    state.composeItems.firstOrNull()?.let { composeItem ->
                        contactsReducer.onNext { contacts -> contacts + composeItem.getContacts() }
                    }
@@ -329,6 +327,7 @@ class ComposeViewModel @Inject constructor(
                    contactsReducer.onNext { contacts -> contacts.filterNot { it == contact } }
                },
                view.chipSelectedIntent.doOnNext { composeItem ->
                    newState { copy(searching = false) }
                    contactsReducer.onNext { contacts ->
                        contacts.toMutableList().apply { addAll(composeItem.getContacts()) }
                    }
+17 −71
Original line number Diff line number Diff line
@@ -20,83 +20,35 @@ package com.moez.QKSMS.feature.compose.editing

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager
import com.jakewharton.rxbinding2.widget.editorActions
import com.jakewharton.rxbinding2.widget.textChanges
import com.moez.QKSMS.R
import com.moez.QKSMS.common.base.QkAdapter
import com.moez.QKSMS.common.base.QkViewHolder
import com.moez.QKSMS.common.util.extensions.dpToPx
import com.moez.QKSMS.common.util.extensions.resolveThemeColor
import com.moez.QKSMS.common.util.extensions.showKeyboard
import com.moez.QKSMS.common.widget.QkEditText
import com.moez.QKSMS.model.Contact
import io.reactivex.subjects.PublishSubject
import kotlinx.android.synthetic.main.contact_chip.view.*
import javax.inject.Inject

class ChipsAdapter @Inject constructor(private val context: Context) : QkAdapter<Contact>() {

    companion object {
        private const val TYPE_EDIT_TEXT = 0
        private const val TYPE_ITEM = 1
    }

    private val hint: String = context.getString(R.string.title_compose)
    private val editText = View.inflate(context, R.layout.chip_input_list_item, null) as QkEditText
class ChipsAdapter @Inject constructor() : QkAdapter<Contact>() {

    var view: RecyclerView? = null
    val chipDeleted: PublishSubject<Contact> = PublishSubject.create<Contact>()
    val textChanges = editText.textChanges()
    val actions = editText.editorActions()
    val backspaces = editText.backspaces

    init {
        val wrap = ViewGroup.LayoutParams.WRAP_CONTENT
        editText.layoutParams = FlexboxLayoutManager.LayoutParams(wrap, wrap).apply {
            minHeight = 36.dpToPx(context)
            minWidth = 56.dpToPx(context)
            flexGrow = 8f
        }

        editText.hint = hint
    }

    override fun onDatasetChanged() {
        editText.text = null
        editText.hint = if (itemCount == 1) hint else null

        if (itemCount != 2) {
            editText.showKeyboard()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
        TYPE_EDIT_TEXT -> {
            editText.setTextColor(parent.context.resolveThemeColor(android.R.attr.textColorPrimary))
            editText.setHintTextColor(parent.context.resolveThemeColor(android.R.attr.textColorTertiary))
            QkViewHolder(editText)
        }

        else -> {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QkViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val view = inflater.inflate(R.layout.contact_chip, parent, false)
            QkViewHolder(view).apply {
        return QkViewHolder(view).apply {
            view.setOnClickListener {
                val contact = getItem(adapterPosition)
                showDetailedChip(view.context, contact)
            }
        }
    }
    }

    override fun onBindViewHolder(holder: QkViewHolder, position: Int) {
        when (getItemViewType(position)) {
            TYPE_ITEM -> {
        val contact = getItem(position)
        val view = holder.containerView

@@ -110,12 +62,6 @@ class ChipsAdapter @Inject constructor(private val context: Context) : QkAdapter
            contact.numbers.firstOrNull { it.address.isNotBlank() }?.address ?: ""
        }
    }
        }
    }

    override fun getItemCount() = super.getItemCount() + 1

    override fun getItemViewType(position: Int) = if (position == itemCount - 1) TYPE_EDIT_TEXT else TYPE_ITEM

    /**
     * The [context] has to come from a view, because we're inflating a view that used themed attrs
+14 −0
Original line number Diff line number Diff line
@@ -376,6 +376,20 @@
                android:scrollbars="vertical"
                tools:visibility="gone" />

            <com.moez.QKSMS.common.widget.QkEditText
                android:id="@+id/search"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@null"
                android:hint="@string/title_compose"
                android:imeOptions="flagNoExtractUi"
                android:inputType="textFilter|textNoSuggestions"
                android:privateImeOptions="nm"
                android:textColor="?android:attr/textColorPrimary"
                android:textColorHint="?android:attr/textColorTertiary"
                android:visibility="gone"
                app:textSize="primary" />

        </LinearLayout>

    </androidx.appcompat.widget.Toolbar>
Loading