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

Commit f6e07d9b authored by moezbhatti's avatar moezbhatti
Browse files

Add button to select contact, parse response as vCard string

parent 728af516
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
import android.provider.MediaStore
import android.text.format.DateFormat
import android.view.Menu
@@ -68,8 +69,9 @@ import javax.inject.Inject
class ComposeActivity : QkThemedActivity(), ComposeView {

    companion object {
        const val CAMERA_REQUEST_CODE = 0
        const val GALLERY_REQUEST_CODE = 1
        private const val CAMERA_REQUEST_CODE = 0
        private const val GALLERY_REQUEST_CODE = 1
        private const val CONTACT_REQUEST_CODE = 2
    }

    @Inject lateinit var attachmentAdapter: AttachmentAdapter
@@ -97,7 +99,9 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
    override val cameraIntent by lazy { Observable.merge(camera.clicks(), cameraLabel.clicks()) }
    override val galleryIntent by lazy { Observable.merge(gallery.clicks(), galleryLabel.clicks()) }
    override val scheduleIntent by lazy { Observable.merge(schedule.clicks(), scheduleLabel.clicks()) }
    override val attachContactIntent by lazy { Observable.merge(contact.clicks(), contactLabel.clicks()) }
    override val attachmentSelectedIntent: Subject<Uri> = PublishSubject.create()
    override val contactSelectedIntent: Subject<Uri> = PublishSubject.create()
    override val inputContentIntent by lazy { message.inputContentSelected }
    override val scheduleSelectedIntent: Subject<Long> = PublishSubject.create()
    override val changeSimIntent by lazy { sim.clicks() }
@@ -232,9 +236,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
        send.imageAlpha = if (state.canSend) 255 else 128
    }

    override fun clearSelection() {
        messageAdapter.clearSelection()
    }
    override fun clearSelection() = messageAdapter.clearSelection()

    override fun showDetails(details: String) {
        AlertDialog.Builder(this)
@@ -268,6 +270,13 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
        }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)).show()
    }

    override fun requestContact() {
        val intent = Intent(Intent.ACTION_PICK)
                .setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE)

        startActivityForResult(Intent.createChooser(intent, null), CONTACT_REQUEST_CODE)
    }

    override fun requestCamera() {
        cameraDestination = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
                .let { timestamp -> ContentValues().apply { put(MediaStore.Images.Media.TITLE, timestamp) } }
@@ -288,9 +297,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
        startActivityForResult(Intent.createChooser(intent, null), GALLERY_REQUEST_CODE)
    }

    override fun setDraft(draft: String) {
        message.setText(draft)
    }
    override fun setDraft(draft: String) = message.setText(draft)

    override fun scrollToMessage(id: Long) {
        messageAdapter.data?.second
@@ -323,15 +330,13 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                CAMERA_REQUEST_CODE -> cameraDestination
                GALLERY_REQUEST_CODE -> data?.data
                else -> null
            }?.let(attachmentSelectedIntent::onNext)
                CAMERA_REQUEST_CODE -> cameraDestination?.let(attachmentSelectedIntent::onNext)
                GALLERY_REQUEST_CODE -> data?.data?.let(attachmentSelectedIntent::onNext)
                CONTACT_REQUEST_CODE -> data?.data?.let(contactSelectedIntent::onNext)
            }
        }

    override fun onBackPressed() {
        backPressedIntent.onNext(Unit)
    }

    override fun onBackPressed() = backPressedIntent.onNext(Unit)

}
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
@@ -48,7 +48,9 @@ interface ComposeView : QkView<ComposeState> {
    val cameraIntent: Observable<*>
    val galleryIntent: Observable<*>
    val scheduleIntent: Observable<*>
    val attachContactIntent: Observable<*>
    val attachmentSelectedIntent: Observable<Uri>
    val contactSelectedIntent: Observable<Uri>
    val inputContentIntent: Observable<InputContentInfoCompat>
    val scheduleSelectedIntent: Observable<Long>
    val scheduleCancelIntent: Observable<*>
@@ -64,6 +66,7 @@ interface ComposeView : QkView<ComposeState> {
    fun requestCamera()
    fun requestGallery()
    fun requestDatePicker()
    fun requestContact()
    fun setDraft(draft: String)
    fun scrollToMessage(id: Long)
    fun showQksmsPlusSnackbar(@StringRes message: Int)
+32 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
package com.moez.QKSMS.feature.compose

import android.content.Context
import android.net.Uri
import android.provider.ContactsContract
import android.telephony.PhoneNumberUtils
import android.telephony.SmsMessage
import android.view.inputmethod.EditorInfo
@@ -68,10 +70,12 @@ import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
import io.realm.RealmList
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import javax.inject.Named


class ComposeViewModel @Inject constructor(
    @Named("query") private val query: String,
    @Named("threadId") private val threadId: Long,
@@ -519,6 +523,21 @@ class ComposeViewModel @Inject constructor(
                .autoDisposable(view.scope())
                .subscribe { scheduled -> newState { copy(scheduled = scheduled) } }

        // Attach a contact
        view.attachContactIntent
                .doOnNext { newState { copy(attaching = false) } }
                .autoDisposable(view.scope())
                .subscribe { view.requestContact() }

        // Contact was selected for attachment
        view.contactSelectedIntent
                .map(::vCard)
                .autoDisposable(view.scope())
                .subscribe({}, { error ->
                    context.makeToast(R.string.compose_contact_error)
                    Timber.w(error)
                })

        // Detach a photo
        view.attachmentDeletedIntent
                .withLatestFrom(attachments) { bitmap, attachments -> attachments.filter { it !== bitmap } }
@@ -678,4 +697,17 @@ class ComposeViewModel @Inject constructor(

    }

    private fun vCard(contactData: Uri): String? {
        val lookupKey = context.contentResolver.query(contactData, null, null, null, null)?.use { cursor ->
            cursor.moveToFirst()
            cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY))
        }

        val vCardUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey)
        return context.contentResolver.openAssetFileDescriptor(vCardUri, "r")
                ?.createInputStream()
                ?.readBytes()
                ?.let { bytes -> String(bytes) }
    }

}
 No newline at end of file
+36 −1
Original line number Diff line number Diff line
@@ -397,7 +397,8 @@
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        app:constraint_referenced_ids="schedule, scheduleLabel, gallery, galleryLabel, camera, cameraLabel, attachingBackground" />
        app:constraint_referenced_ids="contact, contactLabel, schedule, scheduleLabel, gallery, galleryLabel, camera,
         cameraLabel, attachingBackground" />

    <View
        android:id="@+id/attachingBackground"
@@ -410,6 +411,40 @@
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/contact"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginBottom="12dp"
        android:background="@drawable/circle"
        android:backgroundTint="?attr/bubbleColor"
        android:contentDescription="@string/compose_contact_cd"
        android:elevation="4dp"
        android:padding="10dp"
        android:src="@drawable/ic_person_black_24dp"
        android:tint="?android:attr/textColorSecondary"
        android:visibility="visible"
        app:layout_constraintBottom_toTopOf="@id/schedule"
        app:layout_constraintEnd_toEndOf="@id/attach"
        app:layout_constraintStart_toStartOf="@id/attach" />

    <com.moez.QKSMS.common.widget.QkTextView
        android:id="@+id/contactLabel"
        android:layout_width="wrap_content"
        android:layout_height="32dp"
        android:layout_marginStart="8dp"
        android:background="@drawable/rounded_rectangle_4dp"
        android:backgroundTint="?attr/bubbleColor"
        android:elevation="4dp"
        android:gravity="center_vertical"
        android:paddingEnd="8dp"
        android:paddingStart="8dp"
        android:text="@string/compose_contact_cd"
        android:textColor="?android:attr/textColorPrimary"
        app:layout_constraintBottom_toBottomOf="@id/contact"
        app:layout_constraintStart_toEndOf="@id/contact"
        app:layout_constraintTop_toTopOf="@id/contact" />

    <ImageView
        android:id="@+id/schedule"
        android:layout_width="40dp"
+2 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@
    <string name="compose_gallery_cd">Attach a photo</string>
    <string name="compose_camera_cd">Take a photo</string>
    <string name="compose_schedule_cd">Schedule message</string>
    <string name="compose_contact_cd">Attach a contact</string>
    <string name="compose_contact_error">Error reading contact</string>
    <string name="compose_sim_cd">%s selected, change SIM card</string>
    <string name="compose_send_cd">Send message</string>