mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 11:05:25 +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:value="org.thoughtcrime.securesms.home.HomeActivity" />
|
||||
</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
|
||||
android:name="org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity"
|
||||
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.conversation.ConversationActionBarDelegate
|
||||
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.OnReactionSelectedListener
|
||||
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.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.ReactionRecord
|
||||
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
||||
import org.thoughtcrime.securesms.home.search.getSearchName
|
||||
@ -222,7 +221,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
ConversationActionModeCallbackDelegate, VisibleMessageViewDelegate, RecipientModifiedListener,
|
||||
SearchBottomBar.EventListener, LoaderManager.LoaderCallbacks<Cursor>, ConversationActionBarDelegate,
|
||||
OnReactionSelectedListener, ReactWithAnyEmojiDialogFragment.Callback, ReactionsDialogFragment.Callback,
|
||||
ConversationMenuHelper.ConversationMenuListener, View.OnClickListener {
|
||||
ConversationMenuHelper.ConversationMenuListener {
|
||||
|
||||
private lateinit var binding: ActivityConversationV2Binding
|
||||
|
||||
@ -239,6 +238,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
@Inject lateinit var reactionDb: ReactionDatabase
|
||||
@Inject lateinit var viewModelFactory: ConversationViewModel.AssistedFactory
|
||||
@Inject lateinit var mentionViewModelFactory: MentionViewModel.AssistedFactory
|
||||
@Inject lateinit var configFactory: ConfigFactory
|
||||
|
||||
private val screenshotObserver by lazy {
|
||||
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 linkPreviewViewModel: LinkPreviewViewModel by lazy {
|
||||
ViewModelProvider(this, LinkPreviewViewModel.Factory(LinkPreviewRepository()))
|
||||
@ -497,7 +490,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
updatePlaceholder()
|
||||
setUpBlockedBanner()
|
||||
binding.searchBottomBar.setEventListener(this)
|
||||
binding.toolbarContent.profilePictureView.setOnClickListener(this)
|
||||
updateSendAfterApprovalText()
|
||||
setUpMessageRequests()
|
||||
|
||||
@ -949,10 +941,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
val recipient = viewModel.recipient ?: return false
|
||||
if (!viewModel.isMessageRequestThread) {
|
||||
ConversationMenuHelper.onPrepareOptionsMenu(
|
||||
menu,
|
||||
menuInflater,
|
||||
recipient,
|
||||
this
|
||||
menu = menu,
|
||||
inflater = menuInflater,
|
||||
thread = recipient,
|
||||
context = this,
|
||||
configFactory = configFactory,
|
||||
)
|
||||
}
|
||||
maybeUpdateToolbar(recipient)
|
||||
@ -1219,17 +1212,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
return false
|
||||
}
|
||||
return viewModel.recipient?.let { recipient ->
|
||||
ConversationMenuHelper.onOptionItemSelected(this, item, recipient)
|
||||
ConversationMenuHelper.onOptionItemSelected(this, item, recipient, configFactory, storage)
|
||||
} ?: false
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
if (v === binding?.toolbarContent?.profilePictureView) {
|
||||
// open conversation settings
|
||||
conversationSettingsCallback.launch(viewModel.threadId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun block(deleteThread: Boolean) {
|
||||
val recipient = viewModel.recipient ?: return Log.w("Loki", "Recipient was null for block action")
|
||||
val invitingAdmin = viewModel.invitingAdmin
|
||||
|
@ -5,7 +5,6 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.AsyncTask
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
@ -21,13 +20,14 @@ import androidx.core.graphics.drawable.IconCompat
|
||||
import com.squareup.phrase.Phrase
|
||||
import java.io.IOException
|
||||
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.leave
|
||||
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.TextSecurePreferences
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.utilities.AccountId
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
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.conversation.v2.ConversationActivityV2
|
||||
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.groups.EditLegacyGroupActivity
|
||||
import org.thoughtcrime.securesms.groups.EditLegacyGroupActivity.Companion.groupIDKey
|
||||
@ -54,7 +56,8 @@ object ConversationMenuHelper {
|
||||
menu: Menu,
|
||||
inflater: MenuInflater,
|
||||
thread: Recipient,
|
||||
context: Context
|
||||
context: Context,
|
||||
configFactory: ConfigFactory,
|
||||
) {
|
||||
// Prepare
|
||||
menu.clear()
|
||||
@ -77,10 +80,20 @@ object ConversationMenuHelper {
|
||||
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) {
|
||||
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
|
||||
if (isCommunity) {
|
||||
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) {
|
||||
R.id.menu_view_all_media -> { showAllMedia(context, thread) }
|
||||
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_open_group_url -> { copyOpenGroupUrl(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_unmute_notifications -> { unmute(context, thread) }
|
||||
R.id.menu_mute_notifications -> { mute(context, thread) }
|
||||
@ -278,26 +297,67 @@ object ConversationMenuHelper {
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
private fun leaveClosedGroup(context: Context, thread: Recipient) {
|
||||
if (!thread.isLegacyClosedGroupRecipient) { return }
|
||||
private fun leaveClosedGroup(
|
||||
context: Context,
|
||||
thread: Recipient,
|
||||
configFactory: ConfigFactory,
|
||||
storage: StorageProtocol
|
||||
) {
|
||||
when {
|
||||
thread.isLegacyClosedGroupRecipient -> {
|
||||
val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull()
|
||||
val admins = group.admins
|
||||
val accountID = TextSecurePreferences.getLocalNumber(context)
|
||||
val isCurrentUserAdmin = admins.any { it.toString() == accountID }
|
||||
|
||||
val group = DatabaseComponent.get(context).groupDatabase().getGroup(thread.address.toGroupString()).orNull()
|
||||
val admins = group.admins
|
||||
val accountID = TextSecurePreferences.getLocalNumber(context)
|
||||
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)
|
||||
.put(GROUP_NAME_KEY, group.title)
|
||||
.put(GROUP_NAME_KEY, groupName)
|
||||
.format()
|
||||
} else {
|
||||
Phrase.from(context, R.string.groupLeaveDescription)
|
||||
.put(GROUP_NAME_KEY, group.title)
|
||||
.put(GROUP_NAME_KEY, groupName)
|
||||
.format()
|
||||
}
|
||||
|
||||
fun onLeaveFailed() {
|
||||
val txt = Phrase.from(context, R.string.groupLeaveErrorFailed)
|
||||
.put(GROUP_NAME_KEY, group.title)
|
||||
.put(GROUP_NAME_KEY, groupName)
|
||||
.format().toString()
|
||||
Toast.makeText(context, txt, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
@ -307,11 +367,7 @@ object ConversationMenuHelper {
|
||||
text(message)
|
||||
dangerButton(R.string.leave) {
|
||||
try {
|
||||
val groupPublicKey = doubleDecodeGroupID(thread.address.toString()).toHexString()
|
||||
val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(groupPublicKey)
|
||||
|
||||
if (isClosedGroup) MessageSender.leave(groupPublicKey, notifyUser = false)
|
||||
else onLeaveFailed()
|
||||
doLeave()
|
||||
} catch (e: Exception) {
|
||||
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