mirror of
https://github.com/SimpleMobileTools/Simple-SMS-Messenger.git
synced 2025-03-03 19:08:16 +01:00
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" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
@ -5,7 +5,6 @@ import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.net.Uri
|
||||
@ -27,21 +26,19 @@ import android.util.TypedValue
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.LinearLayout.LayoutParams
|
||||
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 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 androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
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.views.MyRecyclerView
|
||||
import com.simplemobiletools.smsmessenger.R
|
||||
import com.simplemobiletools.smsmessenger.adapters.AttachmentsAdapter
|
||||
import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter
|
||||
import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter
|
||||
import com.simplemobiletools.smsmessenger.dialogs.ScheduleMessageDialog
|
||||
import com.simplemobiletools.smsmessenger.extensions.*
|
||||
import com.simplemobiletools.smsmessenger.helpers.*
|
||||
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.item_attachment.view.*
|
||||
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
@ -72,12 +72,6 @@ import java.io.OutputStream
|
||||
|
||||
class ThreadActivity : SimpleActivity() {
|
||||
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_SEND = 15
|
||||
@ -93,8 +87,6 @@ class ThreadActivity : SimpleActivity() {
|
||||
private var privateContacts = ArrayList<SimpleContact>()
|
||||
private var messages = ArrayList<Message>()
|
||||
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 capturedImageUri: Uri? = null
|
||||
private var loadingOlderMessages = false
|
||||
@ -105,6 +97,8 @@ class ThreadActivity : SimpleActivity() {
|
||||
private var scheduledMessage: Message? = null
|
||||
private lateinit var scheduledDateTime: DateTime
|
||||
|
||||
private var isAttachmentPickerVisible = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_thread)
|
||||
@ -145,6 +139,10 @@ class ThreadActivity : SimpleActivity() {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
setupAttachmentPickerView()
|
||||
setupKeyboardListener()
|
||||
hideAttachmentPicker()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@ -161,7 +159,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
if (thread_type_message.value != "" && attachmentSelections.isEmpty()) {
|
||||
if (thread_type_message.value != "" && getAttachments().isEmpty()) {
|
||||
saveSmsDraft(thread_type_message.value, threadId)
|
||||
} else {
|
||||
deleteSmsDraft(threadId)
|
||||
@ -172,6 +170,15 @@ class ThreadActivity : SimpleActivity() {
|
||||
isActivityVisible = false
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
isAttachmentPickerVisible = false
|
||||
if (attachment_picker_holder.isVisible()) {
|
||||
hideAttachmentPicker()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
bus?.unregister(this)
|
||||
@ -214,13 +221,28 @@ class ThreadActivity : SimpleActivity() {
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, resultData)
|
||||
if (resultCode != Activity.RESULT_OK) return
|
||||
val data = resultData?.data
|
||||
|
||||
if (requestCode == TAKE_PHOTO_INTENT) {
|
||||
addAttachment(capturedImageUri!!)
|
||||
} else if (requestCode == PICK_ATTACHMENT_INTENT && resultData != null && resultData.data != null) {
|
||||
addAttachment(resultData.data!!)
|
||||
} else if (requestCode == PICK_SAVE_FILE_INTENT && resultData != null && resultData.data != null) {
|
||||
saveAttachment(resultData)
|
||||
when (requestCode) {
|
||||
CAPTURE_PHOTO_INTENT -> addAttachment(capturedImageUri!!)
|
||||
CAPTURE_VIDEO_INTENT -> if (data != null) {
|
||||
addAttachment(data)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,7 +509,14 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
thread_type_message.setText(intent.getStringExtra(THREAD_TEXT))
|
||||
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) {
|
||||
@ -780,135 +809,134 @@ class ThreadActivity : SimpleActivity() {
|
||||
return items
|
||||
}
|
||||
|
||||
private fun takeOrPickPhotoVideo() {
|
||||
val items = arrayListOf(
|
||||
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)
|
||||
private fun launchActivityForResult(intent: Intent, requestCode: Int, @StringRes error: Int = R.string.no_app_found) {
|
||||
hideKeyboard()
|
||||
try {
|
||||
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
|
||||
putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri)
|
||||
}
|
||||
startActivityForResult(intent, TAKE_PHOTO_INTENT)
|
||||
startActivityForResult(intent, requestCode)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
showErrorToast(getString(R.string.no_app_found))
|
||||
showErrorToast(getString(error))
|
||||
} catch (e: Exception) {
|
||||
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() {
|
||||
hideKeyboard()
|
||||
val mimeTypes = arrayOf("image/*", "video/*")
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "*/*"
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
|
||||
|
||||
try {
|
||||
startActivityForResult(this, PICK_ATTACHMENT_INTENT)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
showErrorToast(getString(R.string.no_app_found))
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
launchActivityForResult(this, PICK_PHOTO_VIDEO_INTENT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchPickDocumentIntent() {
|
||||
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) {
|
||||
val originalUriString = uri.toString()
|
||||
if (attachmentSelections.containsKey(originalUriString)) {
|
||||
if (getAttachments().any { it.uri.toString() == uri.toString() }) {
|
||||
return
|
||||
}
|
||||
|
||||
attachmentSelections[originalUriString] = AttachmentSelection(uri, false)
|
||||
val attachmentView = addAttachmentView(originalUriString, uri)
|
||||
val mimeType = contentResolver.getType(uri) ?: return
|
||||
|
||||
if (mimeType.isImageMimeType() && config.mmsFileSizeLimit != FILE_SIZE_NONE) {
|
||||
val selection = attachmentSelections[originalUriString]
|
||||
attachmentSelections[originalUriString] = selection!!.copy(isPending = true)
|
||||
checkSendMessageAvailability()
|
||||
attachmentView.thread_attachment_progress.beVisible()
|
||||
imageCompressor.compressImage(uri, config.mmsFileSizeLimit) { compressedUri ->
|
||||
runOnUiThread {
|
||||
if (compressedUri != null) {
|
||||
attachmentSelections[originalUriString] = AttachmentSelection(compressedUri, false)
|
||||
loadAttachmentPreview(attachmentView, compressedUri)
|
||||
} else {
|
||||
toast(R.string.compress_error)
|
||||
removeAttachment(attachmentView, originalUriString)
|
||||
}
|
||||
var adapter = getAttachmentsAdapter()
|
||||
if (adapter == null) {
|
||||
adapter = AttachmentsAdapter(
|
||||
activity = this,
|
||||
onItemClick = {},
|
||||
onAttachmentsRemoved = {
|
||||
thread_attachments_recyclerview.beGone()
|
||||
checkSendMessageAvailability()
|
||||
attachmentView.thread_attachment_progress.beGone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addAttachmentView(originalUri: String, uri: Uri): View {
|
||||
thread_attachments_holder.beVisible()
|
||||
val attachmentView = layoutInflater.inflate(R.layout.item_attachment, null).apply {
|
||||
thread_attachments_wrapper.addView(this)
|
||||
thread_remove_attachment.setOnClickListener {
|
||||
removeAttachment(this, originalUri)
|
||||
}
|
||||
},
|
||||
onReady = { checkSendMessageAvailability() }
|
||||
)
|
||||
thread_attachments_recyclerview.adapter = adapter
|
||||
}
|
||||
|
||||
loadAttachmentPreview(attachmentView, uri)
|
||||
return attachmentView
|
||||
}
|
||||
thread_attachments_recyclerview.beVisible()
|
||||
val mimeType = contentResolver.getType(uri).orEmpty()
|
||||
val attachment = AttachmentSelection(
|
||||
uri = uri,
|
||||
mimetype = mimeType,
|
||||
filename = getFilenameFromUri(uri),
|
||||
isPending = mimeType.isImageMimeType()
|
||||
)
|
||||
adapter.addAttachment(attachment)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
@ -933,7 +961,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
}
|
||||
|
||||
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.isClickable = true
|
||||
thread_send_message.alpha = 0.9f
|
||||
@ -947,7 +975,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
private fun sendMessage() {
|
||||
var text = thread_type_message.value
|
||||
if (text.isEmpty() && attachmentSelections.isEmpty()) {
|
||||
if (text.isEmpty() && getAttachments().isEmpty()) {
|
||||
showErrorToast(getString(R.string.unknown_error_occurred))
|
||||
return
|
||||
}
|
||||
@ -1002,8 +1030,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
private fun sendNormalMessage(text: String, subscriptionId: Int) {
|
||||
val addresses = participants.getAddresses()
|
||||
val attachments = attachmentSelections.values
|
||||
.map { it.uri }
|
||||
val attachments = getAttachments().map { it.uri }
|
||||
|
||||
try {
|
||||
refreshedSinceSent = false
|
||||
@ -1022,9 +1049,8 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
private fun clearCurrentMessage() {
|
||||
thread_type_message.setText("")
|
||||
attachmentSelections.clear()
|
||||
thread_attachments_holder.beGone()
|
||||
thread_attachments_wrapper.removeAllViews()
|
||||
getAttachmentsAdapter()?.clear()
|
||||
checkSendMessageAvailability()
|
||||
}
|
||||
|
||||
// show selected contacts, properly split to new lines when appropriate
|
||||
@ -1150,13 +1176,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
putExtra(Intent.EXTRA_TITLE, path.split("/").last())
|
||||
|
||||
try {
|
||||
startActivityForResult(this, PICK_SAVE_FILE_INTENT)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
showErrorToast(getString(R.string.system_service_disabled))
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
launchActivityForResult(this, PICK_SAVE_FILE_INTENT, error = R.string.system_service_disabled)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1204,7 +1224,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
private fun isMmsMessage(text: String): Boolean {
|
||||
val isGroupMms = participants.size > 1 && config.sendGroupMessageMMS
|
||||
val isLongMmsMessage = isLongMmsMessage(text) && config.sendLongMessageMMS
|
||||
return attachmentSelections.isNotEmpty() || isGroupMms || isLongMmsMessage
|
||||
return getAttachments().isNotEmpty() || isGroupMms || isLongMmsMessage
|
||||
}
|
||||
|
||||
private fun updateMessageType() {
|
||||
@ -1217,15 +1237,6 @@ class ThreadActivity : SimpleActivity() {
|
||||
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) {
|
||||
val items = arrayListOf(
|
||||
RadioItem(TYPE_EDIT, getString(R.string.update_message)),
|
||||
@ -1282,7 +1293,7 @@ class ThreadActivity : SimpleActivity() {
|
||||
|
||||
private fun setupScheduleSendUi() {
|
||||
val textColor = getProperTextColor()
|
||||
scheduled_message_holder.background.applyColorFilter(getProperBackgroundColor().getContrastColor())
|
||||
scheduled_message_holder.background.applyColorFilter(getProperPrimaryColor().darkenColor())
|
||||
scheduled_message_button.apply {
|
||||
val clockDrawable = ResourcesCompat.getDrawable(resources, R.drawable.ic_clock_vector, theme)?.apply { applyColorFilter(textColor) }
|
||||
setCompoundDrawablesWithIntrinsicBounds(clockDrawable, null, null, null)
|
||||
@ -1358,10 +1369,94 @@ class ThreadActivity : SimpleActivity() {
|
||||
}
|
||||
|
||||
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, "") }
|
||||
.toArrayList()
|
||||
|
||||
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
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
@ -38,7 +36,6 @@ import com.simplemobiletools.smsmessenger.extensions.*
|
||||
import com.simplemobiletools.smsmessenger.helpers.*
|
||||
import com.simplemobiletools.smsmessenger.models.*
|
||||
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.thread_mesage_attachments_holder
|
||||
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_sending.view.*
|
||||
import kotlinx.android.synthetic.main.item_thread_success.view.*
|
||||
import kotlinx.android.synthetic.main.item_unknown_attachment.view.*
|
||||
import java.util.*
|
||||
|
||||
class ThreadAdapter(
|
||||
activity: SimpleActivity, var messages: ArrayList<ThreadItem>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit, val onThreadIdUpdate: (Long) -> Unit
|
||||
@ -386,7 +381,7 @@ class ThreadAdapter(
|
||||
if (actModeCallback.isSelectable) {
|
||||
holder.viewClicked(message)
|
||||
} else {
|
||||
launchViewIntent(uri, mimetype, attachment.filename)
|
||||
activity.launchViewIntent(uri, mimetype, attachment.filename)
|
||||
}
|
||||
}
|
||||
imageView.setOnLongClickListener {
|
||||
@ -400,50 +395,23 @@ class ThreadAdapter(
|
||||
val uri = attachment.getUri()
|
||||
parent.apply {
|
||||
val vCardView = layoutInflater.inflate(R.layout.item_attachment_vcard, null).apply {
|
||||
background.applyColorFilter(backgroundColor.getContrastColor())
|
||||
vcard_title.setTextColor(textColor)
|
||||
vcard_subtitle.setTextColor(textColor)
|
||||
view_contact_details.setTextColor(properPrimaryColor)
|
||||
setupVCardPreview(
|
||||
activity = activity,
|
||||
uri = uri,
|
||||
onClick = {
|
||||
if (actModeCallback.isSelectable) {
|
||||
holder.viewClicked(message)
|
||||
} else {
|
||||
val intent = Intent(context, VCardViewerActivity::class.java).also {
|
||||
it.putExtra(EXTRA_VCARD_URI, uri)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
},
|
||||
onLongClick = { holder.viewLongClicked() }
|
||||
)
|
||||
}
|
||||
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) {
|
||||
holder.viewClicked(message)
|
||||
} else {
|
||||
val intent = Intent(context, VCardViewerActivity::class.java).also {
|
||||
it.putExtra(EXTRA_VCARD_URI, uri)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
setOnLongClickListener {
|
||||
holder.viewLongClicked()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,66 +419,24 @@ class ThreadAdapter(
|
||||
val mimetype = attachment.mimetype
|
||||
val uri = attachment.getUri()
|
||||
parent.apply {
|
||||
val attachmentView = layoutInflater.inflate(R.layout.item_unknown_attachment, null).apply {
|
||||
if (attachment.filename.isNotEmpty()) {
|
||||
filename.text = attachment.filename
|
||||
}
|
||||
|
||||
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) {
|
||||
holder.viewClicked(message)
|
||||
} else {
|
||||
launchViewIntent(uri, mimetype, attachment.filename)
|
||||
}
|
||||
}
|
||||
setOnLongClickListener {
|
||||
holder.viewLongClicked()
|
||||
true
|
||||
}
|
||||
val attachmentView = layoutInflater.inflate(R.layout.item_attachment_document, null).apply {
|
||||
setupDocumentPreview(
|
||||
uri = uri,
|
||||
title = attachment.filename,
|
||||
onClick = {
|
||||
if (actModeCallback.isSelectable) {
|
||||
holder.viewClicked(message)
|
||||
} else {
|
||||
activity.launchViewIntent(uri, mimetype, attachment.filename)
|
||||
}
|
||||
},
|
||||
onLongClick = { holder.viewLongClicked() },
|
||||
)
|
||||
}
|
||||
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) {
|
||||
view.apply {
|
||||
thread_date_time.apply {
|
||||
|
@ -4,10 +4,12 @@ import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import com.simplemobiletools.commons.extensions.getMimeType
|
||||
import com.simplemobiletools.commons.extensions.hideKeyboard
|
||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.smsmessenger.R
|
||||
import java.util.*
|
||||
|
||||
fun Activity.dialNumber(phoneNumber: String, callback: (() -> Unit)? = null) {
|
||||
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)
|
||||
messageAttachment.attachments.add(attachment)
|
||||
} else {
|
||||
// todo: fix filename parsing, xml is shown some sometimes
|
||||
val text = cursor.getStringValue(Mms.Part.TEXT)
|
||||
val cutName = text.substringAfter("ref src=\"").substringBefore("\"")
|
||||
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
|
||||
get() = prefs.getBoolean(WAS_DB_CLEARED, false)
|
||||
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 EXTRA_VCARD_URI = "vcard"
|
||||
const val SCHEDULED_MESSAGE_ID = "scheduled_message_id"
|
||||
const val SOFT_KEYBOARD_HEIGHT = "soft_keyboard_height"
|
||||
|
||||
private const val PATH = "com.simplemobiletools.smsmessenger.action."
|
||||
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_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
|
||||
const val LOCK_SCREEN_SENDER_MESSAGE = 1
|
||||
const val LOCK_SCREEN_SENDER = 2
|
||||
@ -60,6 +66,15 @@ const val FILE_SIZE_2_MB = 2_097_152L
|
||||
|
||||
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() {
|
||||
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
|
||||
|
||||
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(
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
app/src/main/res/drawable/ic_image_vector.xml
Normal file
10
app/src/main/res/drawable/ic_image_vector.xml
Normal file
@ -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>
|
10
app/src/main/res/drawable/ic_music_vector.xml
Normal file
10
app/src/main/res/drawable/ic_music_vector.xml
Normal file
@ -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>
|
10
app/src/main/res/drawable/ic_vector_play_circle_outline.xml
Normal file
10
app/src/main/res/drawable/ic_vector_play_circle_outline.xml
Normal file
@ -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>
|
10
app/src/main/res/drawable/ic_videocam_vector.xml
Normal file
10
app/src/main/res/drawable/ic_videocam_vector.xml
Normal file
@ -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>
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/thread_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/tiny_margin"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
@ -106,9 +107,9 @@
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/thread_messages_fastscroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/message_divider"
|
||||
android:layout_below="@+id/thread_add_contacts"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/message_divider"
|
||||
app:layout_constraintTop_toBottomOf="@id/thread_add_contacts"
|
||||
app:supportSwipeToRefresh="true">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
@ -130,43 +131,47 @@
|
||||
android:id="@+id/message_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_above="@+id/scheduled_message_holder"
|
||||
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
|
||||
android:id="@+id/thread_add_attachment"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginTop="@dimen/small_margin"
|
||||
android:layout_marginEnd="@dimen/small_margin"
|
||||
android:layout_marginStart="@dimen/small_margin"
|
||||
android:alpha="0.9"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/attachment"
|
||||
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:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/thread_attachments_holder"
|
||||
android:layout_alignStart="@id/thread_type_message"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:layout_marginEnd="@dimen/medium_margin"
|
||||
android:layout_marginBottom="@dimen/small_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="horizontal"
|
||||
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">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/scheduled_message_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_gravity="start"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:drawableStart="@drawable/ic_clock_vector"
|
||||
@ -184,57 +189,55 @@
|
||||
android:id="@+id/discard_scheduled_message"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_gravity="end"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/cancel_schedule_send"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:src="@drawable/ic_cross_vector" />
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/thread_attachments_holder"
|
||||
android:layout_width="wrap_content"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/thread_attachments_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/thread_type_message"
|
||||
android:layout_alignStart="@+id/thread_type_message"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:layout_marginTop="@dimen/tiny_margin"
|
||||
android:layout_marginBottom="@dimen/small_margin"
|
||||
android:overScrollMode="never"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/normal_margin"
|
||||
android:paddingEnd="@dimen/normal_margin"
|
||||
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:paddingEnd="@dimen/normal_margin"
|
||||
android:showDividers="middle" />
|
||||
</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
|
||||
android:id="@+id/thread_type_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginStart="@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:gravity="center_vertical"
|
||||
android:hint="@string/type_a_message"
|
||||
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
|
||||
android:id="@+id/thread_select_sim_icon"
|
||||
android:layout_width="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:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:paddingStart="@dimen/medium_margin"
|
||||
@ -242,43 +245,46 @@
|
||||
android:paddingEnd="@dimen/medium_margin"
|
||||
android:paddingBottom="@dimen/normal_margin"
|
||||
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
|
||||
android:id="@+id/thread_select_sim_number"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
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:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/normal_text_size"
|
||||
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
|
||||
android:id="@+id/thread_character_counter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignTop="@+id/thread_send_message"
|
||||
android:layout_alignBottom="@+id/thread_send_message"
|
||||
android:layout_toStartOf="@+id/thread_send_message"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingStart="@dimen/small_margin"
|
||||
android:paddingEnd="@dimen/small_margin"
|
||||
android:text="0"
|
||||
android:textSize="@dimen/normal_text_size"
|
||||
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
|
||||
android:id="@+id/thread_send_message"
|
||||
android:layout_width="@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:alpha="0.4"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
@ -287,7 +293,139 @@
|
||||
android:drawableTop="@drawable/ic_send_vector"
|
||||
android:paddingVertical="@dimen/small_margin"
|
||||
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>
|
||||
|
@ -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>
|
53
app/src/main/res/layout/item_attachment_document.xml
Normal file
53
app/src/main/res/layout/item_attachment_document.xml
Normal file
@ -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>
|
30
app/src/main/res/layout/item_attachment_document_preview.xml
Normal file
30
app/src/main/res/layout/item_attachment_document_preview.xml
Normal file
@ -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>
|
55
app/src/main/res/layout/item_attachment_media_preview.xml
Normal file
55
app/src/main/res/layout/item_attachment_media_preview.xml
Normal file
@ -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"?>
|
||||
<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: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: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">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/vcard_photo"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_width="@dimen/medium_icon_size"
|
||||
android:layout_height="@dimen/medium_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@color/md_red" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/vcard_title"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/bigger_text_size"
|
||||
app:layout_constraintStart_toEndOf="@id/vcard_photo"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Bob" />
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/medium_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/vcard_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:textSize="@dimen/normal_text_size"
|
||||
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:visibility="visible" />
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/vcard_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/normal_text_size"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:text="Elon Reeve Musk"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/view_contact_details"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:layout_marginTop="@dimen/small_margin"
|
||||
android:text="@string/view_contact_details"
|
||||
android:textColor="@color/color_primary"
|
||||
android:textSize="@dimen/smaller_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/vcard_photo"
|
||||
app:layout_constraintTop_toBottomOf="@id/vcard_subtitle" />
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/vcard_subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/smaller_text_size"
|
||||
android:visibility="gone"
|
||||
tools:text="and 6 others"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/view_contact_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/small_margin"
|
||||
android:text="@string/view_contact_details"
|
||||
android:textColor="@color/color_primary"
|
||||
android:textSize="@dimen/smaller_text_size"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
39
app/src/main/res/layout/item_attachment_vcard_preview.xml
Normal file
39
app/src/main/res/layout/item_attachment_vcard_preview.xml
Normal file
@ -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>
|
22
app/src/main/res/layout/item_remove_attachment_button.xml
Normal file
22
app/src/main/res/layout/item_remove_attachment_button.xml
Normal file
@ -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="bigger_avatar_size">64dp</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="pin_icon_size">15dp</dimen>
|
||||
<dimen name="vcard_property_start_margin">64dp</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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user