Fix various issues with release notes channel.

fork-5.53.8
Cody Henthorne 2022-02-11 10:12:09 -05:00 zatwierdzone przez GitHub
rodzic 90e6dd3d7d
commit 84296a3860
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
14 zmienionych plików z 75 dodań i 67 usunięć

Wyświetl plik

@ -1,9 +1,6 @@
package org.thoughtcrime.securesms.blocked;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -15,6 +12,7 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.RecyclerView;
import org.thoughtcrime.securesms.BlockUnblockDialog;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -74,24 +72,9 @@ public class BlockedUsersFragment extends Fragment {
}
private void handleRecipientClicked(@NonNull Recipient recipient) {
AlertDialog confirmationDialog = new AlertDialog.Builder(requireContext())
.setTitle(R.string.BlockedUsersActivity__unblock_user)
.setMessage(getString(R.string.BlockedUsersActivity__do_you_want_to_unblock_s, recipient.getDisplayName(requireContext())))
.setPositiveButton(R.string.BlockedUsersActivity__unblock, (dialog, which) -> {
viewModel.unblock(recipient.getId());
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
dialog.dismiss();
})
.setCancelable(true)
.create();
confirmationDialog.setOnShowListener(dialog -> {
confirmationDialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.RED);
BlockUnblockDialog.showUnblockFor(requireContext(), getViewLifecycleOwner().getLifecycle(), recipient, () -> {
viewModel.unblock(recipient.getId());
});
confirmationDialog.show();
}
interface Listener {

Wyświetl plik

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.settings.conversation.preferences
import android.content.ClipData
import android.content.Context
import android.text.SpannableStringBuilder
import android.view.View
import android.widget.TextView
import android.widget.Toast
@ -9,7 +10,9 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.PreferenceModel
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.ContextUtil
import org.thoughtcrime.securesms.util.ServiceUtil
import org.thoughtcrime.securesms.util.SpanUtil
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
@ -25,17 +28,25 @@ object BioTextPreference {
}
abstract class BioTextPreferenceModel<T : BioTextPreferenceModel<T>> : PreferenceModel<T>() {
abstract fun getHeadlineText(context: Context): String
abstract fun getHeadlineText(context: Context): CharSequence
abstract fun getSubhead1Text(context: Context): String?
abstract fun getSubhead2Text(): String?
abstract fun getCompoundDrawable(): Int
}
class RecipientModel(
private val recipient: Recipient,
) : BioTextPreferenceModel<RecipientModel>() {
override fun getHeadlineText(context: Context): String = recipient.getDisplayNameOrUsername(context)
override fun getHeadlineText(context: Context): CharSequence {
val name = recipient.getDisplayNameOrUsername(context)
return if (recipient.isReleaseNotes) {
SpannableStringBuilder(name).apply {
SpanUtil.appendCenteredImageSpan(this, ContextUtil.requireDrawable(context, R.drawable.ic_official_28), 28, 28)
}
} else {
name
}
}
override fun getSubhead1Text(context: Context): String? {
return if (recipient.isReleaseNotes) {
@ -47,10 +58,6 @@ object BioTextPreference {
override fun getSubhead2Text(): String? = recipient.e164.transform(PhoneNumberFormatter::prettyPrint).orNull()
override fun getCompoundDrawable(): Int {
return if (recipient.isReleaseNotes) R.drawable.ic_official_28 else 0
}
override fun areContentsTheSame(newItem: RecipientModel): Boolean {
return super.areContentsTheSame(newItem) && newItem.recipient.hasSameContent(recipient)
}
@ -64,14 +71,12 @@ object BioTextPreference {
val groupTitle: String,
val groupMembershipDescription: String?
) : BioTextPreferenceModel<GroupModel>() {
override fun getHeadlineText(context: Context): String = groupTitle
override fun getHeadlineText(context: Context): CharSequence = groupTitle
override fun getSubhead1Text(context: Context): String? = groupMembershipDescription
override fun getSubhead2Text(): String? = null
override fun getCompoundDrawable(): Int = 0
override fun areContentsTheSame(newItem: GroupModel): Boolean {
return super.areContentsTheSame(newItem) &&
groupTitle == newItem.groupTitle &&
@ -91,7 +96,6 @@ object BioTextPreference {
override fun bind(model: T) {
headline.text = model.getHeadlineText(context)
headline.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, model.getCompoundDrawable(), 0)
model.getSubhead1Text(context).let {
subhead1.text = it

Wyświetl plik

@ -6,17 +6,21 @@ import android.view.MotionEvent
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.Toolbar
import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
import org.thoughtcrime.securesms.PassphraseRequiredActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.HidingLinearLayout
import org.thoughtcrime.securesms.components.reminder.ReminderView
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
import org.thoughtcrime.securesms.util.DynamicTheme
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture
import org.thoughtcrime.securesms.util.views.Stub
open class ConversationActivity : PassphraseRequiredActivity(), ConversationParentFragment.Callback {
open class ConversationActivity : PassphraseRequiredActivity(), ConversationParentFragment.Callback, DonationPaymentComponent {
private lateinit var fragment: ConversationParentFragment
@ -73,4 +77,7 @@ open class ConversationActivity : PassphraseRequiredActivity(), ConversationPare
fun getReminderView(): Stub<ReminderView> {
return fragment.reminderView
}
override val donationPaymentRepository: DonationPaymentRepository by lazy { DonationPaymentRepository(this) }
override val googlePayResultPublisher: Subject<DonationPaymentComponent.GooglePayResult> = PublishSubject.create()
}

Wyświetl plik

@ -59,6 +59,7 @@ import androidx.core.view.ViewKt;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
@ -1857,7 +1858,12 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
@Override
public void onDonateClicked() {
if (SignalStore.donationsValues().isLikelyASustainer()) {
startActivity(AppSettingsActivity.boost(requireContext()));
NavHostFragment navHostFragment = NavHostFragment.create(R.navigation.boosts);
requireActivity().getSupportFragmentManager()
.beginTransaction()
.add(navHostFragment, "boost_nav")
.commitNow();
} else {
startActivity(AppSettingsActivity.subscriptions(requireContext()));
}

Wyświetl plik

@ -716,7 +716,7 @@ public final class ConversationReactionOverlay extends FrameLayout {
items.add(new ActionItem(R.drawable.ic_select_24_tinted, getResources().getString(R.string.conversation_selection__menu_multi_select), () -> handleActionItemClicked(Action.MULTISELECT)));
if (menuState.shouldShowInfoAction()) {
if (menuState.shouldShowDetailsAction()) {
items.add(new ActionItem(R.drawable.ic_info_tinted_24, getResources().getString(R.string.conversation_selection__menu_message_details), () -> handleActionItemClicked(Action.VIEW_INFO)));
}

Wyświetl plik

@ -22,7 +22,6 @@ final class MenuState {
private final boolean resend;
private final boolean copy;
private final boolean delete;
private final boolean info;
private final boolean reactions;
private MenuState(@NonNull Builder builder) {
@ -33,7 +32,6 @@ final class MenuState {
resend = builder.resend;
copy = builder.copy;
delete = builder.delete;
info = builder.info;
reactions = builder.reactions;
}
@ -65,10 +63,6 @@ final class MenuState {
return delete;
}
boolean shouldShowInfoAction() {
return info;
}
boolean shouldShowReactions() {
return reactions;
}
@ -154,13 +148,13 @@ final class MenuState {
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
.shouldShowForwardAction(shouldShowForwardAction)
.shouldShowDetailsAction(!actionMessage)
.shouldShowDetailsAction(!actionMessage && !conversationRecipient.isReleaseNotes())
.shouldShowReplyAction(canReplyToMessage(conversationRecipient, actionMessage, messageRecord, shouldShowMessageRequest, isNonAdminInAnnouncementGroup));
}
return builder.shouldShowCopyAction(!actionMessage && !remoteDelete && hasText)
.shouldShowDeleteAction(!hasInMemory && onlyContainsCompleteMessages(selectedParts))
.shouldShowInfoAction(!conversationRecipient.isReleaseNotes())
.shouldShowDetailsAction(!conversationRecipient.isReleaseNotes())
.shouldShowReactions(!conversationRecipient.isReleaseNotes())
.build();
}
@ -216,7 +210,6 @@ final class MenuState {
private boolean resend;
private boolean copy;
private boolean delete;
private boolean info;
private boolean reactions;
@NonNull Builder shouldShowForwardAction(boolean forward) {
@ -254,11 +247,6 @@ final class MenuState {
return this;
}
@NonNull Builder shouldShowInfoAction(boolean info) {
this.info = info;
return this;
}
@NonNull Builder shouldShowReactions(boolean reactions) {
this.reactions = reactions;
return this;

Wyświetl plik

@ -137,11 +137,13 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
val allReleaseNotes: ReleaseNotes? = S3.getAndVerifyObject(MANIFEST, ReleaseNotes::class.java, manifestMd5).result.orNull()
if (allReleaseNotes != null) {
val resolvedNotes: List<FullReleaseNote?> = allReleaseNotes.announcements
.filter { it.androidMinVersion.toIntOrNull()?.let { minVersion: Int -> minVersion > values.highestVersionNoteReceived && minVersion <= BuildConfig.CANONICAL_VERSION_CODE } ?: false }
val resolvedNotes: List<FullReleaseNote?> = allReleaseNotes.announcements.asSequence()
.filter { it.androidMinVersion != null }
.filter { it.androidMinVersion!!.toIntOrNull()?.let { minVersion: Int -> minVersion > values.highestVersionNoteReceived && minVersion <= BuildConfig.CANONICAL_VERSION_CODE } ?: false }
.filter { it.countries == null || LocaleFeatureFlags.shouldShowReleaseNote(it.uuid, it.countries) }
.sortedBy { it.androidMinVersion.toInt() }
.sortedBy { it.androidMinVersion!!.toInt() }
.map { resolveReleaseNote(it) }
.toList()
if (resolvedNotes.any { it == null }) {
Log.w(TAG, "Some release notes did not resolve, aborting.")
@ -174,7 +176,9 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
body = body,
threadId = threadId,
messageRanges = bodyRangeList.build(),
image = note.translation.image
image = note.translation.image,
imageWidth = note.translation.imageWidth?.toIntOrNull() ?: 0,
imageHeight = note.translation.imageHeight?.toIntOrNull() ?: 0
)
SignalDatabase.sms.insertBoostRequestMessage(values.releaseChannelRecipientId!!, threadId)
@ -186,7 +190,7 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.threadId)
TrimThreadJob.enqueueAsync(insertResult.threadId)
highestVersion = max(highestVersion, note.releaseNote.androidMinVersion.toInt())
highestVersion = max(highestVersion, note.releaseNote.androidMinVersion!!.toInt())
}
}
@ -242,7 +246,7 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
data class ReleaseNote(
@JsonProperty val uuid: String,
@JsonProperty val countries: String?,
@JsonProperty val androidMinVersion: String,
@JsonProperty val androidMinVersion: String?,
@JsonProperty val link: String?,
@JsonProperty val ctaId: String?
)
@ -250,6 +254,8 @@ class RetrieveReleaseChannelJob private constructor(private val force: Boolean,
data class TranslatedReleaseNote(
@JsonProperty val uuid: String,
@JsonProperty val image: String?,
@JsonProperty val imageWidth: String?,
@JsonProperty val imageHeight: String?,
@JsonProperty val linkText: String?,
@JsonProperty val title: String,
@JsonProperty val body: String,

Wyświetl plik

@ -4,7 +4,10 @@ import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@ -41,7 +44,9 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.BottomSheetUtil;
import org.thoughtcrime.securesms.util.ContextUtil;
import org.thoughtcrime.securesms.util.DrawableUtil;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.SpanUtil;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
@ -170,16 +175,16 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
String name = recipient.isSelf() ? requireContext().getString(R.string.note_to_self)
: recipient.getDisplayName(requireContext());
fullName.setText(name);
fullName.setVisibility(TextUtils.isEmpty(name) ? View.GONE : View.VISIBLE);
SpannableStringBuilder nameBuilder = new SpannableStringBuilder(name);
if (recipient.isSystemContact() && !recipient.isSelf()) {
fullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_profile_circle_outline_16, 0);
fullName.setCompoundDrawablePadding(ViewUtil.dpToPx(4));
TextViewCompat.setCompoundDrawableTintList(fullName, ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.signal_text_primary)));
Drawable systemContact = DrawableUtil.tint(ContextUtil.requireDrawable(requireContext(), R.drawable.ic_profile_circle_outline_16),
ContextCompat.getColor(requireContext(), R.color.signal_text_primary));
SpanUtil.appendCenteredImageSpan(nameBuilder, systemContact, 16, 16);
} else if (recipient.isReleaseNotes()) {
fullName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_official_28, 0);
fullName.setCompoundDrawablePadding(ViewUtil.dpToPx(4));
SpanUtil.appendCenteredImageSpan(nameBuilder, ContextUtil.requireDrawable(requireContext(), R.drawable.ic_official_28), 28, 28);
}
fullName.setText(nameBuilder);
String aboutText = recipient.getCombinedAboutAndEmoji();
if (recipient.isReleaseNotes()) {

Wyświetl plik

@ -24,6 +24,8 @@ object ReleaseChannel {
body: String,
threadId: Long,
image: String? = null,
imageWidth: Int = 0,
imageHeight: Int = 0,
serverUuid: String? = UUID.randomUUID().toString(),
messageRanges: BodyRangeList? = null
): MessageDatabase.InsertResult? {
@ -36,8 +38,8 @@ object ReleaseChannel {
null,
Optional.absent(),
Optional.absent(),
0,
0,
imageWidth,
imageHeight,
Optional.absent(),
Optional.of(image),
false,

Wyświetl plik

@ -127,6 +127,11 @@ public final class SpanUtil {
return imageSpan;
}
public static void appendCenteredImageSpan(@NonNull SpannableStringBuilder builder, @NonNull Drawable drawable, int width, int height) {
drawable.setBounds(0, 0, ViewUtil.dpToPx(width), ViewUtil.dpToPx(height));
builder.append(" ").append(SpanUtil.buildCenteredImageSpan(drawable));
}
public static CharSequence learnMore(@NonNull Context context,
@ColorInt int color,
@NonNull View.OnClickListener onLearnMoreClicked)

Wyświetl plik

@ -48,6 +48,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="4dp"
android:layout="@layout/conversation_item_update_donate" />
</LinearLayout>

Wyświetl plik

@ -7,15 +7,13 @@
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/bio_preference_headline"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="32dp"
android:drawablePadding="4dp"
android:gravity="center"
android:textAppearance="@style/Signal.Text.Headline.Medium"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

Wyświetl plik

@ -46,11 +46,12 @@
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/rbs_full_name"
style="@style/Signal.Text.Headline.Medium"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dsl_settings_gutter"
android:layout_marginTop="12dp"
android:layout_marginEnd="@dimen/dsl_settings_gutter"
android:gravity="center_horizontal"
android:textColor="@color/signal_text_primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"

Wyświetl plik

@ -466,7 +466,9 @@
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
app:popExitAnim="@anim/fragment_close_exit"
app:popUpTo="@id/app_settings"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_direct_to_manageDonations"