mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-31 07:36:09 +00:00
feat: add more conversation settings options and notification settings
This commit is contained in:
@@ -228,6 +228,10 @@
|
||||
<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/activity_notification_settings_title"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Session.DayNight"/>
|
||||
<activity
|
||||
android:name="org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity"
|
||||
android:screenOrientation="portrait"
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
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 */ }
|
||||
}
|
||||
@@ -27,6 +27,18 @@ class ConversationSettingsActivity: PassphraseRequiredActionBarActivity(), View.
|
||||
|
||||
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 lokiThreadDb: LokiThreadDatabase
|
||||
@Inject lateinit var viewModelFactory: ConversationSettingsViewModel.AssistedFactory
|
||||
@@ -38,6 +50,10 @@ class ConversationSettingsActivity: PassphraseRequiredActionBarActivity(), View.
|
||||
viewModelFactory.create(threadId)
|
||||
}
|
||||
|
||||
private val notificationActivityCallback = registerForActivityResult(ConversationNotificationSettingsActivityContract()) {
|
||||
updateRecipientDisplay()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
super.onCreate(savedInstanceState, ready)
|
||||
binding = ActivityConversationSettingsBinding.inflate(layoutInflater)
|
||||
@@ -47,16 +63,12 @@ class ConversationSettingsActivity: PassphraseRequiredActionBarActivity(), View.
|
||||
binding.searchConversation.setOnClickListener(this)
|
||||
binding.allMedia.setOnClickListener(this)
|
||||
binding.pinConversation.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
binding.notificationSettings.setOnClickListener(this)
|
||||
binding.back.setOnClickListener(this)
|
||||
binding.autoDownloadMediaSwitch.setOnCheckedChangeListener { _, isChecked ->
|
||||
viewModel.setTrusted(isChecked)
|
||||
updateRecipientDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRecipientDisplay() {
|
||||
@@ -72,35 +84,66 @@ class ConversationSettingsActivity: PassphraseRequiredActionBarActivity(), View.
|
||||
binding.conversationSubtitle.isVisible = recipient.isClosedGroupRecipient.apply {
|
||||
binding.conversationSubtitle.text = "TODO: This is a test for group descriptions"
|
||||
}
|
||||
|
||||
// Toggle group-specific settings
|
||||
val areGroupOptionsVisible = recipient.isClosedGroupRecipient
|
||||
groupOptions.forEach { v ->
|
||||
v.isVisible = areGroupOptionsVisible
|
||||
}
|
||||
|
||||
// Group admin settings
|
||||
val isUserGroupAdmin = areGroupOptionsVisible && viewModel.isUserGroupAdmin()
|
||||
with (binding) {
|
||||
groupMembersDivider.root.isVisible = areGroupOptionsVisible && !isUserGroupAdmin
|
||||
groupMembers.isVisible = areGroupOptionsVisible && !isUserGroupAdmin
|
||||
adminControlsGroup.isVisible = isUserGroupAdmin
|
||||
deleteGroup.isVisible = isUserGroupAdmin
|
||||
clearMessagesDivider.root.isVisible = isUserGroupAdmin
|
||||
}
|
||||
|
||||
// Set pinned state
|
||||
binding.pinConversation.setText(
|
||||
if (viewModel.isPinned()) R.string.conversation_settings_unpin_conversation
|
||||
else R.string.conversation_settings_pin_conversation
|
||||
)
|
||||
|
||||
// Set auto-download state
|
||||
val trusted = viewModel.isTrusted()
|
||||
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?) {
|
||||
if (v === binding.searchConversation) {
|
||||
setResult(RESULT_SEARCH)
|
||||
finish()
|
||||
} else if (v === binding.allMedia) {
|
||||
val threadRecipient = viewModel.recipient ?: return
|
||||
val intent = Intent(this, MediaOverviewActivity::class.java).apply {
|
||||
putExtra(MediaOverviewActivity.ADDRESS_EXTRA, threadRecipient.address)
|
||||
when {
|
||||
v === binding.searchConversation -> {
|
||||
setResult(RESULT_SEARCH)
|
||||
finish()
|
||||
}
|
||||
startActivity(intent)
|
||||
} else if (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.allMedia -> {
|
||||
val threadRecipient = viewModel.recipient ?: return
|
||||
val intent = Intent(this, MediaOverviewActivity::class.java).apply {
|
||||
putExtra(MediaOverviewActivity.ADDRESS_EXTRA, threadRecipient.address)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,15 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.launch
|
||||
import org.session.libsession.database.StorageProtocol
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.database.Storage
|
||||
|
||||
class ConversationSettingsViewModel(
|
||||
val threadId: Long,
|
||||
private val storage: Storage
|
||||
private val storage: StorageProtocol,
|
||||
private val prefs: TextSecurePreferences
|
||||
): ViewModel() {
|
||||
|
||||
val recipient get() = storage.getRecipientForThread(threadId)
|
||||
@@ -22,6 +26,22 @@ class ConversationSettingsViewModel(
|
||||
storage.setThreadPinned(threadId, !isPinned)
|
||||
}
|
||||
|
||||
fun isTrusted() = recipient?.let { recipient ->
|
||||
storage.isContactTrusted(recipient)
|
||||
} ?: false
|
||||
|
||||
fun setTrusted(isTrusted: Boolean) {
|
||||
val recipient = recipient ?: return
|
||||
storage.setContactTrusted(recipient, isTrusted)
|
||||
}
|
||||
|
||||
fun isUserGroupAdmin(): Boolean = recipient?.let { recipient ->
|
||||
if (!recipient.isGroupRecipient) return@let false
|
||||
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
|
||||
} ?: false
|
||||
|
||||
// DI-related
|
||||
@dagger.assisted.AssistedFactory
|
||||
interface AssistedFactory {
|
||||
@@ -29,11 +49,12 @@ class ConversationSettingsViewModel(
|
||||
}
|
||||
class Factory @AssistedInject constructor(
|
||||
@Assisted private val threadId: Long,
|
||||
private val storage: Storage
|
||||
private val storage: Storage,
|
||||
private val prefs: TextSecurePreferences
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ConversationSettingsViewModel(threadId, storage) as T
|
||||
return ConversationSettingsViewModel(threadId, storage, prefs) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -685,6 +685,21 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
}
|
||||
}
|
||||
|
||||
override fun isContactTrusted(recipient: Recipient): Boolean {
|
||||
val sessionID = recipient.address.toString()
|
||||
val contactDb = DatabaseComponent.get(context).sessionContactDatabase()
|
||||
val contact = contactDb.getContactWithSessionID(sessionID) ?: return false
|
||||
return contact.isTrusted
|
||||
}
|
||||
|
||||
override fun setContactTrusted(recipient: Recipient, isTrusted: Boolean) {
|
||||
val sessionID = recipient.address.toString()
|
||||
val contactDb = DatabaseComponent.get(context).sessionContactDatabase()
|
||||
val contact = contactDb.getContactWithSessionID(sessionID) ?: return
|
||||
val threadID = DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(recipient)
|
||||
contactDb.setContactIsTrusted(contact, isTrusted, threadID)
|
||||
}
|
||||
|
||||
override fun getLastUpdated(threadID: Long): Long {
|
||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||
return threadDB.getLastUpdated(threadID)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?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/notify_type_all"
|
||||
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/notify_type_mentions"
|
||||
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/notify_type_mute"
|
||||
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>
|
||||
@@ -9,6 +9,16 @@
|
||||
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_arrow_back_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"
|
||||
@@ -71,6 +81,21 @@
|
||||
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/conversation_settings_group_members"
|
||||
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"
|
||||
@@ -235,6 +260,7 @@
|
||||
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"
|
||||
@@ -319,6 +345,7 @@
|
||||
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"
|
||||
@@ -333,6 +360,7 @@
|
||||
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"
|
||||
@@ -342,7 +370,7 @@
|
||||
android:background="?selectableItemBackground"
|
||||
app:drawableStartCompat="@drawable/ic_delete"
|
||||
style="@style/TextAppearance.Session.ConversationSettings.Option.Destructive"
|
||||
android:text="@string/conversation_settings_edit_group"
|
||||
android:text="@string/conversation_settings_delete_group"
|
||||
android:id="@+id/deleteGroup"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/setting_button_height"/>
|
||||
|
||||
@@ -7,24 +7,26 @@
|
||||
<RelativeLayout
|
||||
android:id="@+id/doubleModeImageViewContainer"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_width="@dimen/large_profile_picture_size"
|
||||
android:layout_height="@dimen/large_profile_picture_size">
|
||||
android:layout_width="@dimen/extra_large_profile_picture_size"
|
||||
android:layout_height="@dimen/extra_large_profile_picture_size">
|
||||
|
||||
<ImageView
|
||||
android:layout_margin="@dimen/small_spacing"
|
||||
android:id="@+id/doubleModeImageView1"
|
||||
android:layout_width="@dimen/medium_profile_picture_size"
|
||||
android:layout_height="@dimen/medium_profile_picture_size"
|
||||
android:layout_width="@dimen/large_profile_picture_size"
|
||||
android:layout_height="@dimen/large_profile_picture_size"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@drawable/profile_picture_view_medium_background" />
|
||||
android:background="@drawable/profile_picture_view_large_background" />
|
||||
|
||||
<ImageView
|
||||
android:layout_margin="@dimen/small_spacing"
|
||||
android:id="@+id/doubleModeImageView2"
|
||||
android:layout_width="@dimen/medium_profile_picture_size"
|
||||
android:layout_height="@dimen/medium_profile_picture_size"
|
||||
android:layout_width="@dimen/large_profile_picture_size"
|
||||
android:layout_height="@dimen/large_profile_picture_size"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@drawable/profile_picture_view_medium_background" />
|
||||
android:background="@drawable/profile_picture_view_large_background" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@
|
||||
<string-array name="notify_types">
|
||||
<item>@string/notify_type_all</item>
|
||||
<item>@string/notify_type_mentions</item>
|
||||
<item>@string/notify_type_mute</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -748,8 +748,9 @@
|
||||
<string name="dialog_send_seed_title">Warning</string>
|
||||
<string name="dialog_send_seed_explanation">This is your recovery phrase. If you send it to someone they\'ll have full access to your account.</string>
|
||||
<string name="dialog_send_seed_send_button_title">Send</string>
|
||||
<string name="notify_type_all">All</string>
|
||||
<string name="notify_type_mentions">Mentions</string>
|
||||
<string name="notify_type_all">All Messages</string>
|
||||
<string name="notify_type_mentions">Mentions Only</string>
|
||||
<string name="notify_type_mute">Mute</string>
|
||||
<string name="deleted_message">This message has been deleted</string>
|
||||
<string name="delete_message_for_me">Delete just for me</string>
|
||||
<string name="delete_message_for_everyone">Delete for everyone</string>
|
||||
@@ -877,4 +878,6 @@
|
||||
<string name="conversation_settings_add_admins">Add Admins</string>
|
||||
<string name="conversation_settings_clear_messages">Clear Messages</string>
|
||||
<string name="conversation_settings_leave_group">Leave Group</string>
|
||||
<string name="conversation_settings_group_members">Group Members</string>
|
||||
<string name="conversation_settings_delete_group">Delete Group</string>
|
||||
</resources>
|
||||
|
||||
@@ -163,6 +163,8 @@ interface StorageProtocol {
|
||||
fun getRecipientForThread(threadId: Long): Recipient?
|
||||
fun getRecipientSettings(address: Address): RecipientSettings?
|
||||
fun addContacts(contacts: List<ConfigurationMessage.Contact>)
|
||||
fun isContactTrusted(recipient: Recipient): Boolean
|
||||
fun setContactTrusted(recipient: Recipient, isTrusted: Boolean)
|
||||
|
||||
// Attachments
|
||||
fun getAttachmentDataUri(attachmentId: AttachmentId): Uri
|
||||
|
||||
Reference in New Issue
Block a user