2021-05-31 06:06:02 +02:00
|
|
|
package org.thoughtcrime.securesms.conversation.v2
|
|
|
|
|
2021-06-04 01:58:04 +02:00
|
|
|
import android.database.Cursor
|
2021-06-07 01:48:01 +02:00
|
|
|
import android.graphics.PorterDuff
|
|
|
|
import android.graphics.PorterDuffColorFilter
|
2021-05-31 06:06:02 +02:00
|
|
|
import android.os.Bundle
|
2021-06-04 05:15:43 +02:00
|
|
|
import android.util.Log
|
2021-06-04 07:10:58 +02:00
|
|
|
import android.view.ActionMode
|
|
|
|
import android.view.Menu
|
2021-06-07 01:48:01 +02:00
|
|
|
import android.view.MenuItem
|
|
|
|
import android.widget.ImageView
|
|
|
|
import android.widget.TextView
|
|
|
|
import androidx.annotation.ColorInt
|
2021-06-04 01:58:04 +02:00
|
|
|
import androidx.loader.app.LoaderManager
|
|
|
|
import androidx.loader.content.Loader
|
2021-06-04 05:15:43 +02:00
|
|
|
import androidx.recyclerview.widget.ItemTouchHelper
|
2021-05-31 06:06:02 +02:00
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
2021-05-31 06:29:11 +02:00
|
|
|
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
2021-06-04 06:55:53 +02:00
|
|
|
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
|
2021-05-31 06:06:02 +02:00
|
|
|
import network.loki.messenger.R
|
2021-06-07 01:48:01 +02:00
|
|
|
import org.session.libsession.utilities.ExpirationUtil
|
2021-05-31 06:06:02 +02:00
|
|
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
|
|
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
2021-06-07 01:48:01 +02:00
|
|
|
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
2021-06-01 08:17:14 +02:00
|
|
|
import org.thoughtcrime.securesms.mms.GlideApp
|
2021-05-31 06:06:02 +02:00
|
|
|
|
|
|
|
class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
|
|
|
|
private var threadID: Long = -1
|
|
|
|
|
2021-06-04 01:58:04 +02:00
|
|
|
private val adapter by lazy {
|
|
|
|
val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID)
|
2021-06-04 07:10:58 +02:00
|
|
|
val adapter = ConversationAdapter(this, cursor) { handleLongPress(it) }
|
2021-06-04 01:58:04 +02:00
|
|
|
adapter.setHasStableIds(true)
|
|
|
|
adapter
|
|
|
|
}
|
|
|
|
|
2021-06-01 08:17:14 +02:00
|
|
|
private val thread by lazy {
|
|
|
|
DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadID)!!
|
|
|
|
}
|
|
|
|
|
|
|
|
private val glide by lazy { GlideApp.with(this) }
|
|
|
|
|
2021-05-31 06:06:02 +02:00
|
|
|
// region Settings
|
|
|
|
companion object {
|
|
|
|
const val THREAD_ID = "thread_id"
|
|
|
|
}
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
// region Lifecycle
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
|
|
|
super.onCreate(savedInstanceState, isReady)
|
|
|
|
setContentView(R.layout.activity_conversation_v2)
|
|
|
|
threadID = intent.getLongExtra(THREAD_ID, -1)
|
|
|
|
setUpRecyclerView()
|
2021-06-01 08:17:14 +02:00
|
|
|
setUpToolbar()
|
2021-05-31 06:06:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun setUpRecyclerView() {
|
2021-05-31 06:29:11 +02:00
|
|
|
conversationRecyclerView.adapter = adapter
|
2021-06-02 05:03:22 +02:00
|
|
|
val layoutManager = LinearLayoutManager(this)
|
|
|
|
layoutManager.reverseLayout = true
|
2021-06-04 01:58:04 +02:00
|
|
|
layoutManager.stackFromEnd = true
|
2021-06-02 05:03:22 +02:00
|
|
|
conversationRecyclerView.layoutManager = layoutManager
|
2021-06-07 01:48:01 +02:00
|
|
|
// Workaround for the fact that CursorRecyclerViewAdapter doesn't auto-update automatically (even though it says it will)
|
2021-06-04 01:58:04 +02:00
|
|
|
LoaderManager.getInstance(this).restartLoader(0, null, object : LoaderManager.LoaderCallbacks<Cursor> {
|
|
|
|
|
|
|
|
override fun onCreateLoader(id: Int, bundle: Bundle?): Loader<Cursor> {
|
|
|
|
return ConversationLoader(threadID, this@ConversationActivityV2)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {
|
|
|
|
adapter.changeCursor(cursor)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoaderReset(cursor: Loader<Cursor>) {
|
|
|
|
adapter.changeCursor(null)
|
|
|
|
}
|
|
|
|
})
|
2021-06-04 05:15:43 +02:00
|
|
|
val touchHelperCallback = ConversationTouchHelperCallback(adapter, this) { reply(it) }
|
|
|
|
val touchHelper = ItemTouchHelper(touchHelperCallback)
|
|
|
|
touchHelper.attachToRecyclerView(conversationRecyclerView)
|
2021-05-31 06:06:02 +02:00
|
|
|
}
|
2021-06-01 08:17:14 +02:00
|
|
|
|
|
|
|
private fun setUpToolbar() {
|
2021-06-04 06:55:53 +02:00
|
|
|
val actionBar = supportActionBar!!
|
|
|
|
actionBar.setCustomView(R.layout.activity_conversation_v2_action_bar)
|
|
|
|
actionBar.setDisplayShowCustomEnabled(true)
|
2021-06-01 08:17:14 +02:00
|
|
|
conversationTitleView.text = thread.toShortString()
|
2021-06-02 05:28:02 +02:00
|
|
|
profilePictureView.glide = glide
|
|
|
|
profilePictureView.update(thread, threadID)
|
2021-06-01 08:17:14 +02:00
|
|
|
}
|
2021-06-07 01:48:01 +02:00
|
|
|
|
|
|
|
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
|
|
|
// Prepare
|
|
|
|
menu.clear()
|
|
|
|
val isOpenGroup = thread.isOpenGroupRecipient
|
|
|
|
// Base menu (options that should always be present)
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation, menu)
|
|
|
|
// Expiring messages
|
|
|
|
if (!isOpenGroup) {
|
|
|
|
if (thread.expireMessages > 0) {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_expiration_on, menu)
|
|
|
|
val item = menu.findItem(R.id.menu_expiring_messages)
|
|
|
|
val actionView = item.actionView
|
|
|
|
val iconView = actionView.findViewById<ImageView>(R.id.menu_badge_icon)
|
|
|
|
val badgeView = actionView.findViewById<TextView>(R.id.expiration_badge)
|
|
|
|
@ColorInt val color = resources.getColorWithID(R.color.text, theme)
|
|
|
|
iconView.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)
|
|
|
|
badgeView.text = ExpirationUtil.getExpirationAbbreviatedDisplayValue(this, thread.expireMessages)
|
|
|
|
actionView.setOnClickListener { onOptionsItemSelected(item) }
|
|
|
|
} else {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_expiration_off, menu)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// One-on-one chat menu (options that should only be present for one-on-one chats)
|
|
|
|
if (thread.isContactRecipient) {
|
|
|
|
if (thread.isBlocked) {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_unblock, menu)
|
|
|
|
} else {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_block, menu)
|
|
|
|
}
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_copy_session_id, menu)
|
|
|
|
}
|
|
|
|
// Closed group menu (options that should only be present in closed groups)
|
|
|
|
if (thread.isClosedGroupRecipient) {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_closed_group, menu)
|
|
|
|
}
|
|
|
|
// Open group menu
|
|
|
|
if (isOpenGroup) {
|
|
|
|
menuInflater.inflate(R.menu.menu_conversation_open_group, menu)
|
|
|
|
}
|
|
|
|
// Return
|
|
|
|
return true
|
|
|
|
}
|
2021-06-01 08:17:14 +02:00
|
|
|
// endregion
|
|
|
|
|
|
|
|
// region Interaction
|
2021-06-07 01:48:01 +02:00
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
2021-06-01 08:17:14 +02:00
|
|
|
// TODO: Implement
|
2021-06-07 01:48:01 +02:00
|
|
|
return super.onOptionsItemSelected(item)
|
2021-06-01 08:17:14 +02:00
|
|
|
}
|
2021-06-04 05:15:43 +02:00
|
|
|
|
|
|
|
private fun reply(messagePosition: Int) {
|
|
|
|
Log.d("Loki", "Reply to message at position: $messagePosition.")
|
|
|
|
}
|
2021-06-04 07:10:58 +02:00
|
|
|
|
|
|
|
private fun handleLongPress(messagePosition: Int) {
|
|
|
|
val actionModeCallback = ConversationActionModeCallback()
|
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
|
|
|
startActionMode(actionModeCallback, ActionMode.TYPE_PRIMARY)
|
|
|
|
} else {
|
|
|
|
startActionMode(actionModeCallback)
|
|
|
|
}
|
|
|
|
}
|
2021-05-31 06:06:02 +02:00
|
|
|
// endregion
|
|
|
|
}
|