mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-29 04:55:15 +00:00
Remove conversation settings and added back group operation
This commit is contained in:
parent
cc64f461ef
commit
841bc69c3c
@ -243,13 +243,6 @@
|
|||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value="org.thoughtcrime.securesms.home.HomeActivity" />
|
android:value="org.thoughtcrime.securesms.home.HomeActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="org.thoughtcrime.securesms.conversation.settings.ConversationSettingsActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:theme="@style/Theme.Session.DayNight.NoActionBar"/>
|
|
||||||
<activity android:name="org.thoughtcrime.securesms.conversation.settings.ConversationNotificationSettingsActivity"
|
|
||||||
android:label="@string/sessionNotifications"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:theme="@style/Theme.Session.DayNight"/>
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity"
|
android:name="org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.settings
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import network.loki.messenger.databinding.ActivityConversationNotificationSettingsBinding
|
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase
|
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class ConversationNotificationSettingsActivity: PassphraseRequiredActionBarActivity(), View.OnClickListener {
|
|
||||||
|
|
||||||
lateinit var binding: ActivityConversationNotificationSettingsBinding
|
|
||||||
@Inject lateinit var threadDb: ThreadDatabase
|
|
||||||
@Inject lateinit var recipientDb: RecipientDatabase
|
|
||||||
val recipient by lazy {
|
|
||||||
if (threadId == -1L) null
|
|
||||||
else threadDb.getRecipientForThreadId(threadId)
|
|
||||||
}
|
|
||||||
var threadId: Long = -1
|
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
|
||||||
val recipient = recipient ?: return
|
|
||||||
if (v === binding.notifyAll) {
|
|
||||||
// set notify type
|
|
||||||
recipientDb.setNotifyType(recipient, RecipientDatabase.NOTIFY_TYPE_ALL)
|
|
||||||
} else if (v === binding.notifyMentions) {
|
|
||||||
recipientDb.setNotifyType(recipient, RecipientDatabase.NOTIFY_TYPE_MENTIONS)
|
|
||||||
} else if (v === binding.notifyMute) {
|
|
||||||
recipientDb.setNotifyType(recipient, RecipientDatabase.NOTIFY_TYPE_NONE)
|
|
||||||
}
|
|
||||||
updateValues()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
|
||||||
super.onCreate(savedInstanceState, ready)
|
|
||||||
binding = ActivityConversationNotificationSettingsBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
threadId = intent.getLongExtra(ConversationActivityV2.THREAD_ID, -1L)
|
|
||||||
if (threadId == -1L) finish()
|
|
||||||
updateValues()
|
|
||||||
with (binding) {
|
|
||||||
notifyAll.setOnClickListener(this@ConversationNotificationSettingsActivity)
|
|
||||||
notifyMentions.setOnClickListener(this@ConversationNotificationSettingsActivity)
|
|
||||||
notifyMute.setOnClickListener(this@ConversationNotificationSettingsActivity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateValues() {
|
|
||||||
val notifyType = recipient?.notifyType ?: return
|
|
||||||
binding.notifyAllButton.isSelected = notifyType == RecipientDatabase.NOTIFY_TYPE_ALL
|
|
||||||
binding.notifyMentionsButton.isSelected = notifyType == RecipientDatabase.NOTIFY_TYPE_MENTIONS
|
|
||||||
binding.notifyMuteButton.isSelected = notifyType == RecipientDatabase.NOTIFY_TYPE_NONE
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.settings
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.activity.result.contract.ActivityResultContract
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
|
||||||
|
|
||||||
class ConversationNotificationSettingsActivityContract: ActivityResultContract<Long, Unit>() {
|
|
||||||
|
|
||||||
override fun createIntent(context: Context, input: Long): Intent =
|
|
||||||
Intent(context, ConversationNotificationSettingsActivity::class.java).apply {
|
|
||||||
putExtra(ConversationActivityV2.THREAD_ID, input)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun parseResult(resultCode: Int, intent: Intent?) { /* do nothing */ }
|
|
||||||
}
|
|
@ -1,269 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.settings
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import com.squareup.phrase.Phrase
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import network.loki.messenger.R
|
|
||||||
import network.loki.messenger.databinding.ActivityConversationSettingsBinding
|
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
|
||||||
import org.session.libsession.utilities.Address
|
|
||||||
import org.session.libsession.utilities.GroupUtil
|
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY
|
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
|
||||||
import org.session.libsignal.utilities.Log
|
|
||||||
import org.session.libsignal.utilities.toHexString
|
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase
|
|
||||||
import org.thoughtcrime.securesms.database.LokiThreadDatabase
|
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
|
||||||
import org.thoughtcrime.securesms.groups.EditGroupActivity
|
|
||||||
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity
|
|
||||||
import org.thoughtcrime.securesms.media.MediaOverviewActivity
|
|
||||||
import org.thoughtcrime.securesms.showSessionDialog
|
|
||||||
import java.io.IOException
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class ConversationSettingsActivity: PassphraseRequiredActionBarActivity(), View.OnClickListener {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
// used to trigger displaying conversation search in calling parent activity
|
|
||||||
const val RESULT_SEARCH = 22
|
|
||||||
}
|
|
||||||
|
|
||||||
lateinit var binding: ActivityConversationSettingsBinding
|
|
||||||
|
|
||||||
private val groupOptions: List<View>
|
|
||||||
get() = with(binding) {
|
|
||||||
listOf(
|
|
||||||
groupMembers,
|
|
||||||
groupMembersDivider.root,
|
|
||||||
editGroup,
|
|
||||||
editGroupDivider.root,
|
|
||||||
leaveGroup,
|
|
||||||
leaveGroupDivider.root
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject lateinit var threadDb: ThreadDatabase
|
|
||||||
@Inject lateinit var groupDb: GroupDatabase
|
|
||||||
@Inject lateinit var lokiThreadDb: LokiThreadDatabase
|
|
||||||
@Inject lateinit var viewModelFactory: ConversationSettingsViewModel.AssistedFactory
|
|
||||||
val viewModel: ConversationSettingsViewModel by viewModels {
|
|
||||||
val threadId = intent.getLongExtra(ConversationActivityV2.THREAD_ID, -1L)
|
|
||||||
if (threadId == -1L) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
viewModelFactory.create(threadId)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val notificationActivityCallback = registerForActivityResult(ConversationNotificationSettingsActivityContract()) {
|
|
||||||
updateRecipientDisplay()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
|
||||||
super.onCreate(savedInstanceState, ready)
|
|
||||||
binding = ActivityConversationSettingsBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
updateRecipientDisplay()
|
|
||||||
binding.searchConversation.setOnClickListener(this)
|
|
||||||
binding.clearMessages.setOnClickListener(this)
|
|
||||||
binding.allMedia.setOnClickListener(this)
|
|
||||||
binding.pinConversation.setOnClickListener(this)
|
|
||||||
binding.notificationSettings.setOnClickListener(this)
|
|
||||||
binding.editGroup.setOnClickListener(this)
|
|
||||||
binding.leaveGroup.setOnClickListener(this)
|
|
||||||
binding.back.setOnClickListener(this)
|
|
||||||
binding.autoDownloadMediaSwitch.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
viewModel.setAutoDownloadAttachments(isChecked)
|
|
||||||
updateRecipientDisplay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateRecipientDisplay() {
|
|
||||||
val recipient = viewModel.recipient ?: return
|
|
||||||
// Setup profile image
|
|
||||||
binding.profilePictureView.root.update(recipient)
|
|
||||||
// Setup name
|
|
||||||
binding.conversationName.text = when {
|
|
||||||
recipient.isLocalNumber -> getString(R.string.noteToSelf)
|
|
||||||
else -> recipient.toShortString()
|
|
||||||
}
|
|
||||||
// Setup group description (if group)
|
|
||||||
binding.conversationSubtitle.isVisible = recipient.isClosedGroupV2Recipient.apply {
|
|
||||||
binding.conversationSubtitle.text = viewModel.closedGroupInfo()?.description
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle group-specific settings
|
|
||||||
val areGroupOptionsVisible = recipient.isClosedGroupV2Recipient || recipient.isLegacyClosedGroupRecipient
|
|
||||||
groupOptions.forEach { v ->
|
|
||||||
v.isVisible = areGroupOptionsVisible
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group admin settings
|
|
||||||
val isUserGroupAdmin = areGroupOptionsVisible && viewModel.isUserGroupAdmin()
|
|
||||||
with (binding) {
|
|
||||||
groupMembersDivider.root.isVisible = areGroupOptionsVisible && !isUserGroupAdmin
|
|
||||||
groupMembers.isVisible = !isUserGroupAdmin
|
|
||||||
adminControlsGroup.isVisible = isUserGroupAdmin
|
|
||||||
deleteGroup.isVisible = isUserGroupAdmin
|
|
||||||
clearMessages.isVisible = isUserGroupAdmin
|
|
||||||
clearMessagesDivider.root.isVisible = isUserGroupAdmin
|
|
||||||
leaveGroupDivider.root.isVisible = isUserGroupAdmin
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set pinned state
|
|
||||||
binding.pinConversation.setText(
|
|
||||||
if (viewModel.isPinned()) R.string.pinUnpinConversation
|
|
||||||
else R.string.pinConversation
|
|
||||||
)
|
|
||||||
|
|
||||||
// Set auto-download state
|
|
||||||
val trusted = viewModel.autoDownloadAttachments()
|
|
||||||
binding.autoDownloadMediaSwitch.isChecked = trusted
|
|
||||||
|
|
||||||
// Set notification type
|
|
||||||
val notifyTypes = resources.getStringArray(R.array.notify_types)
|
|
||||||
val summary = notifyTypes.getOrNull(recipient.notifyType)
|
|
||||||
binding.notificationsValue.text = summary
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
|
||||||
val threadRecipient = viewModel.recipient ?: return
|
|
||||||
when {
|
|
||||||
v === binding.searchConversation -> {
|
|
||||||
setResult(RESULT_SEARCH)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
v === binding.allMedia -> {
|
|
||||||
startActivity(MediaOverviewActivity.createIntent(this, threadRecipient.address))
|
|
||||||
}
|
|
||||||
v === binding.pinConversation -> {
|
|
||||||
viewModel.togglePin().invokeOnCompletion { e ->
|
|
||||||
if (e != null) {
|
|
||||||
// something happened
|
|
||||||
Log.e("ConversationSettings", "Failed to toggle pin on thread", e)
|
|
||||||
} else {
|
|
||||||
updateRecipientDisplay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v === binding.notificationSettings -> {
|
|
||||||
notificationActivityCallback.launch(viewModel.threadId)
|
|
||||||
}
|
|
||||||
v === binding.back -> onBackPressed()
|
|
||||||
v === binding.clearMessages -> {
|
|
||||||
|
|
||||||
showSessionDialog {
|
|
||||||
title(R.string.clearMessages)
|
|
||||||
text(Phrase.from(this@ConversationSettingsActivity, R.string.clearMessagesChatDescription)
|
|
||||||
.put(NAME_KEY, threadRecipient.name)
|
|
||||||
.format())
|
|
||||||
dangerButton(
|
|
||||||
R.string.clear,
|
|
||||||
R.string.clear) {
|
|
||||||
viewModel.clearMessages(false)
|
|
||||||
}
|
|
||||||
cancelButton()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v === binding.leaveGroup -> {
|
|
||||||
|
|
||||||
if (threadRecipient.isLegacyClosedGroupRecipient) {
|
|
||||||
// Send a leave group message if this is an active closed group
|
|
||||||
val groupString = threadRecipient.address.toGroupString()
|
|
||||||
val ourId = TextSecurePreferences.getLocalNumber(this)!!
|
|
||||||
if (groupDb.isActive(groupString)) {
|
|
||||||
showSessionDialog {
|
|
||||||
|
|
||||||
title(R.string.groupLeave)
|
|
||||||
|
|
||||||
val name = viewModel.recipient!!.name!!
|
|
||||||
val textWithArgs = if (groupDb.getGroup(groupString).get().admins.map(Address::serialize).contains(ourId)) {
|
|
||||||
Phrase.from(context, R.string.groupLeaveDescriptionAdmin)
|
|
||||||
.put(GROUP_NAME_KEY, name)
|
|
||||||
.format()
|
|
||||||
} else {
|
|
||||||
Phrase.from(context, R.string.groupLeaveDescription)
|
|
||||||
.put(GROUP_NAME_KEY, name)
|
|
||||||
.format()
|
|
||||||
}
|
|
||||||
text(textWithArgs)
|
|
||||||
dangerButton(
|
|
||||||
R.string.groupLeave,
|
|
||||||
R.string.groupLeave
|
|
||||||
) {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
GroupUtil.doubleDecodeGroupID(threadRecipient.address.toString())
|
|
||||||
.toHexString()
|
|
||||||
.let { MessageSender.explicitLeave(it, true, deleteThread = true) }
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cancelButton()
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.e("Loki", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (threadRecipient.isClosedGroupV2Recipient) {
|
|
||||||
val groupInfo = viewModel.closedGroupInfo()
|
|
||||||
showSessionDialog {
|
|
||||||
|
|
||||||
title(R.string.groupLeave)
|
|
||||||
|
|
||||||
val name = viewModel.recipient!!.name!!
|
|
||||||
val textWithArgs = if (groupInfo?.isUserAdmin == true) {
|
|
||||||
Phrase.from(context, R.string.groupLeaveDescription)
|
|
||||||
.put(GROUP_NAME_KEY, name)
|
|
||||||
.format()
|
|
||||||
} else {
|
|
||||||
Phrase.from(context, R.string.groupLeaveDescription)
|
|
||||||
.put(GROUP_NAME_KEY, name)
|
|
||||||
.format()
|
|
||||||
}
|
|
||||||
text(textWithArgs)
|
|
||||||
dangerButton(
|
|
||||||
R.string.groupLeave,
|
|
||||||
R.string.groupLeave
|
|
||||||
) {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
viewModel.leaveGroup()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cancelButton()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v === binding.editGroup -> {
|
|
||||||
val recipient = viewModel.recipient ?: return
|
|
||||||
|
|
||||||
val intent = when {
|
|
||||||
recipient.isLegacyClosedGroupRecipient -> Intent(this, EditLegacyGroupActivity::class.java).apply {
|
|
||||||
val groupID: String = recipient.address.toGroupString()
|
|
||||||
putExtra(EditLegacyGroupActivity.groupIDKey, groupID)
|
|
||||||
}
|
|
||||||
|
|
||||||
recipient.isClosedGroupV2Recipient -> EditGroupActivity.createIntent(
|
|
||||||
context = this,
|
|
||||||
groupSessionId = recipient.address.serialize()
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> return
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.settings
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.activity.result.contract.ActivityResultContract
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
|
||||||
|
|
||||||
sealed class ConversationSettingsActivityResult {
|
|
||||||
object Finished: ConversationSettingsActivityResult()
|
|
||||||
object SearchConversation: ConversationSettingsActivityResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConversationSettingsActivityContract: ActivityResultContract<Long, ConversationSettingsActivityResult>() {
|
|
||||||
|
|
||||||
override fun createIntent(context: Context, input: Long) = Intent(context, ConversationSettingsActivity::class.java).apply {
|
|
||||||
putExtra(ConversationActivityV2.THREAD_ID, input ?: -1L)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun parseResult(resultCode: Int, intent: Intent?): ConversationSettingsActivityResult =
|
|
||||||
when (resultCode) {
|
|
||||||
ConversationSettingsActivity.RESULT_SEARCH -> ConversationSettingsActivityResult.SearchConversation
|
|
||||||
else -> ConversationSettingsActivityResult.Finished
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.settings
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import dagger.assisted.Assisted
|
|
||||||
import dagger.assisted.AssistedInject
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import network.loki.messenger.libsession_util.util.GroupDisplayInfo
|
|
||||||
import org.session.libsession.database.StorageProtocol
|
|
||||||
import org.session.libsession.messaging.jobs.JobQueue
|
|
||||||
import org.session.libsession.messaging.jobs.LibSessionGroupLeavingJob
|
|
||||||
import org.session.libsession.utilities.Address
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
|
||||||
import org.session.libsignal.utilities.AccountId
|
|
||||||
|
|
||||||
class ConversationSettingsViewModel(
|
|
||||||
val threadId: Long,
|
|
||||||
private val storage: StorageProtocol,
|
|
||||||
private val prefs: TextSecurePreferences
|
|
||||||
): ViewModel() {
|
|
||||||
|
|
||||||
val recipient get() = storage.getRecipientForThread(threadId)
|
|
||||||
|
|
||||||
fun isPinned() = storage.isPinned(threadId)
|
|
||||||
|
|
||||||
fun togglePin() = viewModelScope.launch {
|
|
||||||
val isPinned = storage.isPinned(threadId)
|
|
||||||
storage.setPinned(threadId, !isPinned)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun autoDownloadAttachments() = recipient?.let { recipient -> storage.shouldAutoDownloadAttachments(recipient) } ?: false
|
|
||||||
|
|
||||||
fun setAutoDownloadAttachments(shouldDownload: Boolean) {
|
|
||||||
recipient?.let { recipient -> storage.setAutoDownloadAttachments(recipient, shouldDownload) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isUserGroupAdmin(): Boolean = recipient?.let { recipient ->
|
|
||||||
when {
|
|
||||||
recipient.isLegacyClosedGroupRecipient -> {
|
|
||||||
val localUserAddress = prefs.getLocalNumber() ?: return@let false
|
|
||||||
val group = storage.getGroup(recipient.address.toGroupString())
|
|
||||||
group?.admins?.contains(Address.fromSerialized(localUserAddress)) ?: false // this will have to be replaced for new closed groups
|
|
||||||
}
|
|
||||||
recipient.isClosedGroupV2Recipient -> {
|
|
||||||
val group = storage.getLibSessionClosedGroup(recipient.address.serialize()) ?: return@let false
|
|
||||||
group.adminKey != null
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
} ?: false
|
|
||||||
|
|
||||||
fun clearMessages(forAll: Boolean) {
|
|
||||||
if (forAll && !isUserGroupAdmin()) return
|
|
||||||
|
|
||||||
if (!forAll) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
storage.clearMessages(threadId)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// do a send message here and on success do a clear messages
|
|
||||||
viewModelScope.launch {
|
|
||||||
storage.clearMessages(threadId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun closedGroupInfo(): GroupDisplayInfo? = recipient
|
|
||||||
?.address
|
|
||||||
?.takeIf { it.isClosedGroupV2 }
|
|
||||||
?.serialize()
|
|
||||||
?.let(storage::getClosedGroupDisplayInfo)
|
|
||||||
|
|
||||||
// Assume that user has verified they don't want to add a new admin etc
|
|
||||||
suspend fun leaveGroup() {
|
|
||||||
val recipient = recipient ?: return
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
val groupLeave = LibSessionGroupLeavingJob(
|
|
||||||
AccountId(recipient.address.serialize()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
JobQueue.shared.add(groupLeave)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DI-related
|
|
||||||
@dagger.assisted.AssistedFactory
|
|
||||||
interface AssistedFactory {
|
|
||||||
fun create(threadId: Long): Factory
|
|
||||||
}
|
|
||||||
class Factory @AssistedInject constructor(
|
|
||||||
@Assisted private val threadId: Long,
|
|
||||||
private val storage: StorageProtocol,
|
|
||||||
private val prefs: TextSecurePreferences
|
|
||||||
) : ViewModelProvider.Factory {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
|
||||||
return ConversationSettingsViewModel(threadId, storage, prefs) as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -119,8 +119,6 @@ import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel
|
|||||||
import org.thoughtcrime.securesms.contacts.SelectContactsActivity.Companion.selectedContactsKey
|
import org.thoughtcrime.securesms.contacts.SelectContactsActivity.Companion.selectedContactsKey
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationActionBarDelegate
|
import org.thoughtcrime.securesms.conversation.ConversationActionBarDelegate
|
||||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.DisappearingMessagesActivity
|
import org.thoughtcrime.securesms.conversation.disappearingmessages.DisappearingMessagesActivity
|
||||||
import org.thoughtcrime.securesms.conversation.settings.ConversationSettingsActivityContract
|
|
||||||
import org.thoughtcrime.securesms.conversation.settings.ConversationSettingsActivityResult
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnActionSelectedListener
|
import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnActionSelectedListener
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnReactionSelectedListener
|
import org.thoughtcrime.securesms.conversation.v2.ConversationReactionOverlay.OnReactionSelectedListener
|
||||||
import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.MESSAGE_TIMESTAMP
|
import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.MESSAGE_TIMESTAMP
|
||||||
@ -164,6 +162,7 @@ import org.thoughtcrime.securesms.database.model.MessageId
|
|||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity
|
import org.thoughtcrime.securesms.giph.ui.GiphyActivity
|
||||||
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
||||||
import org.thoughtcrime.securesms.home.search.getSearchName
|
import org.thoughtcrime.securesms.home.search.getSearchName
|
||||||
@ -222,7 +221,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
ConversationActionModeCallbackDelegate, VisibleMessageViewDelegate, RecipientModifiedListener,
|
ConversationActionModeCallbackDelegate, VisibleMessageViewDelegate, RecipientModifiedListener,
|
||||||
SearchBottomBar.EventListener, LoaderManager.LoaderCallbacks<Cursor>, ConversationActionBarDelegate,
|
SearchBottomBar.EventListener, LoaderManager.LoaderCallbacks<Cursor>, ConversationActionBarDelegate,
|
||||||
OnReactionSelectedListener, ReactWithAnyEmojiDialogFragment.Callback, ReactionsDialogFragment.Callback,
|
OnReactionSelectedListener, ReactWithAnyEmojiDialogFragment.Callback, ReactionsDialogFragment.Callback,
|
||||||
ConversationMenuHelper.ConversationMenuListener, View.OnClickListener {
|
ConversationMenuHelper.ConversationMenuListener {
|
||||||
|
|
||||||
private lateinit var binding: ActivityConversationV2Binding
|
private lateinit var binding: ActivityConversationV2Binding
|
||||||
|
|
||||||
@ -239,6 +238,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
@Inject lateinit var reactionDb: ReactionDatabase
|
@Inject lateinit var reactionDb: ReactionDatabase
|
||||||
@Inject lateinit var viewModelFactory: ConversationViewModel.AssistedFactory
|
@Inject lateinit var viewModelFactory: ConversationViewModel.AssistedFactory
|
||||||
@Inject lateinit var mentionViewModelFactory: MentionViewModel.AssistedFactory
|
@Inject lateinit var mentionViewModelFactory: MentionViewModel.AssistedFactory
|
||||||
|
@Inject lateinit var configFactory: ConfigFactory
|
||||||
|
|
||||||
private val screenshotObserver by lazy {
|
private val screenshotObserver by lazy {
|
||||||
ScreenshotObserver(this, Handler(Looper.getMainLooper())) {
|
ScreenshotObserver(this, Handler(Looper.getMainLooper())) {
|
||||||
@ -247,13 +247,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val conversationSettingsCallback = registerForActivityResult(ConversationSettingsActivityContract()) { result ->
|
|
||||||
if (result is ConversationSettingsActivityResult.SearchConversation) {
|
|
||||||
// open search
|
|
||||||
binding?.toolbar?.menu?.findItem(R.id.menu_search)?.expandActionView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
private val linkPreviewViewModel: LinkPreviewViewModel by lazy {
|
private val linkPreviewViewModel: LinkPreviewViewModel by lazy {
|
||||||
ViewModelProvider(this, LinkPreviewViewModel.Factory(LinkPreviewRepository()))
|
ViewModelProvider(this, LinkPreviewViewModel.Factory(LinkPreviewRepository()))
|
||||||
@ -497,7 +490,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
updatePlaceholder()
|
updatePlaceholder()
|
||||||
setUpBlockedBanner()
|
setUpBlockedBanner()
|
||||||
binding.searchBottomBar.setEventListener(this)
|
binding.searchBottomBar.setEventListener(this)
|
||||||
binding.toolbarContent.profilePictureView.setOnClickListener(this)
|
|
||||||
updateSendAfterApprovalText()
|
updateSendAfterApprovalText()
|
||||||
setUpMessageRequests()
|
setUpMessageRequests()
|
||||||
|
|
||||||
@ -949,10 +941,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
val recipient = viewModel.recipient ?: return false
|
val recipient = viewModel.recipient ?: return false
|
||||||
if (!viewModel.isMessageRequestThread) {
|
if (!viewModel.isMessageRequestThread) {
|
||||||
ConversationMenuHelper.onPrepareOptionsMenu(
|
ConversationMenuHelper.onPrepareOptionsMenu(
|
||||||
menu,
|
menu = menu,
|
||||||
menuInflater,
|
inflater = menuInflater,
|
||||||
recipient,
|
thread = recipient,
|
||||||
this
|
context = this,
|
||||||
|
configFactory = configFactory,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
maybeUpdateToolbar(recipient)
|
maybeUpdateToolbar(recipient)
|
||||||
@ -1219,17 +1212,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return viewModel.recipient?.let { recipient ->
|
return viewModel.recipient?.let { recipient ->
|
||||||
ConversationMenuHelper.onOptionItemSelected(this, item, recipient)
|
ConversationMenuHelper.onOptionItemSelected(this, item, recipient, configFactory, storage)
|
||||||
} ?: false
|
} ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
|
||||||
if (v === binding?.toolbarContent?.profilePictureView) {
|
|
||||||
// open conversation settings
|
|
||||||
conversationSettingsCallback.launch(viewModel.threadId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun block(deleteThread: Boolean) {
|
override fun block(deleteThread: Boolean) {
|
||||||
val recipient = viewModel.recipient ?: return Log.w("Loki", "Recipient was null for block action")
|
val recipient = viewModel.recipient ?: return Log.w("Loki", "Recipient was null for block action")
|
||||||
val invitingAdmin = viewModel.invitingAdmin
|
val invitingAdmin = viewModel.invitingAdmin
|
||||||
|
@ -5,7 +5,6 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
@ -21,13 +20,14 @@ import androidx.core.graphics.drawable.IconCompat
|
|||||||
import com.squareup.phrase.Phrase
|
import com.squareup.phrase.Phrase
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import org.session.libsession.database.StorageProtocol
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||||
import org.session.libsession.messaging.sending_receiving.leave
|
import org.session.libsession.messaging.sending_receiving.leave
|
||||||
import org.session.libsession.utilities.GroupUtil.doubleDecodeGroupID
|
import org.session.libsession.utilities.GroupUtil.doubleDecodeGroupID
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
|
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY
|
import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
|
import org.session.libsignal.utilities.AccountId
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import org.session.libsignal.utilities.guava.Optional
|
import org.session.libsignal.utilities.guava.Optional
|
||||||
import org.session.libsignal.utilities.toHexString
|
import org.session.libsignal.utilities.toHexString
|
||||||
@ -38,6 +38,8 @@ import org.thoughtcrime.securesms.calls.WebRtcCallActivity
|
|||||||
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
|
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils
|
import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils
|
||||||
|
import org.thoughtcrime.securesms.database.Storage
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity
|
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity
|
||||||
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity.Companion.groupIDKey
|
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity.Companion.groupIDKey
|
||||||
@ -54,7 +56,8 @@ object ConversationMenuHelper {
|
|||||||
menu: Menu,
|
menu: Menu,
|
||||||
inflater: MenuInflater,
|
inflater: MenuInflater,
|
||||||
thread: Recipient,
|
thread: Recipient,
|
||||||
context: Context
|
context: Context,
|
||||||
|
configFactory: ConfigFactory,
|
||||||
) {
|
) {
|
||||||
// Prepare
|
// Prepare
|
||||||
menu.clear()
|
menu.clear()
|
||||||
@ -77,10 +80,20 @@ object ConversationMenuHelper {
|
|||||||
inflater.inflate(R.menu.menu_conversation_block, menu)
|
inflater.inflate(R.menu.menu_conversation_block, menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Closed group menu (options that should only be present in closed groups)
|
// (Legacy) Closed group menu (options that should only be present in closed groups)
|
||||||
if (thread.isLegacyClosedGroupRecipient) {
|
if (thread.isLegacyClosedGroupRecipient) {
|
||||||
inflater.inflate(R.menu.menu_conversation_closed_group, menu)
|
inflater.inflate(R.menu.menu_conversation_legacy_group, menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Groups v2 menu
|
||||||
|
if (thread.isClosedGroupV2Recipient) {
|
||||||
|
if (configFactory.userGroups?.getClosedGroup(thread.address.serialize())?.hasAdminKey() == true) {
|
||||||
|
inflater.inflate(R.menu.menu_conversation_groups_v2_admin, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
inflater.inflate(R.menu.menu_conversation_groups_v2, menu)
|
||||||
|
}
|
||||||
|
|
||||||
// Open group menu
|
// Open group menu
|
||||||
if (isCommunity) {
|
if (isCommunity) {
|
||||||
inflater.inflate(R.menu.menu_conversation_open_group, menu)
|
inflater.inflate(R.menu.menu_conversation_open_group, menu)
|
||||||
@ -134,7 +147,13 @@ object ConversationMenuHelper {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onOptionItemSelected(context: Context, item: MenuItem, thread: Recipient): Boolean {
|
fun onOptionItemSelected(
|
||||||
|
context: Context,
|
||||||
|
item: MenuItem,
|
||||||
|
thread: Recipient,
|
||||||
|
factory: ConfigFactory,
|
||||||
|
storage: StorageProtocol
|
||||||
|
): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_view_all_media -> { showAllMedia(context, thread) }
|
R.id.menu_view_all_media -> { showAllMedia(context, thread) }
|
||||||
R.id.menu_search -> { search(context) }
|
R.id.menu_search -> { search(context) }
|
||||||
@ -146,7 +165,7 @@ object ConversationMenuHelper {
|
|||||||
R.id.menu_copy_account_id -> { copyAccountID(context, thread) }
|
R.id.menu_copy_account_id -> { copyAccountID(context, thread) }
|
||||||
R.id.menu_copy_open_group_url -> { copyOpenGroupUrl(context, thread) }
|
R.id.menu_copy_open_group_url -> { copyOpenGroupUrl(context, thread) }
|
||||||
R.id.menu_edit_group -> { editClosedGroup(context, thread) }
|
R.id.menu_edit_group -> { editClosedGroup(context, thread) }
|
||||||
R.id.menu_leave_group -> { leaveClosedGroup(context, thread) }
|
R.id.menu_leave_group -> { leaveClosedGroup(context, thread, factory, storage) }
|
||||||
R.id.menu_invite_to_open_group -> { inviteContacts(context, thread) }
|
R.id.menu_invite_to_open_group -> { inviteContacts(context, thread) }
|
||||||
R.id.menu_unmute_notifications -> { unmute(context, thread) }
|
R.id.menu_unmute_notifications -> { unmute(context, thread) }
|
||||||
R.id.menu_mute_notifications -> { mute(context, thread) }
|
R.id.menu_mute_notifications -> { mute(context, thread) }
|
||||||
@ -278,26 +297,67 @@ object ConversationMenuHelper {
|
|||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun leaveClosedGroup(context: Context, thread: Recipient) {
|
private fun leaveClosedGroup(
|
||||||
if (!thread.isLegacyClosedGroupRecipient) { return }
|
context: Context,
|
||||||
|
thread: Recipient,
|
||||||
|
configFactory: ConfigFactory,
|
||||||
|
storage: StorageProtocol
|
||||||
|
) {
|
||||||
|
when {
|
||||||
|
thread.isLegacyClosedGroupRecipient -> {
|
||||||
val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull()
|
val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull()
|
||||||
val admins = group.admins
|
val admins = group.admins
|
||||||
val accountID = TextSecurePreferences.getLocalNumber(context)
|
val accountID = TextSecurePreferences.getLocalNumber(context)
|
||||||
val isCurrentUserAdmin = admins.any { it.toString() == accountID }
|
val isCurrentUserAdmin = admins.any { it.toString() == accountID }
|
||||||
val message = if (isCurrentUserAdmin) {
|
|
||||||
|
confirmAndLeaveClosedGroup(context, group.title, isCurrentUserAdmin, doLeave = {
|
||||||
|
val groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString()
|
||||||
|
|
||||||
|
check(DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)) {
|
||||||
|
"Invalid group public key"
|
||||||
|
}
|
||||||
|
MessageSender.leave(groupPublicKey, notifyUser = false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
thread.isClosedGroupV2Recipient -> {
|
||||||
|
val accountId = AccountId(thread.address.serialize())
|
||||||
|
val group = configFactory.userGroups?.getClosedGroup(accountId.hexString) ?: return
|
||||||
|
val (name, isAdmin) = configFactory.getGroupInfoConfig(accountId)?.use {
|
||||||
|
it.getName() to group.hasAdminKey()
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
confirmAndLeaveClosedGroup(
|
||||||
|
context = context,
|
||||||
|
groupName = name,
|
||||||
|
isAdmin = isAdmin,
|
||||||
|
doLeave = {
|
||||||
|
check(storage.leaveGroup(accountId.hexString, true))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun confirmAndLeaveClosedGroup(
|
||||||
|
context: Context,
|
||||||
|
groupName: String,
|
||||||
|
isAdmin: Boolean,
|
||||||
|
doLeave: () -> Unit,
|
||||||
|
) {
|
||||||
|
val message = if (isAdmin) {
|
||||||
Phrase.from(context, R.string.groupDeleteDescription)
|
Phrase.from(context, R.string.groupDeleteDescription)
|
||||||
.put(GROUP_NAME_KEY, group.title)
|
.put(GROUP_NAME_KEY, groupName)
|
||||||
.format()
|
.format()
|
||||||
} else {
|
} else {
|
||||||
Phrase.from(context, R.string.groupLeaveDescription)
|
Phrase.from(context, R.string.groupLeaveDescription)
|
||||||
.put(GROUP_NAME_KEY, group.title)
|
.put(GROUP_NAME_KEY, groupName)
|
||||||
.format()
|
.format()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onLeaveFailed() {
|
fun onLeaveFailed() {
|
||||||
val txt = Phrase.from(context, R.string.groupLeaveErrorFailed)
|
val txt = Phrase.from(context, R.string.groupLeaveErrorFailed)
|
||||||
.put(GROUP_NAME_KEY, group.title)
|
.put(GROUP_NAME_KEY, groupName)
|
||||||
.format().toString()
|
.format().toString()
|
||||||
Toast.makeText(context, txt, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, txt, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
@ -307,11 +367,7 @@ object ConversationMenuHelper {
|
|||||||
text(message)
|
text(message)
|
||||||
dangerButton(R.string.leave) {
|
dangerButton(R.string.leave) {
|
||||||
try {
|
try {
|
||||||
val groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString()
|
doLeave()
|
||||||
val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)
|
|
||||||
|
|
||||||
if (isClosedGroup) MessageSender.leave(groupPublicKey, notifyUser = false)
|
|
||||||
else onLeaveFailed()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
onLeaveFailed()
|
onLeaveFailed()
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:background="@drawable/preference_top"
|
|
||||||
android:paddingTop="@dimen/small_spacing"
|
|
||||||
android:id="@+id/notifyAll"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:text="@string/notificationsAllMessages"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="72dp"/>
|
|
||||||
<View
|
|
||||||
android:layout_marginTop="@dimen/small_spacing"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/notifyAll"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/notifyAll"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/notifyAll"
|
|
||||||
android:layout_marginEnd="54dp"
|
|
||||||
android:id="@+id/notifyAllButton"
|
|
||||||
android:padding="@dimen/small_spacing"
|
|
||||||
android:layout_width="@dimen/small_radial_size"
|
|
||||||
android:layout_height="@dimen/small_radial_size"
|
|
||||||
android:background="@drawable/padded_circle_accent_select"
|
|
||||||
android:foreground="@drawable/radial_multi_select"/>
|
|
||||||
<TextView
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/notifyAll"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:id="@+id/notifyMentions"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:background="@drawable/preference_middle"
|
|
||||||
android:text="@string/notificationsMentionsOnly"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<View
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/notifyMentions"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/notifyMentions"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/notifyMentions"
|
|
||||||
android:layout_marginEnd="54dp"
|
|
||||||
android:id="@+id/notifyMentionsButton"
|
|
||||||
android:layout_width="@dimen/small_radial_size"
|
|
||||||
android:layout_height="@dimen/small_radial_size"
|
|
||||||
android:background="@drawable/padded_circle_accent_select"
|
|
||||||
android:foreground="@drawable/radial_multi_select"/>
|
|
||||||
<TextView
|
|
||||||
android:paddingBottom="@dimen/small_spacing"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/notifyMentions"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:id="@+id/notifyMute"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:background="@drawable/preference_bottom"
|
|
||||||
android:text="@string/notificationsMute"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="72dp"/>
|
|
||||||
<View
|
|
||||||
android:layout_marginBottom="@dimen/small_spacing"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/notifyMute"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/notifyMute"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/notifyMute"
|
|
||||||
android:layout_marginEnd="54dp"
|
|
||||||
android:id="@+id/notifyMuteButton"
|
|
||||||
android:layout_width="@dimen/small_radial_size"
|
|
||||||
android:layout_height="@dimen/small_radial_size"
|
|
||||||
android:background="@drawable/padded_circle_accent_select"
|
|
||||||
android:foreground="@drawable/radial_multi_select"/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,375 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="org.thoughtcrime.securesms.conversation.settings.ConversationSettingsActivity"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/back"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:src="@drawable/ic_baseline_close_24"
|
|
||||||
android:scaleType="centerInside"
|
|
||||||
android:layout_width="?android:actionBarSize"
|
|
||||||
android:layout_height="?android:actionBarSize"
|
|
||||||
app:tint="?android:textColorPrimary" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/profilePictureView"
|
|
||||||
layout="@layout/view_large_profile_picture"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:layout_width="120dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:layout_marginTop="@dimen/small_profile_picture_size"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/conversationName"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="@dimen/massive_spacing"
|
|
||||||
android:layout_marginTop="@dimen/small_spacing"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Title"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/profilePictureView"
|
|
||||||
tools:text="@tools:sample/full_names" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/conversationSubtitle"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/conversationName"
|
|
||||||
android:layout_marginHorizontal="@dimen/massive_spacing"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Subtitle"
|
|
||||||
tools:text="@tools:sample/lorem/random"
|
|
||||||
android:maxLines="2"
|
|
||||||
android:ellipsize="end"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Main conversation settings -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/mainConversationSettingContainer"
|
|
||||||
android:background="@drawable/preference_single_no_padding"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/conversationSubtitle"
|
|
||||||
android:layout_marginTop="@dimen/large_spacing"
|
|
||||||
android:layout_marginHorizontal="@dimen/very_large_spacing"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:background="@drawable/debug_border"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_search_conversation"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:text="@string/searchConversation"
|
|
||||||
android:id="@+id/searchConversation"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_edit_group"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:text="@string/groupMembers"
|
|
||||||
android:id="@+id/groupMembers"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:id="@+id/groupMembersDivider"
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_all_media"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:text="@string/conversationsSettingsAllMedia"
|
|
||||||
android:id="@+id/allMedia"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_pin_conversation"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:text="@string/pinConversation"
|
|
||||||
android:id="@+id/pinConversation"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/notificationSettings"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:paddingHorizontal="@dimen/very_large_spacing"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:src="@drawable/ic_notification_settings"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_width="@dimen/setting_image_size"
|
|
||||||
android:layout_height="@dimen/setting_image_size"
|
|
||||||
app:tint="?android:textColorPrimary" />
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_marginStart="@dimen/very_large_spacing"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/sessionNotifications"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/notificationsValue"
|
|
||||||
tools:text="@tools:sample/lorem"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.OptionSummary"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
<include
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/switchContainer"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_width="96dp"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/autoDownloadMediaSwitch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:minHeight="48dp" />
|
|
||||||
</FrameLayout>
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/autoDownloadMediaContainer"
|
|
||||||
android:layout_toEndOf="@+id/switchContainer"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="@dimen/very_large_spacing"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/attachmentsAutoDownload"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/attachmentsAutoDownloadDescription"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.OptionSummary"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Admin settings -->
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/adminControlsGroup"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:constraint_referenced_ids="adminContainer,adminSettingsTitle"/>
|
|
||||||
<TextView
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Subtitle"
|
|
||||||
android:text="@string/adminSettings"
|
|
||||||
android:id="@+id/adminSettingsTitle"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/mainConversationSettingContainer"
|
|
||||||
android:layout_marginTop="@dimen/medium_spacing"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/adminContainer"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/adminContainer"
|
|
||||||
app:layout_constraintHorizontal_bias="0"
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/adminContainer"
|
|
||||||
android:background="@drawable/preference_single_no_padding"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/adminSettingsTitle"
|
|
||||||
android:layout_marginTop="@dimen/small_spacing"
|
|
||||||
android:layout_marginHorizontal="@dimen/very_large_spacing"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:background="@drawable/debug_border"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_edit_group"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
android:text="@string/groupEdit"
|
|
||||||
android:id="@+id/editGroup"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:id="@+id/editGroupDivider"
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<include
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<LinearLayout
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:id="@+id/disappearingMessages"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"
|
|
||||||
android:paddingHorizontal="@dimen/very_large_spacing"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:src="@drawable/ic_disappearing_messages"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_width="@dimen/setting_image_size"
|
|
||||||
android:layout_height="@dimen/setting_image_size"
|
|
||||||
app:tint="?android:textColorPrimary" />
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_marginStart="@dimen/very_large_spacing"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/disappearingMessages"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/disappearingMessagesValue"
|
|
||||||
tools:text="@tools:sample/lorem"
|
|
||||||
android:paddingVertical="1dp"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.OptionSummary"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/destructiveContainer"
|
|
||||||
android:background="@drawable/preference_single_no_padding"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/adminContainer"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
android:layout_marginTop="@dimen/medium_spacing"
|
|
||||||
android:layout_marginBottom="@dimen/massive_spacing"
|
|
||||||
android:layout_marginHorizontal="@dimen/very_large_spacing"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:background="@drawable/debug_border"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_clear_messages"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option.Destructive"
|
|
||||||
android:text="@string/clearMessages"
|
|
||||||
android:id="@+id/clearMessages"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:id="@+id/clearMessagesDivider"
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_leave_group"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option.Destructive"
|
|
||||||
android:text="@string/groupLeave"
|
|
||||||
android:id="@+id/leaveGroup"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
<include
|
|
||||||
android:id="@+id/leaveGroupDivider"
|
|
||||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
|
||||||
layout="@layout/preference_divider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
app:drawableStartCompat="@drawable/ic_delete"
|
|
||||||
style="@style/TextAppearance.Session.ConversationSettings.Option.Destructive"
|
|
||||||
android:text="@string/groupDelete"
|
|
||||||
android:id="@+id/deleteGroup"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_button_height"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</ScrollView>
|
|
12
app/src/main/res/menu/menu_conversation_groups_v2.xml
Normal file
12
app/src/main/res/menu/menu_conversation_groups_v2.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?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:id="@+id/menu_leave_group"
|
||||||
|
android:contentDescription="@string/AccessibilityId_groupLeave"
|
||||||
|
android:title="@string/groupLeave"
|
||||||
|
app:showAsAction="collapseActionView"/>
|
||||||
|
|
||||||
|
</menu>
|
12
app/src/main/res/menu/menu_conversation_groups_v2_admin.xml
Normal file
12
app/src/main/res/menu/menu_conversation_groups_v2_admin.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?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:id="@+id/menu_edit_group"
|
||||||
|
android:contentDescription="@string/AccessibilityId_groupEdit"
|
||||||
|
android:title="@string/groupEdit"
|
||||||
|
app:showAsAction="collapseActionView" />
|
||||||
|
|
||||||
|
</menu>
|
Loading…
Reference in New Issue
Block a user