290 lines
11 KiB
Kotlin
290 lines
11 KiB
Kotlin
package com.simplemobiletools.smsmessenger.activities
|
|
|
|
import android.app.PendingIntent
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import android.provider.Telephony
|
|
import android.telephony.SmsManager
|
|
import android.view.*
|
|
import android.view.inputmethod.EditorInfo
|
|
import android.widget.LinearLayout
|
|
import android.widget.RelativeLayout
|
|
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
|
import com.simplemobiletools.commons.extensions.*
|
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|
import com.simplemobiletools.smsmessenger.R
|
|
import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter
|
|
import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter
|
|
import com.simplemobiletools.smsmessenger.extensions.*
|
|
import com.simplemobiletools.smsmessenger.helpers.*
|
|
import com.simplemobiletools.smsmessenger.models.*
|
|
import com.simplemobiletools.smsmessenger.receivers.SmsSentReceiver
|
|
import kotlinx.android.synthetic.main.activity_thread.*
|
|
import kotlinx.android.synthetic.main.item_selected_contact.view.*
|
|
import org.greenrobot.eventbus.EventBus
|
|
import org.greenrobot.eventbus.Subscribe
|
|
import org.greenrobot.eventbus.ThreadMode
|
|
|
|
class ThreadActivity : SimpleActivity() {
|
|
private val MIN_DATE_TIME_DIFF_SECS = 300
|
|
|
|
private var targetNumber = ""
|
|
private var threadId = 0
|
|
private var threadItems = ArrayList<ThreadItem>()
|
|
private var bus: EventBus? = null
|
|
private var selectedContacts = ArrayList<Contact>()
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContentView(R.layout.activity_thread)
|
|
|
|
val extras = intent.extras
|
|
if (extras == null) {
|
|
toast(R.string.unknown_error_occurred)
|
|
finish()
|
|
return
|
|
}
|
|
|
|
threadId = intent.getIntExtra(THREAD_ID, 0)
|
|
var thread = getThreadInfo(threadId)
|
|
if (thread == null) {
|
|
if (extras.containsKey(THREAD_NUMBER)) {
|
|
val threadTitle = extras.getString(THREAD_NAME) ?: getString(R.string.app_launcher_name)
|
|
targetNumber = extras.getString(THREAD_NUMBER)!!
|
|
thread = MessagingThread(threadId, threadTitle, targetNumber)
|
|
} else {
|
|
toast(R.string.unknown_error_occurred)
|
|
finish()
|
|
return
|
|
}
|
|
}
|
|
|
|
title = thread.title
|
|
targetNumber = thread.address
|
|
bus = EventBus.getDefault()
|
|
bus!!.register(this)
|
|
val contact = Contact(0, thread.title, "", targetNumber, false)
|
|
selectedContacts.add(contact)
|
|
|
|
ensureBackgroundThread {
|
|
setupAdapter()
|
|
}
|
|
setupButtons()
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
super.onDestroy()
|
|
bus?.unregister(this)
|
|
}
|
|
|
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
|
menuInflater.inflate(R.menu.menu_thread, menu)
|
|
menu.apply {
|
|
findItem(R.id.manage_people).isVisible = false
|
|
findItem(R.id.delete).isVisible = threadItems.isNotEmpty()
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
when (item.itemId) {
|
|
R.id.delete -> askConfirmDelete()
|
|
R.id.manage_people -> managePeople()
|
|
else -> return super.onOptionsItemSelected(item)
|
|
}
|
|
return true
|
|
}
|
|
|
|
private fun setupAdapter() {
|
|
val threadId = intent.getIntExtra(THREAD_ID, 0)
|
|
threadItems = getThreadItems(threadId)
|
|
invalidateOptionsMenu()
|
|
|
|
runOnUiThread {
|
|
val adapter = ThreadAdapter(this, threadItems, thread_messages_list, thread_messages_fastscroller) {}
|
|
thread_messages_list.adapter = adapter
|
|
}
|
|
|
|
getAvailableContacts {
|
|
runOnUiThread {
|
|
val adapter = AutoCompleteTextViewAdapter(this, it)
|
|
new_message_to.setAdapter(adapter)
|
|
new_message_to.imeOptions = EditorInfo.IME_ACTION_NEXT
|
|
new_message_to.setOnItemClickListener { parent, view, position, id ->
|
|
val currContacts = (new_message_to.adapter as AutoCompleteTextViewAdapter).resultList
|
|
val selectedContact = currContacts[position]
|
|
addSelectedContact(selectedContact)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setupButtons() {
|
|
thread_type_message.setColors(config.textColor, config.primaryColor, config.backgroundColor)
|
|
thread_send_message.applyColorFilter(config.textColor)
|
|
|
|
thread_send_message.setOnClickListener {
|
|
val msg = thread_type_message.value
|
|
if (msg.isEmpty()) {
|
|
return@setOnClickListener
|
|
}
|
|
|
|
val intent = Intent(this, SmsSentReceiver::class.java).apply {
|
|
putExtra(MESSAGE_BODY, msg)
|
|
putExtra(MESSAGE_ADDRESS, targetNumber)
|
|
}
|
|
|
|
val pendingIntent = PendingIntent.getBroadcast(this, threadId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
val smsManager = SmsManager.getDefault()
|
|
smsManager.sendTextMessage(targetNumber, null, msg, pendingIntent, null)
|
|
thread_type_message.setText("")
|
|
}
|
|
|
|
thread_send_message.isClickable = false
|
|
thread_type_message.onTextChangeListener {
|
|
thread_send_message.isClickable = it.isNotEmpty()
|
|
thread_send_message.alpha = if (it.isEmpty()) 0.4f else 0.9f
|
|
}
|
|
|
|
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
|
thread_type_message.requestFocus()
|
|
}
|
|
|
|
private fun askConfirmDelete() {
|
|
ConfirmationDialog(this, getString(R.string.delete_whole_conversation_confirmation)) {
|
|
deleteThread(threadId)
|
|
refreshMessages()
|
|
finish()
|
|
}
|
|
}
|
|
|
|
private fun managePeople() {
|
|
if (thread_add_contacts.isVisible()) {
|
|
hideKeyboard()
|
|
thread_add_contacts.beGone()
|
|
} else {
|
|
showSelectedContacts()
|
|
thread_add_contacts.beVisible()
|
|
new_message_to.requestFocus()
|
|
showKeyboard(new_message_to)
|
|
}
|
|
}
|
|
|
|
private fun showSelectedContacts() {
|
|
val views = ArrayList<View>()
|
|
selectedContacts.forEach {
|
|
val contact = it
|
|
layoutInflater.inflate(R.layout.item_selected_contact, null).apply {
|
|
selected_contact_name.text = contact.name
|
|
selected_contact_remove.setOnClickListener {
|
|
if (contact.id != selectedContacts.first().id) {
|
|
removeSelectedContact(contact.id)
|
|
}
|
|
}
|
|
views.add(this)
|
|
}
|
|
}
|
|
showSelectedContact(views)
|
|
}
|
|
|
|
private fun addSelectedContact(contact: Contact) {
|
|
new_message_to.setText("")
|
|
if (selectedContacts.map { it.id }.contains(contact.id)) {
|
|
return
|
|
}
|
|
|
|
selectedContacts.add(contact)
|
|
showSelectedContacts()
|
|
}
|
|
|
|
private fun getThreadItems(threadID: Int): ArrayList<ThreadItem> {
|
|
val messages = getMessages(threadID)
|
|
messages.sortBy { it.id }
|
|
|
|
val items = ArrayList<ThreadItem>()
|
|
var prevDateTime = 0
|
|
var hadUnreadItems = false
|
|
messages.forEach {
|
|
// do not show the date/time above every message, only if the difference between the 2 messages is at least MIN_DATE_TIME_DIFF_SECS
|
|
if (it.date - prevDateTime > MIN_DATE_TIME_DIFF_SECS) {
|
|
items.add(ThreadDateTime(it.date))
|
|
prevDateTime = it.date
|
|
}
|
|
items.add(it)
|
|
|
|
if (it.type == Telephony.Sms.MESSAGE_TYPE_FAILED) {
|
|
items.add(ThreadError(it.id))
|
|
}
|
|
|
|
if (!it.read) {
|
|
hadUnreadItems = true
|
|
markSMSRead(it.id)
|
|
}
|
|
}
|
|
|
|
if (hadUnreadItems) {
|
|
bus?.post(Events.RefreshMessages())
|
|
}
|
|
|
|
return items
|
|
}
|
|
|
|
// show selected contacts, properly split to new lines when appropriate
|
|
// based on https://stackoverflow.com/a/13505029/1967672
|
|
private fun showSelectedContact(views: ArrayList<View>) {
|
|
selected_contacts.removeAllViews()
|
|
var newLinearLayout = LinearLayout(this)
|
|
newLinearLayout.layoutParams =
|
|
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
newLinearLayout.orientation = LinearLayout.HORIZONTAL
|
|
|
|
val sideMargin = (selected_contacts.layoutParams as RelativeLayout.LayoutParams).leftMargin
|
|
val parentWidth = realScreenSize.x - sideMargin * 2
|
|
val mediumMargin = resources.getDimension(R.dimen.medium_margin).toInt()
|
|
var widthSoFar = 0
|
|
var isFirstRow = true
|
|
for (i in views.indices) {
|
|
val LL = LinearLayout(this)
|
|
LL.orientation = LinearLayout.HORIZONTAL
|
|
LL.gravity = Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
|
|
LL.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
views[i].measure(0, 0)
|
|
|
|
var params = LinearLayout.LayoutParams(views[i].measuredWidth, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
params.setMargins(0, 0, mediumMargin, 0)
|
|
LL.addView(views[i], params)
|
|
LL.measure(0, 0)
|
|
widthSoFar += views[i].measuredWidth + mediumMargin
|
|
|
|
if (widthSoFar >= parentWidth) {
|
|
isFirstRow = false
|
|
selected_contacts.addView(newLinearLayout)
|
|
newLinearLayout = LinearLayout(this)
|
|
newLinearLayout.layoutParams =
|
|
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
newLinearLayout.orientation = LinearLayout.HORIZONTAL
|
|
params = LinearLayout.LayoutParams(LL.measuredWidth, LL.measuredHeight)
|
|
params.topMargin = mediumMargin
|
|
newLinearLayout.addView(LL, params)
|
|
widthSoFar = LL.measuredWidth
|
|
} else {
|
|
if (!isFirstRow) {
|
|
(LL.layoutParams as LinearLayout.LayoutParams).topMargin = mediumMargin
|
|
}
|
|
newLinearLayout.addView(LL)
|
|
}
|
|
}
|
|
selected_contacts.addView(newLinearLayout)
|
|
}
|
|
|
|
private fun removeSelectedContact(id: Int) {
|
|
selectedContacts = selectedContacts.filter { it.id != id }.toMutableList() as ArrayList<Contact>
|
|
showSelectedContacts()
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
fun refreshMessages(event: Events.RefreshMessages) {
|
|
setupAdapter()
|
|
}
|
|
}
|