mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 17:27:45 +00:00
Implement conversation item context menu interaction
This commit is contained in:
parent
4ecfd1f230
commit
e1345a8774
@ -14,15 +14,28 @@ import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
||||
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCallback
|
||||
import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
|
||||
class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
|
||||
private var threadID: Long = -1
|
||||
private var actionMode: ActionMode? = null
|
||||
|
||||
private val adapter by lazy {
|
||||
val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID)
|
||||
val adapter = ConversationAdapter(this, cursor) { handleLongPress(it) }
|
||||
val adapter = ConversationAdapter(
|
||||
this,
|
||||
cursor,
|
||||
onItemPress = { message, position ->
|
||||
handlePress(message, position)
|
||||
},
|
||||
onItemLongPress = { message, position ->
|
||||
handleLongPress(message, position)
|
||||
}
|
||||
)
|
||||
adapter.setHasStableIds(true)
|
||||
adapter
|
||||
}
|
||||
@ -84,7 +97,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||
return ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) }
|
||||
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) }
|
||||
// FIXME: Make the menu respect the current app theme
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
return true
|
||||
}
|
||||
// endregion
|
||||
|
||||
@ -98,13 +114,37 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
|
||||
Log.d("Loki", "Reply to message at position: $messagePosition.")
|
||||
}
|
||||
|
||||
private fun handleLongPress(messagePosition: Int) {
|
||||
private fun handlePress(message: MessageRecord, position: Int) {
|
||||
val actionMode = this.actionMode
|
||||
if (actionMode != null) {
|
||||
adapter.toggleSelection(message, position)
|
||||
val actionModeCallback = ConversationActionModeCallback(adapter, threadID, this)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
actionModeCallback.updateActionModeMenu(actionMode.menu)
|
||||
if (adapter.selectedItems.isEmpty()) {
|
||||
actionMode.finish()
|
||||
this.actionMode = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLongPress(message: MessageRecord, position: Int) {
|
||||
val actionMode = this.actionMode
|
||||
val actionModeCallback = ConversationActionModeCallback(adapter, threadID, this)
|
||||
if (actionMode == null) { // Nothing should be selected if this is the case
|
||||
adapter.toggleSelection(message, position)
|
||||
this.actionMode = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
startActionMode(actionModeCallback, ActionMode.TYPE_PRIMARY)
|
||||
} else {
|
||||
startActionMode(actionModeCallback)
|
||||
}
|
||||
} else {
|
||||
adapter.toggleSelection(message, position)
|
||||
actionModeCallback.updateActionModeMenu(actionMode.menu)
|
||||
if (adapter.selectedItems.isEmpty()) {
|
||||
actionMode.finish()
|
||||
this.actionMode = null
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
@ -2,19 +2,22 @@ package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.conversation.v2.messages.ControlMessageView
|
||||
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class ConversationAdapter(context: Context, cursor: Cursor, private val onItemLongPress: (Int) -> Unit)
|
||||
: CursorRecyclerViewAdapter<ViewHolder>(context, cursor) {
|
||||
class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPress: (MessageRecord, Int) -> Unit,
|
||||
private val onItemLongPress: (MessageRecord, Int) -> Unit) : CursorRecyclerViewAdapter<ViewHolder>(context, cursor) {
|
||||
private val messageDB = DatabaseFactory.getMmsSmsDatabase(context)
|
||||
var selectedItems = setOf<MessageRecord>()
|
||||
var selectedItems = mutableSetOf<MessageRecord>()
|
||||
|
||||
sealed class ViewType(val rawValue: Int) {
|
||||
object Visible : ViewType(0)
|
||||
@ -59,9 +62,15 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemLo
|
||||
when (viewHolder) {
|
||||
is VisibleMessageViewHolder -> {
|
||||
val view = viewHolder.view
|
||||
view.background = if (selectedItems.contains(message)) {
|
||||
ColorDrawable(context.resources.getColorWithID(R.color.red, context.theme))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
view.bind(message)
|
||||
view.setOnClickListener { onItemPress(message, viewHolder.adapterPosition) }
|
||||
view.setOnLongClickListener {
|
||||
onItemLongPress(viewHolder.adapterPosition)
|
||||
onItemLongPress(message, viewHolder.adapterPosition)
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -80,4 +89,9 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemLo
|
||||
private fun getMessage(cursor: Cursor): MessageRecord? {
|
||||
return messageDB.readerFor(cursor).current
|
||||
}
|
||||
|
||||
fun toggleSelection(message: MessageRecord, position: Int) {
|
||||
if (selectedItems.contains(message)) selectedItems.remove(message) else selectedItems.add(message)
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
package org.thoughtcrime.securesms.conversation.v2.menus
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ActionMode
|
||||
@ -7,21 +7,26 @@ import android.view.MenuItem
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.conversation.v2.ConversationAdapter
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import java.util.*
|
||||
|
||||
class ConversationActionModeCallback(private val adapter: ConversationAdapter, private val threadID: Long,
|
||||
private val context: Context) : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
// Prepare
|
||||
val inflater = mode.menuInflater
|
||||
inflater.inflate(R.menu.menu_conversation_item_action, menu)
|
||||
updateActionModeMenu(menu)
|
||||
return true
|
||||
}
|
||||
|
||||
fun updateActionModeMenu(menu: Menu) {
|
||||
// Prepare
|
||||
val selectedItems = adapter.selectedItems
|
||||
val containsControlMessage = selectedItems.any { it.isUpdate }
|
||||
val hasText = selectedItems.any { it.body.isNotEmpty() }
|
||||
if (selectedItems.isEmpty()) { mode.finish(); return false }
|
||||
if (selectedItems.isEmpty()) { return }
|
||||
val firstMessage = selectedItems.iterator().next()
|
||||
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
|
||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
||||
@ -58,8 +63,6 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p
|
||||
// Reply
|
||||
menu.findItem(R.id.menu_context_reply).isVisible =
|
||||
(selectedItems.size == 1 && !firstMessage.isPending && !firstMessage.isFailed)
|
||||
// Return
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean {
|
||||
@ -71,6 +74,7 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
|
||||
adapter.selectedItems.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
package org.thoughtcrime.securesms.conversation.v2.menus
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||
|
||||
object ConversationMenuHelper {
|
||||
|
||||
fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, context: Context, onOptionsItemSelected: (MenuItem) -> Unit): Boolean {
|
||||
fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, context: Context, onOptionsItemSelected: (MenuItem) -> Unit) {
|
||||
// Prepare
|
||||
menu.clear()
|
||||
val isOpenGroup = thread.isOpenGroupRecipient
|
||||
@ -62,7 +62,5 @@ object ConversationMenuHelper {
|
||||
inflater.inflate(R.menu.menu_conversation_unmuted, menu)
|
||||
}
|
||||
// TODO: Implement search
|
||||
// Return
|
||||
return true
|
||||
}
|
||||
}
|
@ -4,37 +4,11 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_message_details"
|
||||
android:id="@+id/menu_context_details"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_delete_message"
|
||||
android:id="@+id/menu_context_delete_message"
|
||||
android:icon="?menu_trash_icon"
|
||||
android:title="@string/conversation_context__menu_reply_to_message"
|
||||
android:id="@+id/menu_context_reply"
|
||||
android:icon="?menu_reply_icon"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_ban_user"
|
||||
android:id="@+id/menu_context_ban_user"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_copy_text"
|
||||
android:id="@+id/menu_context_copy"
|
||||
android:icon="?menu_copy_icon"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:title="@string/activity_conversation_copy_public_key_button_title"
|
||||
android:id="@+id/menu_context_copy_public_key"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_resend_message"
|
||||
android:id="@+id/menu_context_resend"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context_image__save_attachment"
|
||||
android:id="@+id/menu_context_save_attachment"
|
||||
@ -42,9 +16,35 @@
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_reply_to_message"
|
||||
android:id="@+id/menu_context_reply"
|
||||
android:icon="?menu_reply_icon"
|
||||
android:title="@string/conversation_context__menu_delete_message"
|
||||
android:id="@+id/menu_context_delete_message"
|
||||
android:icon="?menu_trash_icon"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_copy_text"
|
||||
android:id="@+id/menu_context_copy"
|
||||
android:icon="?menu_copy_icon"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_resend_message"
|
||||
android:id="@+id/menu_context_resend"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_message_details"
|
||||
android:id="@+id/menu_context_details"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/conversation_context__menu_ban_user"
|
||||
android:id="@+id/menu_context_ban_user"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/activity_conversation_copy_public_key_button_title"
|
||||
android:id="@+id/menu_context_copy_public_key"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
Loading…
x
Reference in New Issue
Block a user