Add support for sending all types of files
This commit is contained in:
parent
8d75d5b133
commit
23643d3198
|
@ -93,17 +93,14 @@
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
<data android:mimeType="text/plain" />
|
<data android:mimeType="*/*" />
|
||||||
<data android:mimeType="image/*" />
|
|
||||||
<data android:mimeType="video/*" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
<data android:mimeType="image/*" />
|
<data android:mimeType="*/*" />
|
||||||
<data android:mimeType="video/*" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import android.app.Activity
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.graphics.drawable.LayerDrawable
|
import android.graphics.drawable.LayerDrawable
|
||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -27,21 +26,19 @@ import android.util.TypedValue
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.view.animation.OvershootInterpolator
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.LinearLayout.LayoutParams
|
import android.widget.LinearLayout.LayoutParams
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.appcompat.widget.AppCompatButton
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import com.bumptech.glide.Glide
|
import androidx.core.view.ViewCompat
|
||||||
import com.bumptech.glide.load.DataSource
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import androidx.core.view.children
|
||||||
import com.bumptech.glide.load.engine.GlideException
|
import androidx.core.view.updateLayoutParams
|
||||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
|
||||||
import com.bumptech.glide.request.RequestListener
|
|
||||||
import com.bumptech.glide.request.RequestOptions
|
|
||||||
import com.bumptech.glide.request.target.Target
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||||
|
@ -53,14 +50,17 @@ import com.simplemobiletools.commons.models.RadioItem
|
||||||
import com.simplemobiletools.commons.models.SimpleContact
|
import com.simplemobiletools.commons.models.SimpleContact
|
||||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
import com.simplemobiletools.smsmessenger.R
|
import com.simplemobiletools.smsmessenger.R
|
||||||
|
import com.simplemobiletools.smsmessenger.adapters.AttachmentsAdapter
|
||||||
import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter
|
import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter
|
||||||
import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter
|
import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter
|
||||||
import com.simplemobiletools.smsmessenger.dialogs.ScheduleMessageDialog
|
import com.simplemobiletools.smsmessenger.dialogs.ScheduleMessageDialog
|
||||||
import com.simplemobiletools.smsmessenger.extensions.*
|
import com.simplemobiletools.smsmessenger.extensions.*
|
||||||
import com.simplemobiletools.smsmessenger.helpers.*
|
import com.simplemobiletools.smsmessenger.helpers.*
|
||||||
import com.simplemobiletools.smsmessenger.models.*
|
import com.simplemobiletools.smsmessenger.models.*
|
||||||
|
import ezvcard.VCard
|
||||||
|
import ezvcard.property.FormattedName
|
||||||
|
import ezvcard.property.Telephone
|
||||||
import kotlinx.android.synthetic.main.activity_thread.*
|
import kotlinx.android.synthetic.main.activity_thread.*
|
||||||
import kotlinx.android.synthetic.main.item_attachment.view.*
|
|
||||||
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
@ -72,12 +72,6 @@ import java.io.OutputStream
|
||||||
|
|
||||||
class ThreadActivity : SimpleActivity() {
|
class ThreadActivity : SimpleActivity() {
|
||||||
private val MIN_DATE_TIME_DIFF_SECS = 300
|
private val MIN_DATE_TIME_DIFF_SECS = 300
|
||||||
private val PICK_ATTACHMENT_INTENT = 1
|
|
||||||
private val PICK_SAVE_FILE_INTENT = 11
|
|
||||||
private val TAKE_PHOTO_INTENT = 42
|
|
||||||
|
|
||||||
private val TYPE_TAKE_PHOTO = 12
|
|
||||||
private val TYPE_CHOOSE_PHOTO = 13
|
|
||||||
|
|
||||||
private val TYPE_EDIT = 14
|
private val TYPE_EDIT = 14
|
||||||
private val TYPE_SEND = 15
|
private val TYPE_SEND = 15
|
||||||
|
@ -93,8 +87,6 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private var privateContacts = ArrayList<SimpleContact>()
|
private var privateContacts = ArrayList<SimpleContact>()
|
||||||
private var messages = ArrayList<Message>()
|
private var messages = ArrayList<Message>()
|
||||||
private val availableSIMCards = ArrayList<SIMCard>()
|
private val availableSIMCards = ArrayList<SIMCard>()
|
||||||
private var attachmentSelections = mutableMapOf<String, AttachmentSelection>()
|
|
||||||
private val imageCompressor by lazy { ImageCompressor(this) }
|
|
||||||
private var lastAttachmentUri: String? = null
|
private var lastAttachmentUri: String? = null
|
||||||
private var capturedImageUri: Uri? = null
|
private var capturedImageUri: Uri? = null
|
||||||
private var loadingOlderMessages = false
|
private var loadingOlderMessages = false
|
||||||
|
@ -105,6 +97,8 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private var scheduledMessage: Message? = null
|
private var scheduledMessage: Message? = null
|
||||||
private lateinit var scheduledDateTime: DateTime
|
private lateinit var scheduledDateTime: DateTime
|
||||||
|
|
||||||
|
private var isAttachmentPickerVisible = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_thread)
|
setContentView(R.layout.activity_thread)
|
||||||
|
@ -145,6 +139,10 @@ class ThreadActivity : SimpleActivity() {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupAttachmentPickerView()
|
||||||
|
setupKeyboardListener()
|
||||||
|
hideAttachmentPicker()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
@ -161,7 +159,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
|
||||||
if (thread_type_message.value != "" && attachmentSelections.isEmpty()) {
|
if (thread_type_message.value != "" && getAttachments().isEmpty()) {
|
||||||
saveSmsDraft(thread_type_message.value, threadId)
|
saveSmsDraft(thread_type_message.value, threadId)
|
||||||
} else {
|
} else {
|
||||||
deleteSmsDraft(threadId)
|
deleteSmsDraft(threadId)
|
||||||
|
@ -172,6 +170,15 @@ class ThreadActivity : SimpleActivity() {
|
||||||
isActivityVisible = false
|
isActivityVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed() {
|
||||||
|
isAttachmentPickerVisible = false
|
||||||
|
if (attachment_picker_holder.isVisible()) {
|
||||||
|
hideAttachmentPicker()
|
||||||
|
} else {
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
bus?.unregister(this)
|
bus?.unregister(this)
|
||||||
|
@ -214,15 +221,30 @@ class ThreadActivity : SimpleActivity() {
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, resultData)
|
super.onActivityResult(requestCode, resultCode, resultData)
|
||||||
if (resultCode != Activity.RESULT_OK) return
|
if (resultCode != Activity.RESULT_OK) return
|
||||||
|
val data = resultData?.data
|
||||||
|
|
||||||
if (requestCode == TAKE_PHOTO_INTENT) {
|
when (requestCode) {
|
||||||
addAttachment(capturedImageUri!!)
|
CAPTURE_PHOTO_INTENT -> addAttachment(capturedImageUri!!)
|
||||||
} else if (requestCode == PICK_ATTACHMENT_INTENT && resultData != null && resultData.data != null) {
|
CAPTURE_VIDEO_INTENT -> if (data != null) {
|
||||||
addAttachment(resultData.data!!)
|
addAttachment(data)
|
||||||
} else if (requestCode == PICK_SAVE_FILE_INTENT && resultData != null && resultData.data != null) {
|
}
|
||||||
|
PICK_DOCUMENT_INTENT -> if (data != null) {
|
||||||
|
addAttachment(data)
|
||||||
|
}
|
||||||
|
CAPTURE_AUDIO_INTENT -> if (data != null) {
|
||||||
|
addAttachment(data)
|
||||||
|
}
|
||||||
|
PICK_PHOTO_VIDEO_INTENT -> if (data != null) {
|
||||||
|
addAttachment(data)
|
||||||
|
}
|
||||||
|
PICK_CONTACT_INTENT -> if (data != null) {
|
||||||
|
handleContactAttachment(data)
|
||||||
|
}
|
||||||
|
PICK_SAVE_FILE_INTENT -> if (data != null) {
|
||||||
saveAttachment(resultData)
|
saveAttachment(resultData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun onHomePressed() {
|
private fun onHomePressed() {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
|
@ -487,7 +509,14 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
thread_type_message.setText(intent.getStringExtra(THREAD_TEXT))
|
thread_type_message.setText(intent.getStringExtra(THREAD_TEXT))
|
||||||
thread_add_attachment.setOnClickListener {
|
thread_add_attachment.setOnClickListener {
|
||||||
takeOrPickPhotoVideo()
|
if (attachment_picker_holder.isVisible()) {
|
||||||
|
isAttachmentPickerVisible = false
|
||||||
|
showKeyboard(thread_type_message)
|
||||||
|
} else {
|
||||||
|
isAttachmentPickerVisible = true
|
||||||
|
hideKeyboard()
|
||||||
|
}
|
||||||
|
window.decorView.requestApplyInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.extras?.containsKey(THREAD_ATTACHMENT_URI) == true) {
|
if (intent.extras?.containsKey(THREAD_ATTACHMENT_URI) == true) {
|
||||||
|
@ -780,135 +809,134 @@ class ThreadActivity : SimpleActivity() {
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun takeOrPickPhotoVideo() {
|
private fun launchActivityForResult(intent: Intent, requestCode: Int, @StringRes error: Int = R.string.no_app_found) {
|
||||||
val items = arrayListOf(
|
hideKeyboard()
|
||||||
RadioItem(TYPE_TAKE_PHOTO, getString(R.string.take_photo)),
|
|
||||||
RadioItem(TYPE_CHOOSE_PHOTO, getString(R.string.choose_photo))
|
|
||||||
)
|
|
||||||
RadioGroupDialog(this, items = items) {
|
|
||||||
val checkedId = it as Int
|
|
||||||
if (checkedId == TYPE_TAKE_PHOTO) {
|
|
||||||
launchTakePhotoIntent()
|
|
||||||
} else if (checkedId == TYPE_CHOOSE_PHOTO) {
|
|
||||||
launchPickPhotoVideoIntent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun launchTakePhotoIntent() {
|
|
||||||
val imageFile = createImageFile()
|
|
||||||
capturedImageUri = getMyFileUri(imageFile)
|
|
||||||
try {
|
try {
|
||||||
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
|
startActivityForResult(intent, requestCode)
|
||||||
putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri)
|
|
||||||
}
|
|
||||||
startActivityForResult(intent, TAKE_PHOTO_INTENT)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
showErrorToast(getString(R.string.no_app_found))
|
showErrorToast(getString(error))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showErrorToast(e)
|
showErrorToast(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createTemporaryFile(extension: String = ".jpg"): File {
|
||||||
|
val outputDirectory = File(cacheDir, "captured").apply {
|
||||||
|
if (!exists()) {
|
||||||
|
mkdirs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return File.createTempFile("attachment_", extension, outputDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchCapturePhotoIntent() {
|
||||||
|
val imageFile = createTemporaryFile()
|
||||||
|
capturedImageUri = getMyFileUri(imageFile)
|
||||||
|
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
|
||||||
|
putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri)
|
||||||
|
}
|
||||||
|
launchActivityForResult(intent, CAPTURE_PHOTO_INTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchCaptureVideoIntent() {
|
||||||
|
val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
|
||||||
|
launchActivityForResult(intent, CAPTURE_VIDEO_INTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchCaptureAudioIntent() {
|
||||||
|
val intent = Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION)
|
||||||
|
launchActivityForResult(intent, CAPTURE_AUDIO_INTENT)
|
||||||
|
}
|
||||||
|
|
||||||
private fun launchPickPhotoVideoIntent() {
|
private fun launchPickPhotoVideoIntent() {
|
||||||
hideKeyboard()
|
|
||||||
val mimeTypes = arrayOf("image/*", "video/*")
|
val mimeTypes = arrayOf("image/*", "video/*")
|
||||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
type = "*/*"
|
type = "*/*"
|
||||||
putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
||||||
|
|
||||||
try {
|
launchActivityForResult(this, PICK_PHOTO_VIDEO_INTENT)
|
||||||
startActivityForResult(this, PICK_ATTACHMENT_INTENT)
|
}
|
||||||
} catch (e: ActivityNotFoundException) {
|
}
|
||||||
showErrorToast(getString(R.string.no_app_found))
|
|
||||||
} catch (e: Exception) {
|
private fun launchPickDocumentIntent() {
|
||||||
showErrorToast(e)
|
val mimeTypes = arrayOf("*/*")
|
||||||
|
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||||
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
|
type = "*/*"
|
||||||
|
putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
||||||
|
|
||||||
|
launchActivityForResult(this, PICK_DOCUMENT_INTENT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchPickContactIntent() {
|
||||||
|
val intent = Intent(Intent.ACTION_PICK).apply {
|
||||||
|
type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE
|
||||||
|
}
|
||||||
|
launchActivityForResult(intent, PICK_CONTACT_INTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleContactAttachment(contactUri: Uri) {
|
||||||
|
val projection = arrayOf(
|
||||||
|
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.NUMBER
|
||||||
|
)
|
||||||
|
queryCursor(contactUri, projection, null, null, null) { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
val nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
|
||||||
|
val numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
|
||||||
|
val name = cursor.getString(nameIndex)
|
||||||
|
val number = cursor.getString(numberIndex)
|
||||||
|
// todo: export all properties using VcfExporter
|
||||||
|
val vCard = VCard()
|
||||||
|
vCard.addTelephoneNumber(Telephone(number))
|
||||||
|
vCard.addFormattedName(FormattedName(name))
|
||||||
|
val file = createTemporaryFile(".vcf")
|
||||||
|
val outputStream = file.outputStream()
|
||||||
|
vCard.write(outputStream)
|
||||||
|
val vCardUri = getMyFileUri(file)
|
||||||
|
addAttachment(vCardUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getAttachmentsAdapter(): AttachmentsAdapter? {
|
||||||
|
val adapter = thread_attachments_recyclerview.adapter
|
||||||
|
return adapter as? AttachmentsAdapter
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAttachments() = getAttachmentsAdapter()?.attachments ?: emptyList()
|
||||||
|
|
||||||
private fun addAttachment(uri: Uri) {
|
private fun addAttachment(uri: Uri) {
|
||||||
val originalUriString = uri.toString()
|
if (getAttachments().any { it.uri.toString() == uri.toString() }) {
|
||||||
if (attachmentSelections.containsKey(originalUriString)) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentSelections[originalUriString] = AttachmentSelection(uri, false)
|
var adapter = getAttachmentsAdapter()
|
||||||
val attachmentView = addAttachmentView(originalUriString, uri)
|
if (adapter == null) {
|
||||||
val mimeType = contentResolver.getType(uri) ?: return
|
adapter = AttachmentsAdapter(
|
||||||
|
activity = this,
|
||||||
if (mimeType.isImageMimeType() && config.mmsFileSizeLimit != FILE_SIZE_NONE) {
|
onItemClick = {},
|
||||||
val selection = attachmentSelections[originalUriString]
|
onAttachmentsRemoved = {
|
||||||
attachmentSelections[originalUriString] = selection!!.copy(isPending = true)
|
thread_attachments_recyclerview.beGone()
|
||||||
checkSendMessageAvailability()
|
checkSendMessageAvailability()
|
||||||
attachmentView.thread_attachment_progress.beVisible()
|
},
|
||||||
imageCompressor.compressImage(uri, config.mmsFileSizeLimit) { compressedUri ->
|
onReady = { checkSendMessageAvailability() }
|
||||||
runOnUiThread {
|
)
|
||||||
if (compressedUri != null) {
|
thread_attachments_recyclerview.adapter = adapter
|
||||||
attachmentSelections[originalUriString] = AttachmentSelection(compressedUri, false)
|
|
||||||
loadAttachmentPreview(attachmentView, compressedUri)
|
|
||||||
} else {
|
|
||||||
toast(R.string.compress_error)
|
|
||||||
removeAttachment(attachmentView, originalUriString)
|
|
||||||
}
|
|
||||||
checkSendMessageAvailability()
|
|
||||||
attachmentView.thread_attachment_progress.beGone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addAttachmentView(originalUri: String, uri: Uri): View {
|
thread_attachments_recyclerview.beVisible()
|
||||||
thread_attachments_holder.beVisible()
|
val mimeType = contentResolver.getType(uri).orEmpty()
|
||||||
val attachmentView = layoutInflater.inflate(R.layout.item_attachment, null).apply {
|
val attachment = AttachmentSelection(
|
||||||
thread_attachments_wrapper.addView(this)
|
uri = uri,
|
||||||
thread_remove_attachment.setOnClickListener {
|
mimetype = mimeType,
|
||||||
removeAttachment(this, originalUri)
|
filename = getFilenameFromUri(uri),
|
||||||
}
|
isPending = mimeType.isImageMimeType()
|
||||||
}
|
)
|
||||||
|
adapter.addAttachment(attachment)
|
||||||
|
|
||||||
loadAttachmentPreview(attachmentView, uri)
|
|
||||||
return attachmentView
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadAttachmentPreview(attachmentView: View, uri: Uri) {
|
|
||||||
if (isDestroyed || isFinishing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val roundedCornersRadius = resources.getDimension(R.dimen.medium_margin).toInt()
|
|
||||||
val options = RequestOptions()
|
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
||||||
.transform(CenterCrop(), RoundedCorners(roundedCornersRadius))
|
|
||||||
|
|
||||||
Glide.with(attachmentView.thread_attachment_preview)
|
|
||||||
.load(uri)
|
|
||||||
.transition(DrawableTransitionOptions.withCrossFade())
|
|
||||||
.apply(options)
|
|
||||||
.listener(object : RequestListener<Drawable> {
|
|
||||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
|
|
||||||
attachmentView.thread_attachment_preview.beGone()
|
|
||||||
attachmentView.thread_remove_attachment.beGone()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResourceReady(dr: Drawable?, a: Any?, t: Target<Drawable>?, d: DataSource?, i: Boolean): Boolean {
|
|
||||||
attachmentView.thread_attachment_preview.beVisible()
|
|
||||||
attachmentView.thread_remove_attachment.beVisible()
|
|
||||||
checkSendMessageAvailability()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(attachmentView.thread_attachment_preview)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeAttachment(attachmentView: View, originalUri: String) {
|
|
||||||
thread_attachments_wrapper.removeView(attachmentView)
|
|
||||||
attachmentSelections.remove(originalUri)
|
|
||||||
if (attachmentSelections.isEmpty()) {
|
|
||||||
thread_attachments_holder.beGone()
|
|
||||||
}
|
|
||||||
checkSendMessageAvailability()
|
checkSendMessageAvailability()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,7 +961,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkSendMessageAvailability() {
|
private fun checkSendMessageAvailability() {
|
||||||
if (thread_type_message.text!!.isNotEmpty() || (attachmentSelections.isNotEmpty() && !attachmentSelections.values.any { it.isPending })) {
|
if (thread_type_message.text!!.isNotEmpty() || (getAttachments().isNotEmpty() && !getAttachments().any { it.isPending })) {
|
||||||
thread_send_message.isEnabled = true
|
thread_send_message.isEnabled = true
|
||||||
thread_send_message.isClickable = true
|
thread_send_message.isClickable = true
|
||||||
thread_send_message.alpha = 0.9f
|
thread_send_message.alpha = 0.9f
|
||||||
|
@ -947,7 +975,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
private fun sendMessage() {
|
private fun sendMessage() {
|
||||||
var text = thread_type_message.value
|
var text = thread_type_message.value
|
||||||
if (text.isEmpty() && attachmentSelections.isEmpty()) {
|
if (text.isEmpty() && getAttachments().isEmpty()) {
|
||||||
showErrorToast(getString(R.string.unknown_error_occurred))
|
showErrorToast(getString(R.string.unknown_error_occurred))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1002,8 +1030,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
private fun sendNormalMessage(text: String, subscriptionId: Int) {
|
private fun sendNormalMessage(text: String, subscriptionId: Int) {
|
||||||
val addresses = participants.getAddresses()
|
val addresses = participants.getAddresses()
|
||||||
val attachments = attachmentSelections.values
|
val attachments = getAttachments().map { it.uri }
|
||||||
.map { it.uri }
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
refreshedSinceSent = false
|
refreshedSinceSent = false
|
||||||
|
@ -1022,9 +1049,8 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
private fun clearCurrentMessage() {
|
private fun clearCurrentMessage() {
|
||||||
thread_type_message.setText("")
|
thread_type_message.setText("")
|
||||||
attachmentSelections.clear()
|
getAttachmentsAdapter()?.clear()
|
||||||
thread_attachments_holder.beGone()
|
checkSendMessageAvailability()
|
||||||
thread_attachments_wrapper.removeAllViews()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// show selected contacts, properly split to new lines when appropriate
|
// show selected contacts, properly split to new lines when appropriate
|
||||||
|
@ -1150,13 +1176,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
putExtra(Intent.EXTRA_TITLE, path.split("/").last())
|
putExtra(Intent.EXTRA_TITLE, path.split("/").last())
|
||||||
|
|
||||||
try {
|
launchActivityForResult(this, PICK_SAVE_FILE_INTENT, error = R.string.system_service_disabled)
|
||||||
startActivityForResult(this, PICK_SAVE_FILE_INTENT)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
showErrorToast(getString(R.string.system_service_disabled))
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,7 +1224,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private fun isMmsMessage(text: String): Boolean {
|
private fun isMmsMessage(text: String): Boolean {
|
||||||
val isGroupMms = participants.size > 1 && config.sendGroupMessageMMS
|
val isGroupMms = participants.size > 1 && config.sendGroupMessageMMS
|
||||||
val isLongMmsMessage = isLongMmsMessage(text) && config.sendLongMessageMMS
|
val isLongMmsMessage = isLongMmsMessage(text) && config.sendLongMessageMMS
|
||||||
return attachmentSelections.isNotEmpty() || isGroupMms || isLongMmsMessage
|
return getAttachments().isNotEmpty() || isGroupMms || isLongMmsMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateMessageType() {
|
private fun updateMessageType() {
|
||||||
|
@ -1217,15 +1237,6 @@ class ThreadActivity : SimpleActivity() {
|
||||||
thread_send_message.setText(stringId)
|
thread_send_message.setText(stringId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createImageFile(): File {
|
|
||||||
val outputDirectory = File(cacheDir, "captured").apply {
|
|
||||||
if (!exists()) {
|
|
||||||
mkdirs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return File.createTempFile("IMG_", ".jpg", outputDirectory)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showScheduledMessageInfo(message: Message) {
|
private fun showScheduledMessageInfo(message: Message) {
|
||||||
val items = arrayListOf(
|
val items = arrayListOf(
|
||||||
RadioItem(TYPE_EDIT, getString(R.string.update_message)),
|
RadioItem(TYPE_EDIT, getString(R.string.update_message)),
|
||||||
|
@ -1282,7 +1293,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
private fun setupScheduleSendUi() {
|
private fun setupScheduleSendUi() {
|
||||||
val textColor = getProperTextColor()
|
val textColor = getProperTextColor()
|
||||||
scheduled_message_holder.background.applyColorFilter(getProperBackgroundColor().getContrastColor())
|
scheduled_message_holder.background.applyColorFilter(getProperPrimaryColor().darkenColor())
|
||||||
scheduled_message_button.apply {
|
scheduled_message_button.apply {
|
||||||
val clockDrawable = ResourcesCompat.getDrawable(resources, R.drawable.ic_clock_vector, theme)?.apply { applyColorFilter(textColor) }
|
val clockDrawable = ResourcesCompat.getDrawable(resources, R.drawable.ic_clock_vector, theme)?.apply { applyColorFilter(textColor) }
|
||||||
setCompoundDrawablesWithIntrinsicBounds(clockDrawable, null, null, null)
|
setCompoundDrawablesWithIntrinsicBounds(clockDrawable, null, null, null)
|
||||||
|
@ -1358,10 +1369,94 @@ class ThreadActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildMessageAttachment(text: String, messageId: Long): MessageAttachment {
|
private fun buildMessageAttachment(text: String, messageId: Long): MessageAttachment {
|
||||||
val attachments = attachmentSelections.values
|
val attachments = getAttachments()
|
||||||
.map { Attachment(null, messageId, it.uri.toString(), contentResolver.getType(it.uri) ?: "*/*", 0, 0, "") }
|
.map { Attachment(null, messageId, it.uri.toString(), contentResolver.getType(it.uri) ?: "*/*", 0, 0, "") }
|
||||||
.toArrayList()
|
.toArrayList()
|
||||||
|
|
||||||
return MessageAttachment(messageId, text, attachments)
|
return MessageAttachment(messageId, text, attachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupAttachmentPickerView() {
|
||||||
|
val colors = arrayOf(
|
||||||
|
R.color.md_red_500,
|
||||||
|
R.color.md_pink_500,
|
||||||
|
R.color.md_purple_500,
|
||||||
|
R.color.md_teal_500,
|
||||||
|
R.color.md_green_500,
|
||||||
|
R.color.md_light_green_500,
|
||||||
|
R.color.md_blue_500
|
||||||
|
)
|
||||||
|
attachment_picker_holder.children.filterIsInstance<AppCompatButton>().forEachIndexed { index, button ->
|
||||||
|
button.setTextColor(getProperTextColor())
|
||||||
|
val color = resources.getColor(colors[index])
|
||||||
|
button.compoundDrawables.forEach { it?.applyColorFilter(color) }
|
||||||
|
}
|
||||||
|
pick_from_gallery.setOnClickListener {
|
||||||
|
launchPickPhotoVideoIntent()
|
||||||
|
}
|
||||||
|
camera.setOnClickListener {
|
||||||
|
launchCapturePhotoIntent()
|
||||||
|
}
|
||||||
|
record_video.setOnClickListener {
|
||||||
|
launchCaptureVideoIntent()
|
||||||
|
}
|
||||||
|
record_audio.setOnClickListener {
|
||||||
|
launchCaptureAudioIntent()
|
||||||
|
}
|
||||||
|
pick_file.setOnClickListener {
|
||||||
|
launchPickDocumentIntent()
|
||||||
|
}
|
||||||
|
pick_contact.setOnClickListener {
|
||||||
|
launchPickContactIntent()
|
||||||
|
}
|
||||||
|
schedule_message.setOnClickListener {
|
||||||
|
if (isScheduledMessage) {
|
||||||
|
launchScheduleSendDialog(scheduledDateTime)
|
||||||
|
} else {
|
||||||
|
launchScheduleSendDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAttachmentPicker() {
|
||||||
|
attachment_picker_divider.showWithAnimation()
|
||||||
|
attachment_picker_holder.showWithAnimation()
|
||||||
|
animateAttachmentButton(rotation = -135f)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideAttachmentPicker() {
|
||||||
|
attachment_picker_divider.beGone()
|
||||||
|
attachment_picker_holder.apply {
|
||||||
|
beGone()
|
||||||
|
updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
height = config.keyboardHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
animateAttachmentButton(rotation = 0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun animateAttachmentButton(rotation: Float) {
|
||||||
|
thread_add_attachment.animate()
|
||||||
|
.rotation(rotation)
|
||||||
|
.setDuration(500L)
|
||||||
|
.setInterpolator(OvershootInterpolator())
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupKeyboardListener() {
|
||||||
|
val typeMask = WindowInsetsCompat.Type.ime()
|
||||||
|
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { _, insets ->
|
||||||
|
if (insets.isVisible(typeMask)) {
|
||||||
|
config.keyboardHeight = insets.getInsets(typeMask).bottom
|
||||||
|
hideAttachmentPicker()
|
||||||
|
} else {
|
||||||
|
if (isAttachmentPickerVisible) {
|
||||||
|
showAttachmentPicker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
package com.simplemobiletools.smsmessenger.adapters
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
import com.simplemobiletools.smsmessenger.activities.VCardViewerActivity
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.config
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.isImageMimeType
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.isVideoMimeType
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.launchViewIntent
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.*
|
||||||
|
import com.simplemobiletools.smsmessenger.models.AttachmentSelection
|
||||||
|
import kotlinx.android.synthetic.main.item_attachment_media_preview.view.*
|
||||||
|
import kotlinx.android.synthetic.main.item_remove_attachment_button.view.*
|
||||||
|
|
||||||
|
class AttachmentsAdapter(
|
||||||
|
val activity: BaseSimpleActivity,
|
||||||
|
val onItemClick: (AttachmentSelection) -> Unit,
|
||||||
|
val onAttachmentsRemoved: () -> Unit,
|
||||||
|
val onReady: (() -> Unit)
|
||||||
|
) : ListAdapter<AttachmentSelection, AttachmentsAdapter.ViewHolder>(AttachmentDiffCallback()) {
|
||||||
|
|
||||||
|
private val config = activity.config
|
||||||
|
private val resources = activity.resources
|
||||||
|
private val primaryColor = activity.getProperPrimaryColor()
|
||||||
|
private val imageCompressor by lazy { ImageCompressor(activity) }
|
||||||
|
|
||||||
|
val attachments = mutableListOf<AttachmentSelection>()
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
attachments.clear()
|
||||||
|
submitList(ArrayList())
|
||||||
|
onAttachmentsRemoved()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAttachment(attachment: AttachmentSelection) {
|
||||||
|
attachments.removeAll { AttachmentSelection.areItemsTheSame(it, attachment) }
|
||||||
|
attachments.add(attachment)
|
||||||
|
submitList(attachments.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeAttachment(attachment: AttachmentSelection) {
|
||||||
|
attachments.removeAll { AttachmentSelection.areItemsTheSame(it, attachment) }
|
||||||
|
if (attachments.isEmpty()) {
|
||||||
|
onAttachmentsRemoved()
|
||||||
|
} else {
|
||||||
|
submitList(ArrayList(attachments))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return getItem(position).viewType
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val layoutRes = when (viewType) {
|
||||||
|
ATTACHMENT_DOCUMENT -> com.simplemobiletools.smsmessenger.R.layout.item_attachment_document_preview
|
||||||
|
ATTACHMENT_VCARD -> com.simplemobiletools.smsmessenger.R.layout.item_attachment_vcard_preview
|
||||||
|
ATTACHMENT_MEDIA -> com.simplemobiletools.smsmessenger.R.layout.item_attachment_media_preview
|
||||||
|
else -> throw IllegalArgumentException("Unknown view type: $viewType")
|
||||||
|
}
|
||||||
|
|
||||||
|
val view = activity.layoutInflater.inflate(layoutRes, parent, false)
|
||||||
|
return ViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
val attachment = getItem(position)
|
||||||
|
holder.bindView(attachment, allowSingleClick = true, allowLongClick = false) { view, position ->
|
||||||
|
when (attachment.viewType) {
|
||||||
|
ATTACHMENT_DOCUMENT -> {
|
||||||
|
view.setupDocumentPreview(
|
||||||
|
uri = attachment.uri,
|
||||||
|
title = attachment.filename,
|
||||||
|
attachment = true,
|
||||||
|
onClick = { activity.launchViewIntent(attachment.uri, attachment.mimetype, attachment.filename) },
|
||||||
|
onRemoveButtonClicked = { removeAttachment(attachment) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ATTACHMENT_VCARD -> {
|
||||||
|
view.setupVCardPreview(
|
||||||
|
activity = activity,
|
||||||
|
uri = attachment.uri,
|
||||||
|
attachment = true,
|
||||||
|
onClick = {
|
||||||
|
val intent = Intent(activity, VCardViewerActivity::class.java).also {
|
||||||
|
it.putExtra(EXTRA_VCARD_URI, attachment.uri)
|
||||||
|
}
|
||||||
|
activity.startActivity(intent)
|
||||||
|
},
|
||||||
|
onRemoveButtonClicked = { removeAttachment(attachment) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ATTACHMENT_MEDIA -> setupMediaPreview(view, attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupMediaPreview(view: View, attachment: AttachmentSelection) {
|
||||||
|
view.apply {
|
||||||
|
media_attachment_holder.background.applyColorFilter(primaryColor.darkenColor())
|
||||||
|
media_attachment_holder.setOnClickListener {
|
||||||
|
activity.launchViewIntent(attachment.uri, attachment.mimetype, attachment.filename)
|
||||||
|
}
|
||||||
|
remove_attachment_button.apply {
|
||||||
|
beVisible()
|
||||||
|
background.applyColorFilter(primaryColor)
|
||||||
|
setOnClickListener {
|
||||||
|
removeAttachment(attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachment.mimetype.isImageMimeType() && attachment.isPending && config.mmsFileSizeLimit != FILE_SIZE_NONE) {
|
||||||
|
thumbnail.beGone()
|
||||||
|
compression_progress.beVisible()
|
||||||
|
|
||||||
|
imageCompressor.compressImage(attachment.uri, config.mmsFileSizeLimit) { compressedUri ->
|
||||||
|
activity.runOnUiThread {
|
||||||
|
when (compressedUri) {
|
||||||
|
attachment.uri -> {
|
||||||
|
attachments.find { it.uri == attachment.uri }?.isPending = false
|
||||||
|
loadMediaPreview(view, attachment)
|
||||||
|
}
|
||||||
|
null -> {
|
||||||
|
activity.toast(com.simplemobiletools.smsmessenger.R.string.compress_error)
|
||||||
|
removeAttachment(attachment)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
attachments.remove(attachment)
|
||||||
|
addAttachment(attachment.copy(uri = compressedUri, isPending = false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadMediaPreview(view, attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadMediaPreview(view: View, attachment: AttachmentSelection) {
|
||||||
|
val roundedCornersRadius = resources.getDimension(com.simplemobiletools.smsmessenger.R.dimen.activity_margin).toInt()
|
||||||
|
val size = resources.getDimension(com.simplemobiletools.smsmessenger.R.dimen.attachment_preview_size).toInt()
|
||||||
|
|
||||||
|
val options = RequestOptions()
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
|
.transform(CenterCrop(), RoundedCorners(roundedCornersRadius))
|
||||||
|
|
||||||
|
Glide.with(view.thumbnail)
|
||||||
|
.load(attachment.uri)
|
||||||
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
|
.override(size, size)
|
||||||
|
.apply(options)
|
||||||
|
.listener(object : RequestListener<Drawable> {
|
||||||
|
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
|
||||||
|
removeAttachment(attachment)
|
||||||
|
activity.toast(com.simplemobiletools.smsmessenger.R.string.unknown_error_occurred)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(dr: Drawable?, a: Any?, t: Target<Drawable>?, d: DataSource?, i: Boolean): Boolean {
|
||||||
|
view.thumbnail.beVisible()
|
||||||
|
view.play_icon.beVisibleIf(attachment.mimetype.isVideoMimeType())
|
||||||
|
view.compression_progress.beGone()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(view.thumbnail)
|
||||||
|
}
|
||||||
|
|
||||||
|
open inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
fun bindView(
|
||||||
|
any: AttachmentSelection,
|
||||||
|
allowSingleClick: Boolean,
|
||||||
|
allowLongClick: Boolean,
|
||||||
|
callback: (itemView: View, adapterPosition: Int) -> Unit
|
||||||
|
): View {
|
||||||
|
return itemView.apply {
|
||||||
|
callback(this, adapterPosition)
|
||||||
|
|
||||||
|
if (allowSingleClick) {
|
||||||
|
setOnClickListener { viewClicked(any) }
|
||||||
|
setOnLongClickListener { if (allowLongClick) viewLongClicked() else viewClicked(any); true }
|
||||||
|
} else {
|
||||||
|
setOnClickListener(null)
|
||||||
|
setOnLongClickListener(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun viewClicked(any: AttachmentSelection) {
|
||||||
|
onItemClick.invoke(any)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun viewLongClicked() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AttachmentDiffCallback : DiffUtil.ItemCallback<AttachmentSelection>() {
|
||||||
|
override fun areItemsTheSame(oldItem: AttachmentSelection, newItem: AttachmentSelection): Boolean {
|
||||||
|
return AttachmentSelection.areItemsTheSame(oldItem, newItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: AttachmentSelection, newItem: AttachmentSelection): Boolean {
|
||||||
|
return AttachmentSelection.areContentsTheSame(oldItem, newItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,11 @@
|
||||||
package com.simplemobiletools.smsmessenger.adapters
|
package com.simplemobiletools.smsmessenger.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -38,7 +36,6 @@ import com.simplemobiletools.smsmessenger.extensions.*
|
||||||
import com.simplemobiletools.smsmessenger.helpers.*
|
import com.simplemobiletools.smsmessenger.helpers.*
|
||||||
import com.simplemobiletools.smsmessenger.models.*
|
import com.simplemobiletools.smsmessenger.models.*
|
||||||
import kotlinx.android.synthetic.main.item_attachment_image.view.*
|
import kotlinx.android.synthetic.main.item_attachment_image.view.*
|
||||||
import kotlinx.android.synthetic.main.item_attachment_vcard.view.*
|
|
||||||
import kotlinx.android.synthetic.main.item_received_message.view.*
|
import kotlinx.android.synthetic.main.item_received_message.view.*
|
||||||
import kotlinx.android.synthetic.main.item_received_message.view.thread_mesage_attachments_holder
|
import kotlinx.android.synthetic.main.item_received_message.view.thread_mesage_attachments_holder
|
||||||
import kotlinx.android.synthetic.main.item_received_message.view.thread_message_body
|
import kotlinx.android.synthetic.main.item_received_message.view.thread_message_body
|
||||||
|
@ -49,8 +46,6 @@ import kotlinx.android.synthetic.main.item_thread_date_time.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_error.view.*
|
import kotlinx.android.synthetic.main.item_thread_error.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_sending.view.*
|
import kotlinx.android.synthetic.main.item_thread_sending.view.*
|
||||||
import kotlinx.android.synthetic.main.item_thread_success.view.*
|
import kotlinx.android.synthetic.main.item_thread_success.view.*
|
||||||
import kotlinx.android.synthetic.main.item_unknown_attachment.view.*
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class ThreadAdapter(
|
class ThreadAdapter(
|
||||||
activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit, val onThreadIdUpdate: (Long) -> Unit
|
activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit, val onThreadIdUpdate: (Long) -> Unit
|
||||||
|
@ -386,7 +381,7 @@ class ThreadAdapter(
|
||||||
if (actModeCallback.isSelectable) {
|
if (actModeCallback.isSelectable) {
|
||||||
holder.viewClicked(message)
|
holder.viewClicked(message)
|
||||||
} else {
|
} else {
|
||||||
launchViewIntent(uri, mimetype, attachment.filename)
|
activity.launchViewIntent(uri, mimetype, attachment.filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imageView.setOnLongClickListener {
|
imageView.setOnLongClickListener {
|
||||||
|
@ -400,34 +395,10 @@ class ThreadAdapter(
|
||||||
val uri = attachment.getUri()
|
val uri = attachment.getUri()
|
||||||
parent.apply {
|
parent.apply {
|
||||||
val vCardView = layoutInflater.inflate(R.layout.item_attachment_vcard, null).apply {
|
val vCardView = layoutInflater.inflate(R.layout.item_attachment_vcard, null).apply {
|
||||||
background.applyColorFilter(backgroundColor.getContrastColor())
|
setupVCardPreview(
|
||||||
vcard_title.setTextColor(textColor)
|
activity = activity,
|
||||||
vcard_subtitle.setTextColor(textColor)
|
uri = uri,
|
||||||
view_contact_details.setTextColor(properPrimaryColor)
|
onClick = {
|
||||||
}
|
|
||||||
thread_mesage_attachments_holder.addView(vCardView)
|
|
||||||
|
|
||||||
parseVCardFromUri(context, uri) { vCards ->
|
|
||||||
val title = vCards.firstOrNull()?.parseNameFromVCard()
|
|
||||||
val imageIcon = if (title != null) {
|
|
||||||
SimpleContactsHelper(context).getContactLetterIcon(title)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
activity.runOnUiThread {
|
|
||||||
vCardView.apply {
|
|
||||||
vcard_title.text = title
|
|
||||||
vcard_photo.setImageBitmap(imageIcon)
|
|
||||||
|
|
||||||
if (vCards.size > 1) {
|
|
||||||
vcard_subtitle.beVisible()
|
|
||||||
val quantity = vCards.size - 1
|
|
||||||
vcard_subtitle.text = resources.getQuantityString(R.plurals.and_other_contacts, quantity, quantity)
|
|
||||||
} else {
|
|
||||||
vcard_subtitle.beGone()
|
|
||||||
}
|
|
||||||
|
|
||||||
setOnClickListener {
|
|
||||||
if (actModeCallback.isSelectable) {
|
if (actModeCallback.isSelectable) {
|
||||||
holder.viewClicked(message)
|
holder.viewClicked(message)
|
||||||
} else {
|
} else {
|
||||||
|
@ -436,14 +407,11 @@ class ThreadAdapter(
|
||||||
}
|
}
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onLongClick = { holder.viewLongClicked() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
setOnLongClickListener {
|
thread_mesage_attachments_holder.addView(vCardView)
|
||||||
holder.viewLongClicked()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,66 +419,24 @@ class ThreadAdapter(
|
||||||
val mimetype = attachment.mimetype
|
val mimetype = attachment.mimetype
|
||||||
val uri = attachment.getUri()
|
val uri = attachment.getUri()
|
||||||
parent.apply {
|
parent.apply {
|
||||||
val attachmentView = layoutInflater.inflate(R.layout.item_unknown_attachment, null).apply {
|
val attachmentView = layoutInflater.inflate(R.layout.item_attachment_document, null).apply {
|
||||||
if (attachment.filename.isNotEmpty()) {
|
setupDocumentPreview(
|
||||||
filename.text = attachment.filename
|
uri = uri,
|
||||||
}
|
title = attachment.filename,
|
||||||
|
onClick = {
|
||||||
val size = context.contentResolver
|
|
||||||
.openInputStream(uri)
|
|
||||||
?.use { it.readBytes() }
|
|
||||||
?.size
|
|
||||||
|
|
||||||
if (size != null) {
|
|
||||||
file_size.beVisible()
|
|
||||||
file_size.text = size.formatSize()
|
|
||||||
} else {
|
|
||||||
file_size.beGone()
|
|
||||||
}
|
|
||||||
|
|
||||||
background.applyColorFilter(textColor)
|
|
||||||
filename.setTextColor(textColor)
|
|
||||||
file_size.setTextColor(textColor)
|
|
||||||
icon.background.setTint(properPrimaryColor)
|
|
||||||
|
|
||||||
setOnClickListener {
|
|
||||||
if (actModeCallback.isSelectable) {
|
if (actModeCallback.isSelectable) {
|
||||||
holder.viewClicked(message)
|
holder.viewClicked(message)
|
||||||
} else {
|
} else {
|
||||||
launchViewIntent(uri, mimetype, attachment.filename)
|
activity.launchViewIntent(uri, mimetype, attachment.filename)
|
||||||
}
|
|
||||||
}
|
|
||||||
setOnLongClickListener {
|
|
||||||
holder.viewLongClicked()
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onLongClick = { holder.viewLongClicked() },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
thread_mesage_attachments_holder.addView(attachmentView)
|
thread_mesage_attachments_holder.addView(attachmentView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun launchViewIntent(uri: Uri, mimetype: String, filename: String) {
|
|
||||||
Intent().apply {
|
|
||||||
action = Intent.ACTION_VIEW
|
|
||||||
setDataAndType(uri, mimetype.lowercase(Locale.getDefault()))
|
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
|
||||||
|
|
||||||
try {
|
|
||||||
activity.hideKeyboard()
|
|
||||||
activity.startActivity(this)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
val newMimetype = filename.getMimeType()
|
|
||||||
if (newMimetype.isNotEmpty() && mimetype != newMimetype) {
|
|
||||||
launchViewIntent(uri, newMimetype, filename)
|
|
||||||
} else {
|
|
||||||
activity.toast(R.string.no_app_found)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
activity.showErrorToast(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupDateTime(view: View, dateTime: ThreadDateTime) {
|
private fun setupDateTime(view: View, dateTime: ThreadDateTime) {
|
||||||
view.apply {
|
view.apply {
|
||||||
thread_date_time.apply {
|
thread_date_time.apply {
|
||||||
|
|
|
@ -4,10 +4,12 @@ import android.app.Activity
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import com.simplemobiletools.commons.extensions.getMimeType
|
||||||
import com.simplemobiletools.commons.extensions.hideKeyboard
|
import com.simplemobiletools.commons.extensions.hideKeyboard
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
import com.simplemobiletools.smsmessenger.R
|
import com.simplemobiletools.smsmessenger.R
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
fun Activity.dialNumber(phoneNumber: String, callback: (() -> Unit)? = null) {
|
fun Activity.dialNumber(phoneNumber: String, callback: (() -> Unit)? = null) {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
|
@ -24,3 +26,25 @@ fun Activity.dialNumber(phoneNumber: String, callback: (() -> Unit)? = null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Activity.launchViewIntent(uri: Uri, mimetype: String, filename: String) {
|
||||||
|
Intent().apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
setDataAndType(uri, mimetype.lowercase(Locale.getDefault()))
|
||||||
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
|
||||||
|
try {
|
||||||
|
hideKeyboard()
|
||||||
|
startActivity(this)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
val newMimetype = filename.getMimeType()
|
||||||
|
if (newMimetype.isNotEmpty() && mimetype != newMimetype) {
|
||||||
|
launchViewIntent(uri, newMimetype, filename)
|
||||||
|
} else {
|
||||||
|
toast(R.string.no_app_found)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -335,6 +335,7 @@ fun Context.getMmsAttachment(id: Long, getImageResolutions: Boolean): MessageAtt
|
||||||
val attachment = Attachment(partId, id, Uri.withAppendedPath(uri, partId.toString()).toString(), mimetype, 0, 0, attachmentName)
|
val attachment = Attachment(partId, id, Uri.withAppendedPath(uri, partId.toString()).toString(), mimetype, 0, 0, attachmentName)
|
||||||
messageAttachment.attachments.add(attachment)
|
messageAttachment.attachments.add(attachment)
|
||||||
} else {
|
} else {
|
||||||
|
// todo: fix filename parsing, xml is shown some sometimes
|
||||||
val text = cursor.getStringValue(Mms.Part.TEXT)
|
val text = cursor.getStringValue(Mms.Part.TEXT)
|
||||||
val cutName = text.substringAfter("ref src=\"").substringBefore("\"")
|
val cutName = text.substringAfter("ref src=\"").substringBefore("\"")
|
||||||
if (cutName.isNotEmpty()) {
|
if (cutName.isNotEmpty()) {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.simplemobiletools.smsmessenger.extensions
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.animation.doOnStart
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
|
||||||
|
fun View.showWithAnimation(duration: Long = 250L) {
|
||||||
|
if (!isVisible) {
|
||||||
|
ObjectAnimator.ofFloat(
|
||||||
|
this, "alpha", 0f, 1f
|
||||||
|
).apply {
|
||||||
|
this.duration = duration
|
||||||
|
doOnStart { visibility = View.VISIBLE }
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,4 +86,8 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
var wasDbCleared: Boolean
|
var wasDbCleared: Boolean
|
||||||
get() = prefs.getBoolean(WAS_DB_CLEARED, false)
|
get() = prefs.getBoolean(WAS_DB_CLEARED, false)
|
||||||
set(wasDbCleared) = prefs.edit().putBoolean(WAS_DB_CLEARED, wasDbCleared).apply()
|
set(wasDbCleared) = prefs.edit().putBoolean(WAS_DB_CLEARED, wasDbCleared).apply()
|
||||||
|
|
||||||
|
var keyboardHeight: Int
|
||||||
|
get() = prefs.getInt(SOFT_KEYBOARD_HEIGHT, 600)
|
||||||
|
set(value) = prefs.edit().putInt(SOFT_KEYBOARD_HEIGHT, value).apply()
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ const val IMPORT_MMS = "import_mms"
|
||||||
const val WAS_DB_CLEARED = "was_db_cleared_2"
|
const val WAS_DB_CLEARED = "was_db_cleared_2"
|
||||||
const val EXTRA_VCARD_URI = "vcard"
|
const val EXTRA_VCARD_URI = "vcard"
|
||||||
const val SCHEDULED_MESSAGE_ID = "scheduled_message_id"
|
const val SCHEDULED_MESSAGE_ID = "scheduled_message_id"
|
||||||
|
const val SOFT_KEYBOARD_HEIGHT = "soft_keyboard_height"
|
||||||
|
|
||||||
private const val PATH = "com.simplemobiletools.smsmessenger.action."
|
private const val PATH = "com.simplemobiletools.smsmessenger.action."
|
||||||
const val MARK_AS_READ = PATH + "mark_as_read"
|
const val MARK_AS_READ = PATH + "mark_as_read"
|
||||||
|
@ -45,6 +46,11 @@ const val THREAD_SENT_MESSAGE_ERROR = 4
|
||||||
const val THREAD_SENT_MESSAGE_SENT = 5
|
const val THREAD_SENT_MESSAGE_SENT = 5
|
||||||
const val THREAD_SENT_MESSAGE_SENDING = 6
|
const val THREAD_SENT_MESSAGE_SENDING = 6
|
||||||
|
|
||||||
|
// view types for attachment list
|
||||||
|
const val ATTACHMENT_DOCUMENT = 7
|
||||||
|
const val ATTACHMENT_MEDIA = 8
|
||||||
|
const val ATTACHMENT_VCARD = 9
|
||||||
|
|
||||||
// lock screen visibility constants
|
// lock screen visibility constants
|
||||||
const val LOCK_SCREEN_SENDER_MESSAGE = 1
|
const val LOCK_SCREEN_SENDER_MESSAGE = 1
|
||||||
const val LOCK_SCREEN_SENDER = 2
|
const val LOCK_SCREEN_SENDER = 2
|
||||||
|
@ -60,6 +66,15 @@ const val FILE_SIZE_2_MB = 2_097_152L
|
||||||
|
|
||||||
const val MESSAGES_LIMIT = 50
|
const val MESSAGES_LIMIT = 50
|
||||||
|
|
||||||
|
// intent launch request codes
|
||||||
|
const val PICK_PHOTO_VIDEO_INTENT = 42
|
||||||
|
const val PICK_SAVE_FILE_INTENT = 43
|
||||||
|
const val CAPTURE_PHOTO_INTENT = 44
|
||||||
|
const val CAPTURE_VIDEO_INTENT = 45
|
||||||
|
const val CAPTURE_AUDIO_INTENT = 46
|
||||||
|
const val PICK_DOCUMENT_INTENT = 47
|
||||||
|
const val PICK_CONTACT_INTENT = 48
|
||||||
|
|
||||||
fun refreshMessages() {
|
fun refreshMessages() {
|
||||||
EventBus.getDefault().post(Events.RefreshMessages())
|
EventBus.getDefault().post(Events.RefreshMessages())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.simplemobiletools.smsmessenger.helpers
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.View
|
||||||
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.getFileSizeFromUri
|
||||||
|
import kotlinx.android.synthetic.main.item_attachment_document.view.*
|
||||||
|
import kotlinx.android.synthetic.main.item_remove_attachment_button.view.*
|
||||||
|
|
||||||
|
fun View.setupDocumentPreview(
|
||||||
|
uri: Uri,
|
||||||
|
title: String,
|
||||||
|
attachment: Boolean = false,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
onLongClick: (() -> Unit)? = null,
|
||||||
|
onRemoveButtonClicked: (() -> Unit)? = null
|
||||||
|
) {
|
||||||
|
if (title.isNotEmpty()) {
|
||||||
|
filename.text = title
|
||||||
|
}
|
||||||
|
|
||||||
|
val size = context.getFileSizeFromUri(uri)
|
||||||
|
file_size.beVisible()
|
||||||
|
file_size.text = size.formatSize()
|
||||||
|
|
||||||
|
val textColor = context.getProperTextColor()
|
||||||
|
val primaryColor = context.getProperPrimaryColor()
|
||||||
|
|
||||||
|
document_attachment_holder.background.applyColorFilter(textColor)
|
||||||
|
filename.setTextColor(textColor)
|
||||||
|
file_size.setTextColor(textColor)
|
||||||
|
// todo: set icon drawable based on mime type
|
||||||
|
icon.background.setTint(primaryColor)
|
||||||
|
document_attachment_holder.background.applyColorFilter(primaryColor.darkenColor())
|
||||||
|
|
||||||
|
if (attachment) {
|
||||||
|
remove_attachment_button.apply {
|
||||||
|
beVisible()
|
||||||
|
background.applyColorFilter(primaryColor)
|
||||||
|
if (onRemoveButtonClicked != null) {
|
||||||
|
setOnClickListener {
|
||||||
|
onRemoveButtonClicked.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document_attachment_holder.setOnClickListener {
|
||||||
|
onClick?.invoke()
|
||||||
|
}
|
||||||
|
document_attachment_holder.setOnLongClickListener {
|
||||||
|
onLongClick?.invoke()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.simplemobiletools.smsmessenger.helpers
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.View
|
||||||
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
|
||||||
|
import com.simplemobiletools.smsmessenger.R
|
||||||
|
import kotlinx.android.synthetic.main.item_attachment_vcard.view.*
|
||||||
|
import kotlinx.android.synthetic.main.item_attachment_vcard_preview.view.*
|
||||||
|
import kotlinx.android.synthetic.main.item_remove_attachment_button.view.*
|
||||||
|
|
||||||
|
fun View.setupVCardPreview(
|
||||||
|
activity: Activity,
|
||||||
|
uri: Uri,
|
||||||
|
attachment: Boolean = false,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
onLongClick: (() -> Unit)? = null,
|
||||||
|
onRemoveButtonClicked: (() -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
val textColor = activity.getProperTextColor()
|
||||||
|
val primaryColor = activity.getProperPrimaryColor()
|
||||||
|
|
||||||
|
vcard_attachment_holder.background.applyColorFilter(primaryColor.darkenColor())
|
||||||
|
vcard_title.setTextColor(textColor)
|
||||||
|
vcard_subtitle.setTextColor(textColor)
|
||||||
|
|
||||||
|
if (attachment) {
|
||||||
|
vcard_progress.beVisible()
|
||||||
|
}
|
||||||
|
arrayOf(vcard_photo, vcard_title, vcard_subtitle, view_contact_details).forEach {
|
||||||
|
it.beGone()
|
||||||
|
}
|
||||||
|
|
||||||
|
parseVCardFromUri(activity, uri) { vCards ->
|
||||||
|
val title = vCards.firstOrNull()?.parseNameFromVCard()
|
||||||
|
val imageIcon = if (title != null) {
|
||||||
|
SimpleContactsHelper(activity).getContactLetterIcon(title)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
activity.runOnUiThread {
|
||||||
|
arrayOf(vcard_photo, vcard_title).forEach {
|
||||||
|
it.beVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
vcard_photo.setImageBitmap(imageIcon)
|
||||||
|
vcard_title.text = title
|
||||||
|
|
||||||
|
if (vCards.size > 1) {
|
||||||
|
vcard_subtitle.beVisible()
|
||||||
|
val quantity = vCards.size - 1
|
||||||
|
vcard_subtitle.text = resources.getQuantityString(R.plurals.and_other_contacts, quantity, quantity)
|
||||||
|
} else {
|
||||||
|
vcard_subtitle.beGone()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachment) {
|
||||||
|
vcard_progress.beGone()
|
||||||
|
remove_attachment_button.apply {
|
||||||
|
beVisible()
|
||||||
|
background.applyColorFilter(primaryColor)
|
||||||
|
if (onRemoveButtonClicked != null) {
|
||||||
|
setOnClickListener {
|
||||||
|
onRemoveButtonClicked.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view_contact_details.setTextColor(primaryColor)
|
||||||
|
view_contact_details.beVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
vcard_attachment_holder.setOnClickListener {
|
||||||
|
onClick?.invoke()
|
||||||
|
}
|
||||||
|
vcard_attachment_holder.setOnLongClickListener {
|
||||||
|
onLongClick?.invoke()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,35 @@
|
||||||
package com.simplemobiletools.smsmessenger.models
|
package com.simplemobiletools.smsmessenger.models
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.isImageMimeType
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.isVCardMimeType
|
||||||
|
import com.simplemobiletools.smsmessenger.extensions.isVideoMimeType
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.ATTACHMENT_DOCUMENT
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.ATTACHMENT_MEDIA
|
||||||
|
import com.simplemobiletools.smsmessenger.helpers.ATTACHMENT_VCARD
|
||||||
|
|
||||||
data class AttachmentSelection(
|
data class AttachmentSelection(
|
||||||
val uri: Uri,
|
val uri: Uri,
|
||||||
val isPending: Boolean,
|
val mimetype: String,
|
||||||
)
|
val filename: String,
|
||||||
|
var isPending: Boolean,
|
||||||
|
val viewType: Int = getViewTypeForMimeType(mimetype)
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun getViewTypeForMimeType(mimetype: String): Int {
|
||||||
|
return when {
|
||||||
|
mimetype.isImageMimeType() || mimetype.isVideoMimeType() -> ATTACHMENT_MEDIA
|
||||||
|
mimetype.isVCardMimeType() -> ATTACHMENT_VCARD
|
||||||
|
else -> ATTACHMENT_DOCUMENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun areItemsTheSame(first: AttachmentSelection, second: AttachmentSelection): Boolean {
|
||||||
|
return first.uri == second.uri
|
||||||
|
}
|
||||||
|
|
||||||
|
fun areContentsTheSame(first: AttachmentSelection, second: AttachmentSelection): Boolean {
|
||||||
|
return first.uri == second.uri && first.mimetype == second.mimetype && first.filename == second.filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M10,16.5l6,-4.5 -6,-4.5v9zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z" />
|
||||||
|
</vector>
|
|
@ -22,10 +22,10 @@
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/thread_holder"
|
android:id="@+id/thread_holder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="@dimen/tiny_margin"
|
android:layout_marginBottom="@dimen/tiny_margin"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -106,9 +107,9 @@
|
||||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||||
android:id="@+id/thread_messages_fastscroller"
|
android:id="@+id/thread_messages_fastscroller"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_above="@+id/message_divider"
|
app:layout_constraintBottom_toTopOf="@id/message_divider"
|
||||||
android:layout_below="@+id/thread_add_contacts"
|
app:layout_constraintTop_toBottomOf="@id/thread_add_contacts"
|
||||||
app:supportSwipeToRefresh="true">
|
app:supportSwipeToRefresh="true">
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
|
@ -130,43 +131,47 @@
|
||||||
android:id="@+id/message_divider"
|
android:id="@+id/message_divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1px"
|
android:layout_height="1px"
|
||||||
android:layout_above="@+id/scheduled_message_holder"
|
|
||||||
android:background="@color/divider_grey"
|
android:background="@color/divider_grey"
|
||||||
android:importantForAccessibility="no" />
|
android:importantForAccessibility="no"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/scheduled_message_holder"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/thread_messages_fastscroller"
|
||||||
|
tools:layout_height="1dp" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/thread_add_attachment"
|
android:id="@+id/thread_add_attachment"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
android:layout_height="@dimen/normal_icon_size"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_marginStart="@dimen/small_margin"
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_marginTop="@dimen/small_margin"
|
|
||||||
android:layout_marginEnd="@dimen/small_margin"
|
|
||||||
android:alpha="0.9"
|
android:alpha="0.9"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/attachment"
|
android:contentDescription="@string/attachment"
|
||||||
android:padding="@dimen/normal_margin"
|
android:padding="@dimen/normal_margin"
|
||||||
android:src="@drawable/ic_plus_vector" />
|
android:src="@drawable/ic_plus_vector"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_divider"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<RelativeLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:id="@+id/scheduled_message_holder"
|
android:id="@+id/scheduled_message_holder"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_above="@+id/thread_attachments_holder"
|
android:layout_marginStart="@dimen/normal_margin"
|
||||||
android:layout_alignStart="@id/thread_type_message"
|
|
||||||
android:layout_marginTop="@dimen/medium_margin"
|
android:layout_marginTop="@dimen/medium_margin"
|
||||||
android:layout_marginEnd="@dimen/medium_margin"
|
android:layout_marginEnd="@dimen/medium_margin"
|
||||||
android:layout_marginBottom="@dimen/small_margin"
|
|
||||||
android:background="@drawable/section_holder_stroke"
|
android:background="@drawable/section_holder_stroke"
|
||||||
|
android:orientation="horizontal"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/thread_attachments_recyclerview"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/message_divider"
|
||||||
|
app:layout_goneMarginBottom="@dimen/medium_margin"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyTextView
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
android:id="@+id/scheduled_message_button"
|
android:id="@+id/scheduled_message_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_gravity="start"
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:drawableStart="@drawable/ic_clock_vector"
|
android:drawableStart="@drawable/ic_clock_vector"
|
||||||
|
@ -184,57 +189,55 @@
|
||||||
android:id="@+id/discard_scheduled_message"
|
android:id="@+id/discard_scheduled_message"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
android:layout_height="@dimen/normal_icon_size"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_gravity="end"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/cancel_schedule_send"
|
android:contentDescription="@string/cancel_schedule_send"
|
||||||
android:padding="@dimen/normal_margin"
|
android:padding="@dimen/normal_margin"
|
||||||
android:src="@drawable/ic_cross_vector" />
|
android:src="@drawable/ic_cross_vector" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
<HorizontalScrollView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/thread_attachments_holder"
|
android:id="@+id/thread_attachments_recyclerview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_above="@+id/thread_type_message"
|
android:layout_marginTop="@dimen/tiny_margin"
|
||||||
android:layout_alignStart="@+id/thread_type_message"
|
|
||||||
android:layout_marginTop="@dimen/medium_margin"
|
|
||||||
android:layout_marginBottom="@dimen/small_margin"
|
android:layout_marginBottom="@dimen/small_margin"
|
||||||
android:overScrollMode="never"
|
android:clipToPadding="false"
|
||||||
android:scrollbars="none"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/thread_attachments_wrapper"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="@dimen/attachment_preview_size"
|
|
||||||
android:divider="@drawable/linear_layout_horizontal_divider"
|
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="@dimen/normal_margin"
|
||||||
android:paddingEnd="@dimen/normal_margin"
|
android:paddingEnd="@dimen/normal_margin"
|
||||||
android:showDividers="middle" />
|
android:scrollbars="none"
|
||||||
</HorizontalScrollView>
|
android:visibility="gone"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/thread_type_message"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/scheduled_message_holder"
|
||||||
|
app:layout_goneMarginTop="@dimen/medium_margin"
|
||||||
|
tools:itemCount="2"
|
||||||
|
tools:listitem="@layout/item_attachment_document_preview"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyEditText
|
<com.simplemobiletools.commons.views.MyEditText
|
||||||
android:id="@+id/thread_type_message"
|
android:id="@+id/thread_type_message"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_marginStart="@dimen/small_margin"
|
||||||
android:layout_marginEnd="@dimen/small_margin"
|
android:layout_marginEnd="@dimen/small_margin"
|
||||||
android:layout_toStartOf="@+id/thread_select_sim_icon"
|
|
||||||
android:layout_toEndOf="@+id/thread_add_attachment"
|
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:hint="@string/type_a_message"
|
android:hint="@string/type_a_message"
|
||||||
android:inputType="textCapSentences|textMultiLine"
|
android:inputType="textCapSentences|textMultiLine"
|
||||||
android:minHeight="@dimen/normal_icon_size" />
|
android:minHeight="@dimen/normal_icon_size"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_divider"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/thread_select_sim_icon"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/thread_add_attachment" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/thread_select_sim_icon"
|
android:id="@+id/thread_select_sim_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_marginTop="@dimen/small_margin"
|
|
||||||
android:layout_toStartOf="@+id/thread_character_counter"
|
|
||||||
android:alpha="0.9"
|
android:alpha="0.9"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:paddingStart="@dimen/medium_margin"
|
android:paddingStart="@dimen/medium_margin"
|
||||||
|
@ -242,43 +245,46 @@
|
||||||
android:paddingEnd="@dimen/medium_margin"
|
android:paddingEnd="@dimen/medium_margin"
|
||||||
android:paddingBottom="@dimen/normal_margin"
|
android:paddingBottom="@dimen/normal_margin"
|
||||||
android:src="@drawable/ic_sim_vector"
|
android:src="@drawable/ic_sim_vector"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_divider"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/thread_character_counter"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/thread_select_sim_number"
|
android:id="@+id/thread_select_sim_number"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignStart="@+id/thread_select_sim_icon"
|
|
||||||
android:layout_alignTop="@+id/thread_select_sim_icon"
|
|
||||||
android:layout_alignEnd="@+id/thread_select_sim_icon"
|
|
||||||
android:layout_alignBottom="@+id/thread_select_sim_icon"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textSize="@dimen/normal_text_size"
|
android:textSize="@dimen/normal_text_size"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:text="1" />
|
app:layout_constraintBottom_toBottomOf="@id/thread_select_sim_icon"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/thread_select_sim_icon"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/thread_select_sim_icon"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/thread_select_sim_icon"
|
||||||
|
tools:text="1"
|
||||||
|
tools:textColor="@color/dark_grey"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyTextView
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
android:id="@+id/thread_character_counter"
|
android:id="@+id/thread_character_counter"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignTop="@+id/thread_send_message"
|
|
||||||
android:layout_alignBottom="@+id/thread_send_message"
|
|
||||||
android:layout_toStartOf="@+id/thread_send_message"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingStart="@dimen/small_margin"
|
android:paddingStart="@dimen/small_margin"
|
||||||
android:paddingEnd="@dimen/small_margin"
|
android:paddingEnd="@dimen/small_margin"
|
||||||
android:text="0"
|
android:text="0"
|
||||||
android:textSize="@dimen/normal_text_size"
|
android:textSize="@dimen/normal_text_size"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:ignore="HardcodedText" />
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_divider"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/thread_send_message"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/thread_send_message"
|
||||||
|
tools:ignore="HardcodedText"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyButton
|
<com.simplemobiletools.commons.views.MyButton
|
||||||
android:id="@+id/thread_send_message"
|
android:id="@+id/thread_send_message"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
android:layout_height="@dimen/normal_icon_size"
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_marginTop="@dimen/small_margin"
|
|
||||||
android:layout_marginEnd="@dimen/small_margin"
|
android:layout_marginEnd="@dimen/small_margin"
|
||||||
android:alpha="0.4"
|
android:alpha="0.4"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
@ -287,7 +293,139 @@
|
||||||
android:drawableTop="@drawable/ic_send_vector"
|
android:drawableTop="@drawable/ic_send_vector"
|
||||||
android:paddingVertical="@dimen/small_margin"
|
android:paddingVertical="@dimen/small_margin"
|
||||||
android:text="@string/sms"
|
android:text="@string/sms"
|
||||||
android:textSize="@dimen/smaller_text_size" />
|
android:textSize="@dimen/smaller_text_size"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_divider"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
</RelativeLayout>
|
<View
|
||||||
|
android:id="@+id/attachment_picker_divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:background="@color/divider_grey"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/attachment_picker_holder" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/attachment_picker_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingVertical="@dimen/normal_margin"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/pick_from_gallery"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_image_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="@string/gallery_short"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/camera"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/camera"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_camera_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="@string/take_photo"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/record_video"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/pick_from_gallery"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/record_video"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_videocam_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="Record Video"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/record_audio"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/camera"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/record_audio"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_microphone_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="Record Audio"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/record_video"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/pick_file"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:layout_marginTop="@dimen/normal_margin"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_document_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="Files"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/pick_from_gallery"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/pick_from_gallery" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/pick_contact"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:layout_marginTop="@dimen/normal_margin"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_person_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="@string/contacts_short"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/camera"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/camera" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/schedule_message"
|
||||||
|
android:layout_width="@dimen/attachment_button_width"
|
||||||
|
android:layout_height="@dimen/attachment_button_height"
|
||||||
|
android:layout_marginTop="@dimen/normal_margin"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:drawableTop="@drawable/ic_clock_vector"
|
||||||
|
android:paddingHorizontal="@dimen/medium_margin"
|
||||||
|
android:paddingTop="@dimen/medium_margin"
|
||||||
|
android:text="@string/schedule_message"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/default_text_color"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/pick_contact"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/record_video"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/record_video" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/conversation_holder"
|
|
||||||
android:layout_width="@dimen/attachment_preview_size"
|
|
||||||
android:layout_height="@dimen/attachment_preview_size">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/thread_attachment_preview"
|
|
||||||
android:layout_width="@dimen/attachment_preview_size"
|
|
||||||
android:layout_height="@dimen/attachment_preview_size"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/thread_attachment_progress"
|
|
||||||
android:layout_width="@dimen/remove_attachment_size"
|
|
||||||
android:layout_height="@dimen/remove_attachment_size"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/thread_remove_attachment"
|
|
||||||
android:layout_width="@dimen/remove_attachment_size"
|
|
||||||
android:layout_height="@dimen/remove_attachment_size"
|
|
||||||
android:layout_alignTop="@+id/thread_attachment_preview"
|
|
||||||
android:layout_alignEnd="@+id/thread_attachment_preview"
|
|
||||||
android:padding="@dimen/tiny_margin"
|
|
||||||
android:src="@drawable/ic_cross_vector"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/document_attachment_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/section_holder_stroke"
|
||||||
|
android:foreground="@drawable/ripple_all_corners"
|
||||||
|
android:minHeight="@dimen/attachment_preview_min_height"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="@dimen/normal_margin"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_min="@dimen/attachment_preview_min_height"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="@dimen/medium_icon_size"
|
||||||
|
android:layout_height="@dimen/medium_icon_size"
|
||||||
|
android:background="@drawable/circle_background"
|
||||||
|
android:padding="@dimen/medium_margin"
|
||||||
|
app:srcCompat="@drawable/ic_document_vector" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/medium_margin"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/filename"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/attachment"
|
||||||
|
android:textSize="@dimen/normal_text_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="Event_16_02_2022.ics" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/file_size"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/normal_text_size"
|
||||||
|
tools:text="2.18 KB" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/thread_attachment_wrapper"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/item_attachment_document"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_min="@dimen/attachment_preview_min_height"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1"
|
||||||
|
app:layout_constraintWidth_max="@dimen/attachment_preview_max_width" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/item_remove_attachment_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/document_attachment_holder"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/document_attachment_holder"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/document_attachment_holder"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/document_attachment_holder" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/thread_attachment_wrapper"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:id="@+id/media_attachment_holder"
|
||||||
|
android:layout_width="@dimen/attachment_preview_size"
|
||||||
|
android:layout_height="@dimen/attachment_preview_size"
|
||||||
|
android:background="@drawable/section_holder_stroke"
|
||||||
|
android:foreground="@drawable/ripple_all_corners"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_margin="1dp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/play_icon"
|
||||||
|
android:layout_width="@dimen/remove_attachment_size"
|
||||||
|
android:layout_height="@dimen/remove_attachment_size"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:alpha="0.8"
|
||||||
|
android:src="@drawable/ic_vector_play_circle_outline"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/compression_progress"
|
||||||
|
android:layout_width="@dimen/remove_attachment_size"
|
||||||
|
android:layout_height="@dimen/remove_attachment_size"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/item_remove_attachment_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/media_attachment_holder"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/media_attachment_holder"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/media_attachment_holder"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/media_attachment_holder" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,57 +1,63 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/vcard_attachment_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/section_holder_stroke"
|
android:background="@drawable/section_holder_stroke"
|
||||||
android:orientation="vertical"
|
android:foreground="@drawable/ripple_all_corners"
|
||||||
|
android:minHeight="@dimen/attachment_preview_min_height"
|
||||||
|
android:orientation="horizontal"
|
||||||
android:padding="@dimen/normal_margin">
|
android:padding="@dimen/normal_margin">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/vcard_photo"
|
android:id="@+id/vcard_photo"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/medium_icon_size"
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
android:layout_height="@dimen/medium_icon_size"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
tools:src="@color/md_red" />
|
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/vcard_title"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="@dimen/medium_margin"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/vcard_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/normal_margin"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textSize="@dimen/bigger_text_size"
|
android:singleLine="true"
|
||||||
app:layout_constraintStart_toEndOf="@id/vcard_photo"
|
android:textSize="@dimen/normal_text_size"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:textStyle="bold"
|
||||||
tools:text="Bob" />
|
android:visibility="gone"
|
||||||
|
tools:text="Elon Reeve Musk"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/vcard_subtitle"
|
android:id="@+id/vcard_subtitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/normal_margin"
|
android:textSize="@dimen/smaller_text_size"
|
||||||
android:textSize="@dimen/normal_text_size"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/view_contact_details"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/vcard_photo"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/vcard_title"
|
|
||||||
tools:text="and 6 others"
|
tools:text="and 6 others"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/view_contact_details"
|
android:id="@+id/view_contact_details"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/normal_margin"
|
|
||||||
android:layout_marginTop="@dimen/small_margin"
|
android:layout_marginTop="@dimen/small_margin"
|
||||||
android:text="@string/view_contact_details"
|
android:text="@string/view_contact_details"
|
||||||
android:textColor="@color/color_primary"
|
android:textColor="@color/color_primary"
|
||||||
android:textSize="@dimen/smaller_text_size"
|
android:textSize="@dimen/smaller_text_size"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:visibility="gone"
|
||||||
app:layout_constraintStart_toEndOf="@id/vcard_photo"
|
tools:visibility="visible" />
|
||||||
app:layout_constraintTop_toBottomOf="@id/vcard_subtitle" />
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/thread_attachment_wrapper"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/item_attachment_vcard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_min="@dimen/attachment_preview_min_height"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1"
|
||||||
|
app:layout_constraintWidth_max="@dimen/attachment_preview_max_width" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/vcard_progress"
|
||||||
|
android:layout_width="@dimen/remove_attachment_size"
|
||||||
|
android:layout_height="@dimen/remove_attachment_size"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/vcard_attachment_holder" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/item_remove_attachment_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/vcard_attachment_holder"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/vcard_attachment_holder" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/remove_attachment_button"
|
||||||
|
android:layout_width="@dimen/remove_attachment_size"
|
||||||
|
android:layout_height="@dimen/remove_attachment_size"
|
||||||
|
android:layout_marginTop="@dimen/medium_margin"
|
||||||
|
android:layout_marginEnd="@dimen/medium_margin"
|
||||||
|
android:background="@drawable/button_background_rounded"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="@dimen/tiny_margin"
|
||||||
|
android:src="@drawable/ic_cross_vector"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/thread_received_attachment_wrapper"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/section_holder_stroke"
|
|
||||||
android:foreground="@drawable/ripple_all_corners"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="@dimen/normal_margin">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/icon"
|
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
|
||||||
android:background="@drawable/circle_background"
|
|
||||||
android:padding="@dimen/normal_margin"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/ic_document_vector" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/filename"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/normal_margin"
|
|
||||||
android:ellipsize="middle"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/attachment"
|
|
||||||
android:textSize="@dimen/bigger_text_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/file_size"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/icon"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/icon"
|
|
||||||
tools:text="Events_2022_02_16.ics" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/file_size"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/normal_margin"
|
|
||||||
android:textSize="@dimen/bigger_text_size"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/icon"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/icon"
|
|
||||||
tools:text="2.18 KB" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -3,9 +3,14 @@
|
||||||
<dimen name="notification_large_icon_size">72dp</dimen>
|
<dimen name="notification_large_icon_size">72dp</dimen>
|
||||||
<dimen name="bigger_avatar_size">64dp</dimen>
|
<dimen name="bigger_avatar_size">64dp</dimen>
|
||||||
<dimen name="play_outline_size">36dp</dimen>
|
<dimen name="play_outline_size">36dp</dimen>
|
||||||
<dimen name="attachment_preview_size">60dp</dimen>
|
<dimen name="attachment_preview_size">64dp</dimen>
|
||||||
|
<dimen name="attachment_preview_min_height">@dimen/attachment_preview_size</dimen>
|
||||||
|
<dimen name="attachment_preview_max_width">156dp</dimen>
|
||||||
<dimen name="remove_attachment_size">24dp</dimen>
|
<dimen name="remove_attachment_size">24dp</dimen>
|
||||||
<dimen name="pin_icon_size">15dp</dimen>
|
<dimen name="pin_icon_size">15dp</dimen>
|
||||||
<dimen name="vcard_property_start_margin">64dp</dimen>
|
<dimen name="vcard_property_start_margin">64dp</dimen>
|
||||||
<dimen name="small_icon_size">20dp</dimen>
|
<dimen name="small_icon_size">20dp</dimen>
|
||||||
|
<dimen name="medium_icon_size">36dp</dimen>
|
||||||
|
<dimen name="attachment_button_height">80dp</dimen>
|
||||||
|
<dimen name="attachment_button_width">90dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue