Changed the missed call control message logic

The control message is now clickable when the phone toggle is disabled or when the microphone permission is not given
This commit is contained in:
ThomasSession 2024-09-02 14:07:19 +10:00
parent 4860adcd86
commit f44d066e67
19 changed files with 105 additions and 107 deletions

View File

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.conversation.v2 package org.thoughtcrime.securesms.conversation.v2
import android.Manifest
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.database.Cursor import android.database.Cursor
@ -33,7 +34,9 @@ import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import com.bumptech.glide.RequestManager import com.bumptech.glide.RequestManager
import com.squareup.phrase.Phrase import com.squareup.phrase.Phrase
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.MissingMicrophonePermissionDialog import org.thoughtcrime.securesms.MissingMicrophonePermissionDialog
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity
import org.thoughtcrime.securesms.showSessionDialog import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.ui.getSubbedCharSequence import org.thoughtcrime.securesms.ui.getSubbedCharSequence
@ -172,43 +175,6 @@ class ConversationAdapter(
is ControlMessageViewHolder -> { is ControlMessageViewHolder -> {
viewHolder.view.bind(message, messageBefore) viewHolder.view.bind(message, messageBefore)
when {
// Click behaviour for first missed call control message
//todo this behaviour is different than iOS where the control message is always clickable when the call toggle is disabled in the privacy page
message.isCallLog && message.isFirstMissedCall -> {
viewHolder.view.setOnClickListener {
context.showSessionDialog {
val titleTxt = context.getSubbedString(
R.string.callsMissedCallFrom,
NAME_KEY to message.individualRecipient.name!!
)
title(titleTxt)
val bodyTxt = context.getSubbedCharSequence(
R.string.callsYouMissedCallPermissions,
NAME_KEY to message.individualRecipient.name!!
)
text(bodyTxt)
button(R.string.sessionSettings) {
Intent(context, PrivacySettingsActivity::class.java)
.let(context::startActivity)
}
cancelButton()
}
}
}
// Click behaviour for missed calls due to missing permission
message.isCallLog && message.isMissedPermissionCall -> {
viewHolder.view.setOnClickListener {
MissingMicrophonePermissionDialog.show(context)
}
}
// non clickable in other cases
else -> viewHolder.view.setOnClickListener(null)
}
} }
} }
} }

View File

@ -1,6 +1,8 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.Manifest
import android.content.Context import android.content.Context
import android.content.Intent
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@ -11,7 +13,6 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.squareup.phrase.Phrase import com.squareup.phrase.Phrase
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.ViewControlMessageBinding import network.loki.messenger.databinding.ViewControlMessageBinding
import network.loki.messenger.libsession_util.util.ExpiryMode import network.loki.messenger.libsession_util.util.ExpiryMode
@ -19,11 +20,19 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.ExpirationConfiguration import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.getColorFromAttr
import org.thoughtcrime.securesms.MissingMicrophonePermissionDialog
import org.thoughtcrime.securesms.conversation.disappearingmessages.DisappearingMessages import org.thoughtcrime.securesms.conversation.disappearingmessages.DisappearingMessages
import org.thoughtcrime.securesms.conversation.disappearingmessages.expiryMode import org.thoughtcrime.securesms.conversation.disappearingmessages.expiryMode
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity
import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.ui.getSubbedCharSequence import org.thoughtcrime.securesms.ui.getSubbedCharSequence
import org.thoughtcrime.securesms.ui.getSubbedString
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class ControlMessageView : LinearLayout { class ControlMessageView : LinearLayout {
@ -32,6 +41,12 @@ class ControlMessageView : LinearLayout {
private val binding = ViewControlMessageBinding.inflate(LayoutInflater.from(context), this, true) private val binding = ViewControlMessageBinding.inflate(LayoutInflater.from(context), this, true)
private val infoDrawable by lazy {
val d = ResourcesCompat.getDrawable(resources, R.drawable.ic_info_outline_white_24dp, context.theme)
d?.setTint(context.getColorFromAttr(R.attr.message_received_text_color))
d
}
constructor(context: Context) : super(context) constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
@ -98,17 +113,63 @@ class ControlMessageView : LinearLayout {
val drawable = when { val drawable = when {
message.isIncomingCall -> R.drawable.ic_incoming_call message.isIncomingCall -> R.drawable.ic_incoming_call
message.isOutgoingCall -> R.drawable.ic_outgoing_call message.isOutgoingCall -> R.drawable.ic_outgoing_call
message.isFirstMissedCall -> R.drawable.ic_info_outline_light
else -> R.drawable.ic_missed_call else -> R.drawable.ic_missed_call
} }
binding.textView.isVisible = false binding.textView.isVisible = false
binding.callTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, drawable, context.theme), null, null, null) binding.callTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
ResourcesCompat.getDrawable(resources, drawable, context.theme),
null, null, null)
binding.callTextView.text = messageBody binding.callTextView.text = messageBody
if (message.expireStarted > 0 && message.expiresIn > 0) { if (message.expireStarted > 0 && message.expiresIn > 0) {
binding.expirationTimerView.isVisible = true binding.expirationTimerView.isVisible = true
binding.expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn) binding.expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
} }
// remove clicks by default
setOnClickListener(null)
hideInfo()
// handle click behaviour depending on criteria
if (message.isMissedCall || message.isFirstMissedCall) {
when {
// if we're currently missing the audio/microphone permission,
// show a dedicated permission dialog
!Permissions.hasAll(context, Manifest.permission.RECORD_AUDIO) -> {
showInfo()
setOnClickListener {
MissingMicrophonePermissionDialog.show(context)
}
}
// when the call toggle is disabled in the privacy screen,
// show a dedicated privacy dialog
!TextSecurePreferences.isCallNotificationsEnabled(context) -> {
showInfo()
setOnClickListener {
context.showSessionDialog {
val titleTxt = context.getSubbedString(
R.string.callsMissedCallFrom,
NAME_KEY to message.individualRecipient.name!!
)
title(titleTxt)
val bodyTxt = context.getSubbedCharSequence(
R.string.callsYouMissedCallPermissions,
NAME_KEY to message.individualRecipient.name!!
)
text(bodyTxt)
button(R.string.sessionSettings) {
Intent(context, PrivacySettingsActivity::class.java)
.let(context::startActivity)
}
cancelButton()
}
}
}
}
}
} }
} }
@ -116,6 +177,24 @@ class ControlMessageView : LinearLayout {
binding.callView.isVisible = message.isCallLog binding.callView.isVisible = message.isCallLog
} }
fun showInfo(){
binding.callTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
binding.callTextView.compoundDrawablesRelative.first(),
null,
infoDrawable,
null
)
}
fun hideInfo(){
binding.callTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
binding.callTextView.compoundDrawablesRelative.first(),
null,
null,
null
)
}
fun recycle() { fun recycle() {
} }

View File

@ -41,7 +41,6 @@ public interface MmsSmsColumns {
protected static final long MISSED_CALL_TYPE = 3; protected static final long MISSED_CALL_TYPE = 3;
protected static final long JOINED_TYPE = 4; protected static final long JOINED_TYPE = 4;
protected static final long FIRST_MISSED_CALL_TYPE = 5; protected static final long FIRST_MISSED_CALL_TYPE = 5;
protected static final long MISSED_PERMISSION_CALL_TYPE = 6;
protected static final long BASE_INBOX_TYPE = 20; protected static final long BASE_INBOX_TYPE = 20;
protected static final long BASE_OUTBOX_TYPE = 21; protected static final long BASE_OUTBOX_TYPE = 21;
@ -236,7 +235,7 @@ public interface MmsSmsColumns {
public static boolean isCallLog(long type) { public static boolean isCallLog(long type) {
long baseType = type & BASE_TYPE_MASK; long baseType = type & BASE_TYPE_MASK;
return baseType == INCOMING_CALL_TYPE || baseType == OUTGOING_CALL_TYPE || return baseType == INCOMING_CALL_TYPE || baseType == OUTGOING_CALL_TYPE ||
baseType == MISSED_CALL_TYPE || baseType == FIRST_MISSED_CALL_TYPE || baseType == MISSED_PERMISSION_CALL_TYPE; baseType == MISSED_CALL_TYPE || baseType == FIRST_MISSED_CALL_TYPE;
} }
public static boolean isExpirationTimerUpdate(long type) { public static boolean isExpirationTimerUpdate(long type) {
@ -267,10 +266,6 @@ public interface MmsSmsColumns {
return (type & BASE_TYPE_MASK) == MISSED_CALL_TYPE; return (type & BASE_TYPE_MASK) == MISSED_CALL_TYPE;
} }
public static boolean isMissedPermissionCall(long type) {
return (type & BASE_TYPE_MASK) == MISSED_PERMISSION_CALL_TYPE;
}
public static boolean isFirstMissedCall(long type) { public static boolean isFirstMissedCall(long type) {
return (type & BASE_TYPE_MASK) == FIRST_MISSED_CALL_TYPE; return (type & BASE_TYPE_MASK) == FIRST_MISSED_CALL_TYPE;
} }

View File

@ -501,8 +501,6 @@ public class SmsDatabase extends MessagingDatabase {
return Types.MISSED_CALL_TYPE; return Types.MISSED_CALL_TYPE;
case CALL_FIRST_MISSED: case CALL_FIRST_MISSED:
return Types.FIRST_MISSED_CALL_TYPE; return Types.FIRST_MISSED_CALL_TYPE;
case CALL_MISSED_PERMISSION:
return Types.MISSED_PERMISSION_CALL_TYPE;
default: default:
return 0; return 0;
} }

View File

@ -142,9 +142,6 @@ public abstract class DisplayRecord {
public boolean isFirstMissedCall() { public boolean isFirstMissedCall() {
return SmsDatabase.Types.isFirstMissedCall(type); return SmsDatabase.Types.isFirstMissedCall(type);
} }
public boolean isMissedPermissionCall() {
return SmsDatabase.Types.isMissedPermissionCall(type);
}
public boolean isDeleted() { return MmsSmsColumns.Types.isDeletedMessage(type); } public boolean isDeleted() { return MmsSmsColumns.Types.isDeletedMessage(type); }
public boolean isMessageRequestResponse() { return MmsSmsColumns.Types.isMessageRequestResponse(type); } public boolean isMessageRequestResponse() { return MmsSmsColumns.Types.isMessageRequestResponse(type); }

View File

@ -134,8 +134,6 @@ public abstract class MessageRecord extends DisplayRecord {
callType = CallMessageType.CALL_OUTGOING; callType = CallMessageType.CALL_OUTGOING;
} else if (isMissedCall()) { } else if (isMissedCall()) {
callType = CallMessageType.CALL_MISSED; callType = CallMessageType.CALL_MISSED;
} else if (isMissedPermissionCall()) {
callType = CallMessageType.CALL_MISSED_PERMISSION;
} else { } else {
callType = CallMessageType.CALL_FIRST_MISSED; callType = CallMessageType.CALL_FIRST_MISSED;
} }

View File

@ -62,26 +62,15 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
if (!approvedContact && storage.getUserPublicKey() != sender) continue if (!approvedContact && storage.getUserPublicKey() != sender) continue
// if the user has not enabled voice/video calls // if the user has not enabled voice/video calls
if (!textSecurePreferences.isCallNotificationsEnabled()) { // or if the user has not granted audio/microphone permissions
if (
!textSecurePreferences.isCallNotificationsEnabled() ||
!Permissions.hasAll(context, Manifest.permission.RECORD_AUDIO)
) {
Log.d("Loki","Dropping call message if call notifications disabled") Log.d("Loki","Dropping call message if call notifications disabled")
if (nextMessage.type != PRE_OFFER) continue if (nextMessage.type != PRE_OFFER) continue
val sentTimestamp = nextMessage.sentTimestamp ?: continue val sentTimestamp = nextMessage.sentTimestamp ?: continue
if (textSecurePreferences.setShownCallNotification()) { insertMissedCall(sender, sentTimestamp)
// first time call notification encountered
val notification = CallNotificationBuilder.getFirstCallNotification(context, sender)
context.getSystemService(NotificationManager::class.java).notify(CallNotificationBuilder.WEBRTC_NOTIFICATION, notification)
insertMissedCall(sender, sentTimestamp, isFirstCall = true)
} else {
insertMissedCall(sender, sentTimestamp)
}
continue
}
// or if the user has not granted audio/microphone permissions
else if (!Permissions.hasAll(context, Manifest.permission.RECORD_AUDIO)) {
if (nextMessage.type != PRE_OFFER) continue
val sentTimestamp = nextMessage.sentTimestamp ?: continue
Log.d("Loki", "Attempted to receive a call without audio permissions")
insertMissedPermissionCall(sender, sentTimestamp)
continue continue
} }
@ -103,20 +92,10 @@ class CallMessageProcessor(private val context: Context, private val textSecureP
} }
} }
private fun insertMissedCall(sender: String, sentTimestamp: Long, isFirstCall: Boolean = false) { private fun insertMissedCall(sender: String, sentTimestamp: Long) {
val currentUserPublicKey = storage.getUserPublicKey() val currentUserPublicKey = storage.getUserPublicKey()
if (sender == currentUserPublicKey) return // don't insert a "missed" due to call notifications disabled if it's our own sender if (sender == currentUserPublicKey) return // don't insert a "missed" due to call notifications disabled if it's our own sender
if (isFirstCall) { storage.insertCallMessage(sender, CallMessageType.CALL_MISSED, sentTimestamp)
storage.insertCallMessage(sender, CallMessageType.CALL_FIRST_MISSED, sentTimestamp)
} else {
storage.insertCallMessage(sender, CallMessageType.CALL_MISSED, sentTimestamp)
}
}
private fun insertMissedPermissionCall(sender: String, sentTimestamp: Long) {
val currentUserPublicKey = storage.getUserPublicKey()
if (sender == currentUserPublicKey) return // don't insert a "missed" due to call notifications disabled if it's our own sender
storage.insertCallMessage(sender, CallMessageType.CALL_MISSED_PERMISSION, sentTimestamp)
} }
private fun incomingHangup(callMessage: CallMessage) { private fun incomingHangup(callMessage: CallMessage) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>

View File

@ -5,8 +5,8 @@
android:viewportHeight="20"> android:viewportHeight="20">
<path <path
android:pathData="M14.414,7l3.293,-3.293a1,1 0,0 0,-1.414 -1.414L13,5.586V4a1,1 0,1 0,-2 0v4.003a0.996,0.996 0,0 0,0.617 0.921A0.997,0.997 0,0 0,12 9h4a1,1 0,1 0,0 -2h-1.586z" android:pathData="M14.414,7l3.293,-3.293a1,1 0,0 0,-1.414 -1.414L13,5.586V4a1,1 0,1 0,-2 0v4.003a0.996,0.996 0,0 0,0.617 0.921A0.997,0.997 0,0 0,12 9h4a1,1 0,1 0,0 -2h-1.586z"
android:fillColor="#000000"/> android:fillColor="?message_received_text_color"/>
<path <path
android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z" android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z"
android:fillColor="#000000"/> android:fillColor="?message_received_text_color"/>
</vector> </vector>

View File

@ -5,8 +5,8 @@
android:viewportHeight="20"> android:viewportHeight="20">
<path <path
android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z" android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z"
android:fillColor="#000000"/> android:fillColor="?danger"/>
<path <path
android:pathData="M16.707,3.293a1,1 0,0 1,0 1.414L15.414,6l1.293,1.293a1,1 0,0 1,-1.414 1.414L14,7.414l-1.293,1.293a1,1 0,1 1,-1.414 -1.414L12.586,6l-1.293,-1.293a1,1 0,0 1,1.414 -1.414L14,4.586l1.293,-1.293a1,1 0,0 1,1.414 0z" android:pathData="M16.707,3.293a1,1 0,0 1,0 1.414L15.414,6l1.293,1.293a1,1 0,0 1,-1.414 1.414L14,7.414l-1.293,1.293a1,1 0,1 1,-1.414 -1.414L12.586,6l-1.293,-1.293a1,1 0,0 1,1.414 -1.414L14,4.586l1.293,-1.293a1,1 0,0 1,1.414 0z"
android:fillColor="#000000"/> android:fillColor="?danger"/>
</vector> </vector>

View File

@ -5,8 +5,8 @@
android:viewportHeight="20"> android:viewportHeight="20">
<path <path
android:pathData="M17.924,2.617a0.997,0.997 0,0 0,-0.215 -0.322l-0.004,-0.004A0.997,0.997 0,0 0,17 2h-4a1,1 0,1 0,0 2h1.586l-3.293,3.293a1,1 0,0 0,1.414 1.414L16,5.414V7a1,1 0,1 0,2 0V3a0.997,0.997 0,0 0,-0.076 -0.383z" android:pathData="M17.924,2.617a0.997,0.997 0,0 0,-0.215 -0.322l-0.004,-0.004A0.997,0.997 0,0 0,17 2h-4a1,1 0,1 0,0 2h1.586l-3.293,3.293a1,1 0,0 0,1.414 1.414L16,5.414V7a1,1 0,1 0,2 0V3a0.997,0.997 0,0 0,-0.076 -0.383z"
android:fillColor="#000000"/> android:fillColor="?message_received_text_color"/>
<path <path
android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z" android:pathData="M2,3a1,1 0,0 1,1 -1h2.153a1,1 0,0 1,0.986 0.836l0.74,4.435a1,1 0,0 1,-0.54 1.06l-1.548,0.773a11.037,11.037 0,0 0,6.105 6.105l0.774,-1.548a1,1 0,0 1,1.059 -0.54l4.435,0.74a1,1 0,0 1,0.836 0.986V17a1,1 0,0 1,-1 1h-2C7.82,18 2,12.18 2,5V3z"
android:fillColor="#000000"/> android:fillColor="?message_received_text_color"/>
</vector> </vector>

View File

@ -65,7 +65,6 @@
tools:text="You missed a call" tools:text="You missed a call"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:drawableTint="?message_received_text_color"
app:drawableStartCompat="@drawable/ic_missed_call" /> app:drawableStartCompat="@drawable/ic_missed_call" />
</FrameLayout> </FrameLayout>

View File

@ -48,7 +48,7 @@
<item name="menu_selectall_icon">@drawable/ic_baseline_select_all_24</item> <item name="menu_selectall_icon">@drawable/ic_baseline_select_all_24</item>
<item name="menu_split_icon">@drawable/ic_baseline_call_split_24</item> <item name="menu_split_icon">@drawable/ic_baseline_call_split_24</item>
<item name="menu_popup_expand">@drawable/ic_baseline_launch_24</item> <item name="menu_popup_expand">@drawable/ic_baseline_launch_24</item>
<item name="menu_info_icon">@drawable/ic_baseline_info_24</item> <item name="menu_info_icon">@drawable/ic_info_outline_white_24dp</item>
<item name="menu_pin_icon">@drawable/ic_outline_pin_24</item> <item name="menu_pin_icon">@drawable/ic_outline_pin_24</item>
<item name="menu_unpin_icon">@drawable/ic_outline_pin_off_24</item> <item name="menu_unpin_icon">@drawable/ic_outline_pin_off_24</item>
<item name="menu_mark_all_as_read">@drawable/ic_outline_mark_chat_read_24</item> <item name="menu_mark_all_as_read">@drawable/ic_outline_mark_chat_read_24</item>

View File

@ -4,6 +4,5 @@ enum class CallMessageType {
CALL_MISSED, CALL_MISSED,
CALL_INCOMING, CALL_INCOMING,
CALL_OUTGOING, CALL_OUTGOING,
CALL_FIRST_MISSED, CALL_FIRST_MISSED
CALL_MISSED_PERMISSION,
} }

View File

@ -8,22 +8,21 @@ import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.calls.CallMessageType.CALL_FIRST_MISSED import org.session.libsession.messaging.calls.CallMessageType.CALL_FIRST_MISSED
import org.session.libsession.messaging.calls.CallMessageType.CALL_INCOMING import org.session.libsession.messaging.calls.CallMessageType.CALL_INCOMING
import org.session.libsession.messaging.calls.CallMessageType.CALL_MISSED import org.session.libsession.messaging.calls.CallMessageType.CALL_MISSED
import org.session.libsession.messaging.calls.CallMessageType.CALL_MISSED_PERMISSION
import org.session.libsession.messaging.calls.CallMessageType.CALL_OUTGOING import org.session.libsession.messaging.calls.CallMessageType.CALL_OUTGOING
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.SCREENSHOT import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.SCREENSHOT
import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.getExpirationTypeDisplayValue
import org.session.libsession.utilities.truncateIdForDisplay
import org.session.libsignal.utilities.Log
import org.session.libsession.utilities.StringSubstitutionConstants.COUNT_KEY import org.session.libsession.utilities.StringSubstitutionConstants.COUNT_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.DISAPPEARING_MESSAGES_TYPE_KEY import org.session.libsession.utilities.StringSubstitutionConstants.DISAPPEARING_MESSAGES_TYPE_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.OTHER_NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.OTHER_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
import org.session.libsession.utilities.getExpirationTypeDisplayValue
import org.session.libsession.utilities.truncateIdForDisplay
import org.session.libsignal.utilities.Log
object UpdateMessageBuilder { object UpdateMessageBuilder {
const val TAG = "libsession" const val TAG = "libsession"
@ -266,7 +265,6 @@ object UpdateMessageBuilder {
CALL_INCOMING -> Phrase.from(context, R.string.callsCalledYou).put(NAME_KEY, senderName).format().toString() CALL_INCOMING -> Phrase.from(context, R.string.callsCalledYou).put(NAME_KEY, senderName).format().toString()
CALL_OUTGOING -> Phrase.from(context, R.string.callsYouCalled).put(NAME_KEY, senderName).format().toString() CALL_OUTGOING -> Phrase.from(context, R.string.callsYouCalled).put(NAME_KEY, senderName).format().toString()
CALL_MISSED, CALL_FIRST_MISSED -> Phrase.from(context, R.string.callsMissedCallFrom).put(NAME_KEY, senderName).format().toString() CALL_MISSED, CALL_FIRST_MISSED -> Phrase.from(context, R.string.callsMissedCallFrom).put(NAME_KEY, senderName).format().toString()
CALL_MISSED_PERMISSION -> Phrase.from(context, R.string.callsMissedCallFrom).put(NAME_KEY, senderName).format().toString() + "\n" + context.getString(R.string.permissionsMicrophoneDescription)
} }
} }
} }