Re-implement conversation item context menu

This commit is contained in:
nielsandriesse 2021-06-07 11:37:20 +10:00
parent c0d80d68df
commit 4ecfd1f230
9 changed files with 128 additions and 32 deletions

View File

@ -1,15 +1,64 @@
package org.thoughtcrime.securesms.conversation.v2 package org.thoughtcrime.securesms.conversation.v2
import android.content.Context
import android.view.ActionMode import android.view.ActionMode
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import java.util.*
class ConversationActionModeCallback : ActionMode.Callback { class ConversationActionModeCallback(private val adapter: ConversationAdapter, private val threadID: Long,
private val context: Context) : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
// Prepare
val inflater = mode.menuInflater val inflater = mode.menuInflater
inflater.inflate(R.menu.conversation_item_action_menu, menu) inflater.inflate(R.menu.menu_conversation_item_action, menu)
val selectedItems = adapter.selectedItems
val containsControlMessage = selectedItems.any { it.isUpdate }
val hasText = selectedItems.any { it.body.isNotEmpty() }
if (selectedItems.isEmpty()) { mode.finish(); return false }
val firstMessage = selectedItems.iterator().next()
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
fun userCanDeleteSelectedItems(): Boolean {
if (openGroup == null) { return true }
val allSentByCurrentUser = selectedItems.all { it.isOutgoing }
if (allSentByCurrentUser) { return true }
return OpenGroupAPIV2.isUserModerator(userPublicKey, openGroup.room, openGroup.server)
}
fun userCanBanSelectedUsers(): Boolean {
if (openGroup == null) { return false }
val anySentByCurrentUser = selectedItems.any { it.isOutgoing }
if (anySentByCurrentUser) { return false } // Users can't ban themselves
val selectedUsers = selectedItems.map { it.recipient.address.toString() }.toSet()
if (selectedUsers.size > 1) { return false }
return OpenGroupAPIV2.isUserModerator(userPublicKey, openGroup.room, openGroup.server)
}
// Message info
menu.findItem(R.id.menu_context_details).isVisible = (selectedItems.size == 1)
// Delete message
menu.findItem(R.id.menu_context_delete_message).isVisible = userCanDeleteSelectedItems()
// Ban user
menu.findItem(R.id.menu_context_ban_user).isVisible = userCanBanSelectedUsers()
// Copy message text
menu.findItem(R.id.menu_context_copy).isVisible = !containsControlMessage && hasText
// Copy Session ID
menu.findItem(R.id.menu_context_copy_public_key).isVisible =
(openGroup != null && selectedItems.size == 1 && firstMessage.recipient.address.toString() != userPublicKey)
// Resend
menu.findItem(R.id.menu_context_resend).isVisible = (selectedItems.size == 1 && firstMessage.isFailed)
// Save media
menu.findItem(R.id.menu_context_save_attachment).isVisible = (selectedItems.size == 1
&& firstMessage.isMms && (firstMessage as MediaMmsMessageRecord).containsMediaSlide())
// Reply
menu.findItem(R.id.menu_context_reply).isVisible =
(selectedItems.size == 1 && !firstMessage.isPending && !firstMessage.isFailed)
// Return
return true return true
} }

View File

@ -1,16 +1,11 @@
package org.thoughtcrime.securesms.conversation.v2 package org.thoughtcrime.securesms.conversation.v2
import android.database.Cursor import android.database.Cursor
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.ActionMode import android.view.ActionMode
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.loader.app.LoaderManager import androidx.loader.app.LoaderManager
import androidx.loader.content.Loader import androidx.loader.content.Loader
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
@ -18,10 +13,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_conversation_v2.* import kotlinx.android.synthetic.main.activity_conversation_v2.*
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.* import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.utilities.ExpirationUtil
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.mms.GlideApp
class ConversationActivityV2 : PassphraseRequiredActionBarActivity() { class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
@ -106,7 +99,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
} }
private fun handleLongPress(messagePosition: Int) { private fun handleLongPress(messagePosition: Int) {
val actionModeCallback = ConversationActionModeCallback() val actionModeCallback = ConversationActionModeCallback(adapter, threadID, this)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
startActionMode(actionModeCallback, ActionMode.TYPE_PRIMARY) startActionMode(actionModeCallback, ActionMode.TYPE_PRIMARY)
} else { } else {

View File

@ -14,6 +14,7 @@ import java.lang.IllegalStateException
class ConversationAdapter(context: Context, cursor: Cursor, private val onItemLongPress: (Int) -> Unit) class ConversationAdapter(context: Context, cursor: Cursor, private val onItemLongPress: (Int) -> Unit)
: CursorRecyclerViewAdapter<ViewHolder>(context, cursor) { : CursorRecyclerViewAdapter<ViewHolder>(context, cursor) {
private val messageDB = DatabaseFactory.getMmsSmsDatabase(context) private val messageDB = DatabaseFactory.getMmsSmsDatabase(context)
var selectedItems = setOf<MessageRecord>()
sealed class ViewType(val rawValue: Int) { sealed class ViewType(val rawValue: Int) {
object Visible : ViewType(0) object Visible : ViewType(0)

View File

@ -55,6 +55,13 @@ object ConversationMenuHelper {
if (isOpenGroup) { if (isOpenGroup) {
inflater.inflate(R.menu.menu_conversation_open_group, menu) inflater.inflate(R.menu.menu_conversation_open_group, menu)
} }
// Muting
if (thread.isMuted) {
inflater.inflate(R.menu.menu_conversation_muted, menu)
} else {
inflater.inflate(R.menu.menu_conversation_unmuted, menu)
}
// TODO: Implement search
// Return // Return
return true return true
} }

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentView" android:id="@+id/contentView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:icon="@drawable/ic_baseline_delete_24"
android:title="Title"
app:showAsAction="ifRoom" />
<item
android:icon="@drawable/ic_baseline_delete_24"
android:title="Title"
app:showAsAction="ifRoom" />
<item
android:icon="@drawable/ic_baseline_delete_24"
android:title="Title"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
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"
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"
android:icon="?menu_save_icon"
app:showAsAction="ifRoom" />
<item
android:title="@string/conversation_context__menu_reply_to_message"
android:id="@+id/menu_context_reply"
android:icon="?menu_reply_icon"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="@string/conversation_muted__unmute"
android:id="@+id/menu_unmute_notifications" />
</menu>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="@string/conversation_unmuted__mute_notifications"
android:id="@+id/menu_mute_notifications" />
</menu>