diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java b/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java index a114e9bab0..8d73f8eded 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ComposeText.java @@ -9,13 +9,11 @@ import android.text.Annotation; import android.text.Editable; import android.text.InputType; import android.text.Selection; -import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; -import android.text.style.RelativeSizeSpan; import android.util.AttributeSet; import android.view.ActionMode; import android.view.Menu; @@ -49,7 +47,6 @@ import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.List; @@ -65,7 +62,6 @@ public class ComposeText extends EmojiEditText { private static final Pattern TIME_PATTERN = Pattern.compile("^[0-9]{1,2}:[0-9]{1,2}$"); private CharSequence hint; - private SpannableString subHint; private MentionRendererDelegate mentionRendererDelegate; private SpoilerRendererDelegate spoilerRendererDelegate; private MentionValidatorWatcher mentionValidatorWatcher; @@ -106,13 +102,7 @@ public class ComposeText extends EmojiEditText { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (getLayout() != null && !TextUtils.isEmpty(hint)) { - if (!TextUtils.isEmpty(subHint)) { - setHintWithChecks(new SpannableStringBuilder().append(ellipsizeToWidth(hint)) - .append("\n") - .append(ellipsizeToWidth(subHint))); - } else { - setHintWithChecks(ellipsizeToWidth(hint)); - } + setHintWithChecks(ellipsizeToWidth(hint)); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } @@ -173,25 +163,9 @@ public class ComposeText extends EmojiEditText { TruncateAt.END); } - public void setHint(@NonNull String hint, @Nullable CharSequence subHint) { + public void setHint(@NonNull String hint) { this.hint = hint; - - if (subHint != null) { - this.subHint = new SpannableString(subHint); - this.subHint.setSpan(new RelativeSizeSpan(0.5f), 0, subHint.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); - } else { - this.subHint = null; - } - - if (this.subHint != null) { - setHintWithChecks(new SpannableStringBuilder().append(ellipsizeToWidth(this.hint)) - .append("\n") - .append(ellipsizeToWidth(this.subHint))); - } else { - setHintWithChecks(ellipsizeToWidth(this.hint)); - } - - setHintWithChecks(hint); + setHintWithChecks(ellipsizeToWidth(this.hint)); } public void setDraftText(@Nullable CharSequence draftText) { @@ -249,10 +223,7 @@ public class ComposeText extends EmojiEditText { } setImeOptions(imeOptions); - setHint(getContext().getString(messageSendType.getComposeHintRes()), - messageSendType.getSimName() != null - ? getContext().getString(R.string.conversation_activity__from_sim_name, messageSendType.getSimName()) - : null); + setHint(getContext().getString(messageSendType.getComposeHintRes())); setInputType(inputType); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/SendButton.kt b/app/src/main/java/org/thoughtcrime/securesms/components/SendButton.kt index 94473f72ff..30de588f41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/SendButton.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/SendButton.kt @@ -6,13 +6,7 @@ import android.view.View import android.view.View.OnLongClickListener import android.view.ViewGroup import androidx.appcompat.widget.AppCompatImageButton -import com.google.android.material.snackbar.Snackbar -import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.components.menu.ActionItem -import org.thoughtcrime.securesms.components.menu.SignalContextMenu import org.thoughtcrime.securesms.conversation.MessageSendType -import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.ViewUtil /** @@ -21,83 +15,21 @@ import org.thoughtcrime.securesms.util.ViewUtil */ class SendButton(context: Context, attributeSet: AttributeSet?) : AppCompatImageButton(context, attributeSet), OnLongClickListener { - companion object { - private val TAG = Log.tag(SendButton::class.java) - } - private var scheduledSendListener: ScheduledSendListener? = null - private var availableSendTypes: List = MessageSendType.getAllAvailable(context, false) - private var activeMessageSendType: MessageSendType? = null - private var defaultTransportType: MessageSendType.TransportType = MessageSendType.TransportType.SIGNAL - private var defaultSubscriptionId: Int? = null - - var snackbarContainer: View? = null private var popupContainer: ViewGroup? = null init { setOnLongClickListener(this) ViewUtil.mirrorIfRtl(this, getContext()) - } - - /** - * The actively-selected send type. - */ - private val selectedSendType: MessageSendType - get() { - activeMessageSendType?.let { - return it - } - - if (defaultTransportType === MessageSendType.TransportType.SMS) { - for (type in availableSendTypes) { - if (type.usesSmsTransport && (defaultSubscriptionId == null || type.simSubscriptionId == defaultSubscriptionId)) { - return type - } - } - } - - for (type in availableSendTypes) { - if (type.transportType === defaultTransportType) { - return type - } - } - - Log.w(TAG, "No options of default type! Resetting. DefaultTransportType: $defaultTransportType, AllAvailable: ${availableSendTypes.map { it.transportType }}") - - val signalType: MessageSendType? = availableSendTypes.firstOrNull { it.usesSignalTransport } - if (signalType != null) { - Log.w(TAG, "No options of default type, but Signal type is available. Switching. DefaultTransportType: $defaultTransportType, AllAvailable: ${availableSendTypes.map { it.transportType }}") - defaultTransportType = MessageSendType.TransportType.SIGNAL - onSelectionChanged(signalType) - return signalType - } else if (availableSendTypes.isEmpty()) { - Log.w(TAG, "No send types available at all! Enabling the Signal transport.") - defaultTransportType = MessageSendType.TransportType.SIGNAL - availableSendTypes = listOf(MessageSendType.SignalMessageSendType) - onSelectionChanged(MessageSendType.SignalMessageSendType) - return MessageSendType.SignalMessageSendType - } else { - throw AssertionError("No options of default type! DefaultTransportType: $defaultTransportType, AllAvailable: ${availableSendTypes.map { it.transportType }}") - } - } - - fun triggerSelectedChangedEvent() { - onSelectionChanged(newType = selectedSendType) + setImageResource(MessageSendType.SignalMessageSendType.buttonDrawableRes) + contentDescription = context.getString(MessageSendType.SignalMessageSendType.titleRes) } fun setScheduledSendListener(listener: ScheduledSendListener?) { this.scheduledSendListener = listener } - private fun setSendType(sendType: MessageSendType?) { - if (activeMessageSendType == sendType) { - return - } - activeMessageSendType = sendType - onSelectionChanged(newType = selectedSendType) - } - /** * Must be called with a view that is acceptable for determining the bounds of the popup selector. */ @@ -105,58 +37,19 @@ class SendButton(context: Context, attributeSet: AttributeSet?) : AppCompatImage popupContainer = container } - private fun onSelectionChanged(newType: MessageSendType) { - setImageResource(newType.buttonDrawableRes) - contentDescription = context.getString(newType.titleRes) - } - override fun onLongClick(v: View): Boolean { if (!isEnabled) { return false } val scheduleListener = scheduledSendListener - if (availableSendTypes.size == 1) { - return if (scheduleListener?.canSchedule() == true && selectedSendType.transportType != MessageSendType.TransportType.SMS) { - scheduleListener.onSendScheduled() - true - } else if (snackbarContainer != null && !SignalStore.misc().smsExportPhase.allowSmsFeatures()) { - Snackbar.make(snackbarContainer!!, R.string.InputPanel__sms_messaging_is_no_longer_supported_in_signal, Snackbar.LENGTH_SHORT).show() - true - } else { - false - } + + return if (scheduleListener?.canSchedule() == true) { + scheduleListener.onSendScheduled() + true + } else { + false } - - showSendTypeContextMenu(selectedSendType.transportType != MessageSendType.TransportType.SMS) - - return true - } - - private fun showSendTypeContextMenu(allowScheduling: Boolean) { - val currentlySelected: MessageSendType = selectedSendType - val listener = scheduledSendListener - val items = availableSendTypes - .filterNot { it == currentlySelected } - .map { option -> - ActionItem( - iconRes = option.menuDrawableRes, - title = option.getTitle(context), - action = { setSendType(option) } - ) - }.toMutableList() - if (allowScheduling && listener?.canSchedule() == true) { - items += ActionItem( - iconRes = R.drawable.symbol_calendar_24, - title = context.getString(R.string.conversation_activity__option_schedule_message), - action = { listener.onSendScheduled() } - ) - } - - SignalContextMenu.Builder((parent as View), popupContainer!!) - .preferredVerticalPosition(SignalContextMenu.VerticalPosition.ABOVE) - .offsetY(ViewUtil.dpToPx(8)) - .show(items) } interface ScheduledSendListener { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageSendType.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageSendType.kt index f4415ad435..b65a52a2c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageSendType.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/MessageSendType.kt @@ -1,21 +1,16 @@ package org.thoughtcrime.securesms.conversation -import android.Manifest import android.content.Context import android.os.Parcelable import androidx.annotation.ColorRes import androidx.annotation.DrawableRes import androidx.annotation.StringRes import kotlinx.parcelize.Parcelize -import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.CharacterCalculator import org.thoughtcrime.securesms.util.MmsCharacterCalculator import org.thoughtcrime.securesms.util.PushCharacterCalculator import org.thoughtcrime.securesms.util.SmsCharacterCalculator -import org.thoughtcrime.securesms.util.dualsim.SubscriptionInfoCompat -import org.thoughtcrime.securesms.util.dualsim.SubscriptionManagerCompat import java.lang.IllegalArgumentException /** @@ -51,10 +46,6 @@ sealed class MessageSendType( return characterCalculator.calculateCharacters(body) } - fun getSimSubscriptionIdOr(fallback: Int): Int { - return simSubscriptionId ?: fallback - } - open fun getTitle(context: Context): String { return context.getString(titleRes) } @@ -126,45 +117,14 @@ sealed class MessageSendType( } companion object { - - private val TAG = Log.tag(MessageSendType::class.java) - - /** - * Returns a list of all available [MessageSendType]s. Requires [Manifest.permission.READ_PHONE_STATE] in order to get available - * SMS options. - */ @JvmStatic - fun getAllAvailable(context: Context, isMedia: Boolean = false): List { - val options: MutableList = mutableListOf() - - options += SignalMessageSendType - - if (SignalStore.misc().smsExportPhase.allowSmsFeatures()) { - try { - val subscriptions: Collection = SubscriptionManagerCompat(context).activeAndReadySubscriptionInfos - - if (subscriptions.size < 2) { - options += if (isMedia) MmsMessageSendType() else SmsMessageSendType() - } else { - options += subscriptions.map { - if (isMedia) { - MmsMessageSendType(simName = it.displayName, simSubscriptionId = it.subscriptionId) - } else { - SmsMessageSendType(simName = it.displayName, simSubscriptionId = it.subscriptionId) - } - } - } - } catch (e: SecurityException) { - Log.w(TAG, "Did not have permission to get SMS subscription details!") - } - } - - return options + fun getAllAvailable(): List { + return listOf(SignalMessageSendType) } @JvmStatic - fun getFirstForTransport(context: Context, isMedia: Boolean, transportType: TransportType): MessageSendType { - return getAllAvailable(context, isMedia).firstOrNull { it.transportType == transportType } ?: throw IllegalArgumentException("No options available for desired type $transportType!") + fun getFirstForTransport(transportType: TransportType): MessageSendType { + return getAllAvailable().firstOrNull { it.transportType == transportType } ?: throw IllegalArgumentException("No options available for desired type $transportType!") } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/Multiselect.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/Multiselect.kt index 9895e250eb..8cb2bd8e3c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/Multiselect.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/Multiselect.kt @@ -84,7 +84,7 @@ object Multiselect { return false } - val sendType: MessageSendType = MessageSendType.getFirstForTransport(context, true, MessageSendType.TransportType.SMS) + val sendType: MessageSendType = MessageSendType.getFirstForTransport(MessageSendType.TransportType.SMS) val mmsConstraints = MediaConstraints.getMmsMediaConstraints(sendType.simSubscriptionId ?: -1) return mmsConstraints.isSatisfied(context, mediaUri, mediaType, mediaSize) || mmsConstraints.canResize(mediaType) @@ -107,7 +107,7 @@ object Multiselect { return false } - val sendType: MessageSendType = MessageSendType.getFirstForTransport(context, true, MessageSendType.TransportType.SMS) + val sendType: MessageSendType = MessageSendType.getFirstForTransport(MessageSendType.TransportType.SMS) val mmsConstraints = MediaConstraints.getMmsMediaConstraints(sendType.simSubscriptionId ?: -1) return mmsConstraints.isSatisfied(context, attachment) || mmsConstraints.canResize(attachment) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 1ed7497c5c..6705b83704 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -913,7 +913,6 @@ class ConversationFragment : setOnClickListener(sendButtonListener) setScheduledSendListener(sendButtonListener) isEnabled = true - sendButton.triggerSelectedChangedEvent() } sendEditButton.setOnClickListener { handleSendEditMessage() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareRepository.kt index b1ec65510b..791d5986ac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/v2/ShareRepository.kt @@ -191,7 +191,7 @@ class ShareRepository(context: Context) { return false } - val sendType: MessageSendType = MessageSendType.getFirstForTransport(context, true, MessageSendType.TransportType.SMS) + val sendType: MessageSendType = MessageSendType.getFirstForTransport(MessageSendType.TransportType.SMS) val mmsConstraints = MediaConstraints.getMmsMediaConstraints(sendType.simSubscriptionId ?: -1) return mmsConstraints.isSatisfied(context, attachment) || mmsConstraints.canResize(attachment) }