From 9a24455085f4b238ec49cddf9081395cc0c2d1c2 Mon Sep 17 00:00:00 2001 From: Nicholas Tinsley Date: Mon, 19 Aug 2024 13:45:53 -0400 Subject: [PATCH] Delete the reminders system. --- .../reminder/BubbleOptOutReminder.kt | 15 -- .../reminder/CdsPermanentErrorReminder.kt | 42 ---- .../reminder/CdsTemporaryErrorReminder.kt | 35 ---- .../components/reminder/DozeReminder.java | 41 ---- .../reminder/EnclaveFailureReminder.kt | 23 --- .../reminder/ExpiredBuildReminder.java | 34 ---- .../GroupsV1MigrationSuggestionsReminder.java | 48 ----- .../reminder/OutdatedBuildReminder.java | 48 ----- .../PendingGroupJoinRequestsReminder.java | 36 ---- .../components/reminder/Reminder.java | 119 ------------ .../reminder/ReminderActionsAdapter.java | 68 ------- .../components/reminder/ReminderView.java | 183 ------------------ .../reminder/ServiceOutageReminder.java | 30 --- .../reminder/UnauthorizedReminder.java | 31 --- .../reminder/UsernameOutOfSyncReminder.kt | 51 ----- .../settings/app/AppSettingsFragment.kt | 89 ++------- .../conversation/v2/ConversationBannerView.kt | 34 ---- .../conversation/v2/ConversationFragment.kt | 49 ++--- .../conversation/v2/ConversationRepository.kt | 40 ---- .../conversation/v2/ConversationViewModel.kt | 19 +- .../ConversationListFragment.java | 96 +-------- .../securesms/events/ReminderUpdateEvent.java | 5 - .../jobs/ServiceOutageDetectionJob.java | 4 - .../lock/SignalPinReminderDialog.java | 2 +- .../preferences/PaymentsHomeFragment.java | 39 +--- .../stories/landing/StoriesLandingFragment.kt | 85 ++------ .../securesms/util/RemoteConfig.kt | 9 - ...onversation_activity_reminderview_stub.xml | 8 - .../layout/conversation_list_banner_view.xml | 2 +- .../res/layout/conversation_list_fragment.xml | 12 +- .../conversation_list_reminder_view.xml | 10 - .../dsl_settings_fragment_with_reminder.xml | 8 - .../main/res/layout/kbs_pin_reminder_view.xml | 4 +- .../res/layout/payments_home_fragment.xml | 8 - .../res/layout/stories_landing_fragment.xml | 8 - .../layout/stories_landing_reminder_view.xml | 8 - .../res/layout/v2_conversation_fragment.xml | 7 - 37 files changed, 73 insertions(+), 1277 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/BubbleOptOutReminder.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsPermanentErrorReminder.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsTemporaryErrorReminder.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/EnclaveFailureReminder.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/GroupsV1MigrationSuggestionsReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/PendingGroupJoinRequestsReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/Reminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderActionsAdapter.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderView.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/UnauthorizedReminder.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/reminder/UsernameOutOfSyncReminder.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/events/ReminderUpdateEvent.java delete mode 100644 app/src/main/res/layout/conversation_activity_reminderview_stub.xml delete mode 100644 app/src/main/res/layout/conversation_list_reminder_view.xml delete mode 100644 app/src/main/res/layout/stories_landing_reminder_view.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/BubbleOptOutReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/BubbleOptOutReminder.kt deleted file mode 100644 index e377474c1d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/BubbleOptOutReminder.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder - -import org.thoughtcrime.securesms.R - -class BubbleOptOutReminder : Reminder(R.string.BubbleOptOutTooltip__description) { - - init { - addAction(Action(R.string.BubbleOptOutTooltip__turn_off, R.id.reminder_action_bubble_turn_off)) - addAction(Action(R.string.BubbleOptOutTooltip__not_now, R.id.reminder_action_bubble_not_now)) - } - - override fun isDismissable(): Boolean { - return false - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsPermanentErrorReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsPermanentErrorReminder.kt deleted file mode 100644 index 4b1e3193ad..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsPermanentErrorReminder.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder - -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.keyvalue.SignalStore -import kotlin.time.Duration.Companion.days - -/** - * Reminder shown when CDS is in a permanent error state, preventing us from doing a sync. - */ -class CdsPermanentErrorReminder : Reminder(R.string.reminder_cds_permanent_error_body) { - - init { - addAction( - Action( - R.string.reminder_cds_permanent_error_learn_more, - R.id.reminder_action_cds_permanent_error_learn_more - ) - ) - } - - override fun isDismissable(): Boolean { - return false - } - - override fun getImportance(): Importance { - return Importance.ERROR - } - - companion object { - /** - * Even if we're not truly "permanently blocked", if the time until we're unblocked is long enough, we'd rather show the permanent error message than - * telling the user to wait for 3 months or something. - */ - val PERMANENT_TIME_CUTOFF = 30.days.inWholeMilliseconds - - @JvmStatic - fun isEligible(): Boolean { - val timeUntilUnblock = SignalStore.misc.cdsBlockedUtil - System.currentTimeMillis() - return SignalStore.misc.isCdsBlocked && timeUntilUnblock >= PERMANENT_TIME_CUTOFF - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsTemporaryErrorReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsTemporaryErrorReminder.kt deleted file mode 100644 index d9a11dba03..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/CdsTemporaryErrorReminder.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder - -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.keyvalue.SignalStore - -/** - * Reminder shown when CDS is rate-limited, preventing us from temporarily doing a refresh. - */ -class CdsTemporaryErrorReminder : Reminder(R.string.reminder_cds_warning_body) { - - init { - addAction( - Action( - R.string.reminder_cds_warning_learn_more, - R.id.reminder_action_cds_temporary_error_learn_more - ) - ) - } - - override fun isDismissable(): Boolean { - return false - } - - override fun getImportance(): Importance { - return Importance.ERROR - } - - companion object { - @JvmStatic - fun isEligible(): Boolean { - val timeUntilUnblock = SignalStore.misc.cdsBlockedUtil - System.currentTimeMillis() - return SignalStore.misc.isCdsBlocked && timeUntilUnblock < CdsPermanentErrorReminder.PERMANENT_TIME_CUTOFF - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java deleted file mode 100644 index 6d5dcf3e1d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/DozeReminder.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.PowerManager; -import android.provider.Settings; - -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.PowerManagerCompat; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -@SuppressLint("BatteryLife") -public class DozeReminder extends Reminder { - - @RequiresApi(api = 23) - public DozeReminder(@NonNull final Context context) { - super(R.string.DozeReminder_optimize_for_missing_play_services, R.string.DozeReminder_this_device_does_not_support_play_services_tap_to_disable_system_battery); - - setOkListener(v -> { - TextSecurePreferences.setPromptedOptimizeDoze(context, true); - PowerManagerCompat.requestIgnoreBatteryOptimizations(context); - }); - - setDismissListener(v -> TextSecurePreferences.setPromptedOptimizeDoze(context, true)); - } - - public static boolean isEligible(Context context) { - return !SignalStore.account().isFcmEnabled() && - !TextSecurePreferences.hasPromptedOptimizeDoze(context) && - Build.VERSION.SDK_INT >= 23 && - !((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isIgnoringBatteryOptimizations(context.getPackageName()); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/EnclaveFailureReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/EnclaveFailureReminder.kt deleted file mode 100644 index 8244b7a62a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/EnclaveFailureReminder.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder - -import android.content.Context -import android.view.View -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.util.PlayStoreUtil - -/** - * Banner to update app to the latest version because of enclave failure - */ -class EnclaveFailureReminder(context: Context) : Reminder(R.string.EnclaveFailureReminder_update_signal) { - - init { - addAction(Action(R.string.ExpiredBuildReminder_update_now, R.id.reminder_action_update_now)) - okListener = View.OnClickListener { PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(context) } - } - - override fun isDismissable(): Boolean = false - - override fun getImportance(): Importance { - return Importance.TERMINAL - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java deleted file mode 100644 index 43d4657db0..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ExpiredBuildReminder.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.keyvalue.SignalStore; - -/** - * Showed when a build has fully expired (either via the compile-time constant, or remote - * deprecation). - */ -public class ExpiredBuildReminder extends Reminder { - - public ExpiredBuildReminder(final Context context) { - super(R.string.ExpiredBuildReminder_this_version_of_signal_has_expired); - addAction(new Action(R.string.ExpiredBuildReminder_update_now, R.id.reminder_action_update_now)); - } - - @Override - public boolean isDismissable() { - return false; - } - - @Override - public @NonNull Importance getImportance() { - return Importance.TERMINAL; - } - - public static boolean isEligible() { - return SignalStore.misc().isClientDeprecated(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/GroupsV1MigrationSuggestionsReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/GroupsV1MigrationSuggestionsReminder.java deleted file mode 100644 index 58582deb1a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/GroupsV1MigrationSuggestionsReminder.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.recipients.RecipientId; - -import java.util.List; - -/** - * Shows a reminder to add anyone that might have been missed in GV1->GV2 migration. - */ -public class GroupsV1MigrationSuggestionsReminder extends Reminder { - private final int suggestionsSize; - - public GroupsV1MigrationSuggestionsReminder(@NonNull List suggestions) { - this.suggestionsSize = suggestions.size(); - - addAction(new AddMembersAction(suggestionsSize)); - addAction(new Action(R.string.GroupsV1MigrationSuggestionsReminder_no_thanks, R.id.reminder_action_gv1_suggestion_no_thanks)); - } - - @Override - public @NonNull CharSequence getText(@NonNull Context context) { - return context.getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsReminder_members_couldnt_be_added_to_the_new_group, suggestionsSize, suggestionsSize); - } - - @Override - public boolean isDismissable() { - return false; - } - - private static class AddMembersAction extends Action { - private final int suggestionsSize; - - public AddMembersAction(int suggestionsSize) { - super(NO_RESOURCE, R.id.reminder_action_gv1_suggestion_add_members); - this.suggestionsSize = suggestionsSize; - } - - @Override - public CharSequence getTitle(@NonNull Context context) { - return context.getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsReminder_add_members, suggestionsSize); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java deleted file mode 100644 index d21b9f255a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/OutdatedBuildReminder.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.PlayStoreUtil; -import org.thoughtcrime.securesms.util.Util; - -import java.util.concurrent.TimeUnit; - -/** - * Reminder that is shown when a build is getting close to expiry (either because of the - * compile-time constant, or remote deprecation). - */ -public class OutdatedBuildReminder extends Reminder { - - public OutdatedBuildReminder(final Context context) { - setOkListener(v -> PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(context)); - addAction(new Action(R.string.OutdatedBuildReminder_update_now, R.id.reminder_action_update_now)); - } - - @Override - public @NonNull CharSequence getText(@NonNull Context context) { - int days = getDaysUntilExpiry(); - - if (days == 0) { - return context.getString(R.string.OutdatedBuildReminder_your_version_of_signal_will_expire_today); - } else { - return context.getResources().getQuantityString(R.plurals.OutdatedBuildReminder_your_version_of_signal_will_expire_in_n_days, days, days); - } - } - - @Override - public boolean isDismissable() { - return false; - } - - public static boolean isEligible() { - return getDaysUntilExpiry() <= 10; - } - - private static int getDaysUntilExpiry() { - return (int) TimeUnit.MILLISECONDS.toDays(Util.getTimeUntilBuildExpiry(SignalStore.misc().getEstimatedServerTime())); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/PendingGroupJoinRequestsReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/PendingGroupJoinRequestsReminder.java deleted file mode 100644 index ce85802b42..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/PendingGroupJoinRequestsReminder.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; - -/** - * Shown to admins when there are pending group join requests. - */ -public final class PendingGroupJoinRequestsReminder extends Reminder { - - private final int count; - - public PendingGroupJoinRequestsReminder(int count) { - this.count = count; - - addAction(new Action(R.string.PendingGroupJoinRequestsReminder_view, R.id.reminder_action_review_join_requests)); - } - - @Override - public @NonNull CharSequence getText(@NonNull Context context) { - return context.getResources().getQuantityString(R.plurals.PendingGroupJoinRequestsReminder_d_pending_member_requests, count, count); - } - - @Override - public boolean isDismissable() { - return true; - } - - @Override - public @NonNull Importance getImportance() { - return Importance.NORMAL; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/Reminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/Reminder.java deleted file mode 100644 index 83dde25e8a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/Reminder.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; -import android.view.View.OnClickListener; - -import androidx.annotation.IdRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; - -import org.whispersystems.signalservice.api.util.Preconditions; - -import java.util.LinkedList; -import java.util.List; - -public abstract class Reminder { - public static final int NO_RESOURCE = -1; - - private int title; - private int text; - - private OnClickListener okListener; - private OnClickListener dismissListener; - - private final List actions = new LinkedList<>(); - - /** - * For a reminder that wishes to generate it's own strings by overwriting - * {@link #getText(Context)} and {@link #getTitle(Context)} - */ - public Reminder() { - this(NO_RESOURCE, NO_RESOURCE); - } - - public Reminder(@StringRes int textRes) { - this(NO_RESOURCE, textRes); - } - - public Reminder(@StringRes int titleRes, @StringRes int textRes) { - this.title = titleRes; - this.text = textRes; - } - - public @Nullable CharSequence getTitle(@NonNull Context context) { - if (title == NO_RESOURCE) { - return null; - } - - return context.getString(title); - } - - public @NonNull CharSequence getText(@NonNull Context context) { - Preconditions.checkArgument(text != NO_RESOURCE); - return context.getString(text); - } - - public OnClickListener getOkListener() { - return okListener; - } - - public OnClickListener getDismissListener() { - return dismissListener; - } - - public void setOkListener(OnClickListener okListener) { - this.okListener = okListener; - } - - public void setDismissListener(OnClickListener dismissListener) { - this.dismissListener = dismissListener; - } - - public boolean isDismissable() { - return true; - } - - public @NonNull Importance getImportance() { - return Importance.NORMAL; - } - - protected void addAction(@NonNull Action action) { - actions.add(action); - } - - public List getActions() { - return actions; - } - - public int getProgress() { - return -1; - } - - public enum Importance { - NORMAL, ERROR, TERMINAL - } - - public static class Action { - private final int title; - private final int actionId; - - public Action(@IdRes int actionId) { - this(NO_RESOURCE, actionId); - } - - public Action(@StringRes int title, @IdRes int actionId) { - this.title = title; - this.actionId = actionId; - } - - public CharSequence getTitle(@NonNull Context context) { - Preconditions.checkArgument(title != NO_RESOURCE); - return context.getText(title); - } - - public int getActionId() { - return actionId; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderActionsAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderActionsAdapter.java deleted file mode 100644 index cb2a0baf50..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderActionsAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; - -import org.thoughtcrime.securesms.R; - -import java.util.Collections; -import java.util.List; - -final class ReminderActionsAdapter extends RecyclerView.Adapter { - - private final Reminder.Importance importance; - private final List actions; - private final ReminderView.OnActionClickListener actionClickListener; - - ReminderActionsAdapter(Reminder.Importance importance, List actions, ReminderView.OnActionClickListener actionClickListener) { - this.importance = importance; - this.actions = Collections.unmodifiableList(actions); - this.actionClickListener = actionClickListener; - } - - @NonNull - @Override - public ActionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - Context context = parent.getContext(); - TextView button = ((TextView) LayoutInflater.from(context).inflate(R.layout.reminder_action_button, parent, false)); - - if (importance == Reminder.Importance.NORMAL) { - button.setTextColor(ContextCompat.getColor(context, R.color.signal_colorPrimary)); - } else if (importance == Reminder.Importance.ERROR || importance == Reminder.Importance.TERMINAL) { - button.setTextColor(ContextCompat.getColor(context, R.color.signal_light_colorOnSurface)); - } - - return new ActionViewHolder(button); - } - - @Override - public void onBindViewHolder(@NonNull ActionViewHolder holder, int position) { - final Reminder.Action action = actions.get(position); - - ((Button) holder.itemView).setText(action.getTitle(holder.itemView.getContext())); - holder.itemView.setOnClickListener(v -> { - if (holder.getAdapterPosition() == RecyclerView.NO_POSITION) return; - - actionClickListener.onActionClick(action.getActionId()); - }); - } - - @Override - public int getItemCount() { - return actions.size(); - } - - final class ActionViewHolder extends RecyclerView.ViewHolder { - ActionViewHolder(@NonNull View itemView) { - super(itemView); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderView.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderView.java deleted file mode 100644 index d87b5aa8a7..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ReminderView.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.ProgressBar; -import android.widget.Space; -import android.widget.TextView; - -import androidx.annotation.IdRes; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.card.MaterialCardView; - -import org.signal.core.util.DimensionUnit; -import org.thoughtcrime.securesms.R; - -import java.util.List; - -/** - * View to display actionable reminders to the user - */ -public final class ReminderView extends FrameLayout { - private ProgressBar progressBar; - private TextView progressText; - private MaterialCardView container; - private ImageButton closeButton; - private TextView title; - private TextView text; - private OnDismissListener dismissListener; - private Space space; - private RecyclerView actionsRecycler; - private OnActionClickListener actionClickListener; - private OnHideListener onHideListener; - - public ReminderView(Context context) { - super(context); - initialize(); - } - - public ReminderView(Context context, AttributeSet attrs) { - super(context, attrs); - initialize(); - } - - public ReminderView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initialize(); - } - - private void initialize() { - LayoutInflater.from(getContext()).inflate(R.layout.reminder_header, this, true); - progressBar = findViewById(R.id.reminder_progress); - progressText = findViewById(R.id.reminder_progress_text); - container = findViewById(R.id.container); - closeButton = findViewById(R.id.cancel); - title = findViewById(R.id.reminder_title); - text = findViewById(R.id.reminder_text); - space = findViewById(R.id.reminder_space); - actionsRecycler = findViewById(R.id.reminder_actions); - } - - public void showReminder(final Reminder reminder) { - if (!TextUtils.isEmpty(reminder.getTitle(getContext()))) { - title.setText(reminder.getTitle(getContext())); - title.setVisibility(VISIBLE); - space.setVisibility(GONE); - } else { - title.setText(""); - title.setVisibility(GONE); - space.setVisibility(VISIBLE); - text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_colorOnSurface)); - } - - if (!reminder.isDismissable()) { - space.setVisibility(GONE); - } - - text.setText(reminder.getText(getContext())); - switch (reminder.getImportance()) { - case NORMAL: - title.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_colorOnSurface)); - text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_colorOnSurfaceVariant)); - break; - case ERROR: - case TERMINAL: - container.setStrokeWidth(0); - container.setCardBackgroundColor(ContextCompat.getColor(getContext(), R.color.reminder_background)); - title.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_light_colorOnSurface)); - text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_light_colorOnSurface)); - break; - default: - throw new IllegalStateException(); - } - - if (reminder.getOkListener() != null) { - setOnClickListener(reminder.getOkListener()); - } - - closeButton.setVisibility(reminder.isDismissable() ? View.VISIBLE : View.GONE); - closeButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - hide(); - if (reminder.getDismissListener() != null) reminder.getDismissListener().onClick(v); - if (dismissListener != null) dismissListener.onDismiss(); - } - }); - - if (reminder.getImportance() == Reminder.Importance.NORMAL) { - closeButton.setColorFilter(ContextCompat.getColor(getContext(), R.color.signal_colorOnSurfaceVariant)); - } - - int progress = reminder.getProgress(); - if (progress != -1) { - progressBar.setProgress(progress); - progressBar.setVisibility(VISIBLE); - progressText.setText(getContext().getString(R.string.reminder_header_progress, progress)); - progressText.setVisibility(VISIBLE); - } else { - progressBar.setVisibility(GONE); - progressText.setVisibility(GONE); - } - - List actions = reminder.getActions(); - if (actions.isEmpty()) { - text.setPadding(0, 0, 0, ((int) DimensionUnit.DP.toPixels(16f))); - actionsRecycler.setVisibility(GONE); - } else { - text.setPadding(0, 0, 0, 0); - actionsRecycler.setVisibility(VISIBLE); - actionsRecycler.setAdapter(new ReminderActionsAdapter(reminder.getImportance(), actions, this::handleActionClicked)); - } - - container.setVisibility(View.VISIBLE); - } - - private void handleActionClicked(@IdRes int actionId) { - if (actionClickListener != null) actionClickListener.onActionClick(actionId); - } - - public void setOnDismissListener(OnDismissListener dismissListener) { - this.dismissListener = dismissListener; - } - - public void setOnActionClickListener(@Nullable OnActionClickListener actionClickListener) { - this.actionClickListener = actionClickListener; - } - - public void setOnHideListener(@Nullable OnHideListener onHideListener) { - this.onHideListener = onHideListener; - } - - public void requestDismiss() { - closeButton.performClick(); - } - - public void hide() { - if (onHideListener != null && onHideListener.onHide()) { - return; - } - - container.setVisibility(View.GONE); - } - - public interface OnDismissListener { - void onDismiss(); - } - - public interface OnActionClickListener { - void onActionClick(@IdRes int actionId); - } - - public interface OnHideListener { - boolean onHide(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java deleted file mode 100644 index 6accba6108..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/ServiceOutageReminder.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -public class ServiceOutageReminder extends Reminder { - - public ServiceOutageReminder() { - super(R.string.reminder_header_service_outage_text); - } - - public static boolean isEligible(@NonNull Context context) { - return TextSecurePreferences.getServiceOutage(context); - } - - @Override - public boolean isDismissable() { - return false; - } - - @NonNull - @Override - public Importance getImportance() { - return Importance.ERROR; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UnauthorizedReminder.java b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UnauthorizedReminder.java deleted file mode 100644 index 307daa4024..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UnauthorizedReminder.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -public class UnauthorizedReminder extends Reminder { - - public UnauthorizedReminder() { - super(R.string.UnauthorizedReminder_this_is_likely_because_you_registered_your_phone_number_with_Signal_on_a_different_device); - addAction(new Action(R.string.UnauthorizedReminder_reregister_action, R.id.reminder_action_re_register)); - } - - @Override - public boolean isDismissable() { - return false; - } - - @Override - public @NonNull Importance getImportance() { - return Importance.ERROR; - } - - public static boolean isEligible(Context context) { - return TextSecurePreferences.isUnauthorizedReceived(context) || !SignalStore.account().isRegistered(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UsernameOutOfSyncReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UsernameOutOfSyncReminder.kt deleted file mode 100644 index ff61af3915..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/reminder/UsernameOutOfSyncReminder.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.thoughtcrime.securesms.components.reminder - -import android.content.Context -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.keyvalue.AccountValues.UsernameSyncState -import org.thoughtcrime.securesms.keyvalue.SignalStore - -/** - * Displays a reminder message when the local username gets out of sync with - * what the server thinks our username is. - */ -class UsernameOutOfSyncReminder : Reminder(NO_RESOURCE) { - - init { - val action = if (SignalStore.account.usernameSyncState == UsernameSyncState.USERNAME_AND_LINK_CORRUPTED) { - R.id.reminder_action_fix_username_and_link - } else { - R.id.reminder_action_fix_username_link - } - - addAction( - Action( - R.string.UsernameOutOfSyncReminder__fix_now, - action - ) - ) - } - - override fun getText(context: Context): CharSequence { - return if (SignalStore.account.usernameSyncState == UsernameSyncState.USERNAME_AND_LINK_CORRUPTED) { - context.getString(R.string.UsernameOutOfSyncReminder__username_and_link_corrupt) - } else { - context.getString(R.string.UsernameOutOfSyncReminder__link_corrupt) - } - } - - override fun isDismissable(): Boolean { - return false - } - - companion object { - @JvmStatic - fun isEligible(): Boolean { - return when (SignalStore.account.usernameSyncState) { - UsernameSyncState.USERNAME_AND_LINK_CORRUPTED -> true - UsernameSyncState.LINK_CORRUPTED -> true - UsernameSyncState.IN_SYNC -> false - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt index 6dc05eec9a..8fab7f547a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.View import android.widget.TextView import android.widget.Toast -import androidx.annotation.IdRes import androidx.annotation.StringRes import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.viewModels @@ -13,9 +12,6 @@ import androidx.navigation.fragment.findNavController import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import org.signal.core.util.isNotNullOrBlank import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.badges.BadgeImageView @@ -24,10 +20,6 @@ import org.thoughtcrime.securesms.banner.banners.OutdatedBuildBanner import org.thoughtcrime.securesms.banner.banners.UnauthorizedBanner import org.thoughtcrime.securesms.components.AvatarImageView import org.thoughtcrime.securesms.components.emoji.EmojiTextView -import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder -import org.thoughtcrime.securesms.components.reminder.Reminder -import org.thoughtcrime.securesms.components.reminder.ReminderView -import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon @@ -38,13 +30,10 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaym import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord -import org.thoughtcrime.securesms.events.ReminderUpdateEvent import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter import org.thoughtcrime.securesms.recipients.Recipient -import org.thoughtcrime.securesms.registration.ui.RegistrationActivity import org.thoughtcrime.securesms.util.Environment -import org.thoughtcrime.securesms.util.PlayStoreUtil import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.ViewUtil @@ -62,17 +51,15 @@ class AppSettingsFragment : DSLSettingsFragment( private val viewModel: AppSettingsViewModel by viewModels() - private lateinit var reminderView: Stub private lateinit var bannerView: Stub override fun onViewCreated(view: View, savedInstanceState: Bundle?) { viewLifecycleOwner.lifecycle.addObserver(InAppPaymentsBottomSheetDelegate(childFragmentManager, viewLifecycleOwner)) super.onViewCreated(view, savedInstanceState) - reminderView = ViewUtil.findStubById(view, R.id.reminder_stub) bannerView = ViewUtil.findStubById(view, R.id.banner_stub) - updateReminders() + updateBanners() } override fun bindAdapter(adapter: MappingAdapter) { @@ -85,69 +72,31 @@ class AppSettingsFragment : DSLSettingsFragment( } } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onEvent(event: ReminderUpdateEvent?) { - updateReminders() - } - - private fun updateReminders() { - if (RemoteConfig.newBannerUi) { - val bannerFlows = listOf( - OutdatedBuildBanner.createFlow(requireContext(), OutdatedBuildBanner.ExpiryStatus.EXPIRED_ONLY), - UnauthorizedBanner.createFlow(requireContext()) - ) - val bannerManager = BannerManager(bannerFlows) - bannerManager.setContent(bannerView.get()) - } else { - if (ExpiredBuildReminder.isEligible()) { - showReminder(ExpiredBuildReminder(context)) - } else if (UnauthorizedReminder.isEligible(context)) { - showReminder(UnauthorizedReminder()) - } else { - hideReminders() + private fun updateBanners() { + val bannerFlows = listOf( + OutdatedBuildBanner.createFlow(requireContext(), OutdatedBuildBanner.ExpiryStatus.EXPIRED_ONLY), + UnauthorizedBanner.createFlow(requireContext()) + ) + val bannerManager = BannerManager(bannerFlows, + onNewBannerShownListener = { + if (bannerView.resolved()) { + bannerView.get().addOnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ -> + recyclerView?.setPadding(0, bottom - top, 0, 0) + } + recyclerView?.clipToPadding = false + } + }, + onNoBannerShownListener = { + recyclerView?.clipToPadding = true } - } + ) + bannerManager.setContent(bannerView.get()) viewModel.refreshDeprecatedOrUnregistered() } - private fun showReminder(reminder: Reminder) { - if (!reminderView.resolved()) { - reminderView.get().addOnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ -> - recyclerView?.setPadding(0, bottom - top, 0, 0) - } - recyclerView?.clipToPadding = false - } - reminderView.get().showReminder(reminder) - reminderView.get().setOnActionClickListener { reminderActionId: Int -> this.handleReminderAction(reminderActionId) } - } - - private fun hideReminders() { - if (reminderView.resolved()) { - reminderView.get().hide() - recyclerView?.clipToPadding = true - } - } - - private fun handleReminderAction(@IdRes reminderActionId: Int) { - when (reminderActionId) { - R.id.reminder_action_update_now -> { - PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext()) - } - R.id.reminder_action_re_register -> { - startActivity(RegistrationActivity.newIntentForReRegistration(requireContext())) - } - } - } - override fun onResume() { super.onResume() viewModel.refreshExpiredGiftBadge() - EventBus.getDefault().register(this) - } - - override fun onPause() { - super.onPause() - EventBus.getDefault().unregister(this) } private fun getConfiguration(state: AppSettingsState): DSLConfiguration { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationBannerView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationBannerView.kt index f7b00277eb..21e63c6957 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationBannerView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationBannerView.kt @@ -21,8 +21,6 @@ import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.banner.Banner import org.thoughtcrime.securesms.banner.BannerManager import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView -import org.thoughtcrime.securesms.components.reminder.Reminder -import org.thoughtcrime.securesms.components.reminder.ReminderView import org.thoughtcrime.securesms.components.voice.VoiceNotePlayerView import org.thoughtcrime.securesms.database.identity.IdentityRecordList import org.thoughtcrime.securesms.database.model.IdentityRecord @@ -50,7 +48,6 @@ class ConversationBannerView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : LinearLayoutCompat(context, attrs, defStyleAttr) { private val unverifiedBannerStub: Stub by lazy { ViewUtil.findStubById(this, R.id.unverified_banner_stub) } - private val reminderStub: Stub by lazy { ViewUtil.findStubById(this, R.id.reminder_stub) } private val bannerStub: Stub by lazy { ViewUtil.findStubById(this, R.id.banner_stub) } private val reviewBannerStub: Stub by lazy { ViewUtil.findStubById(this, R.id.review_banner_stub) } private val voiceNotePlayerStub: Stub by lazy { ViewUtil.findStubById(this, R.id.voice_note_player_stub) } @@ -68,33 +65,6 @@ class ConversationBannerView @JvmOverloads constructor( } } - fun showReminder(reminder: Reminder) { - show( - stub = reminderStub - ) { - showReminder(reminder) - setOnActionClickListener { - when (it) { - R.id.reminder_action_update_now -> listener?.updateAppAction() - R.id.reminder_action_re_register -> listener?.reRegisterAction() - R.id.reminder_action_review_join_requests -> listener?.reviewJoinRequestsAction() - R.id.reminder_action_gv1_suggestion_no_thanks -> listener?.gv1SuggestionsAction(it) - R.id.reminder_action_bubble_not_now, R.id.reminder_action_bubble_turn_off -> { - listener?.changeBubbleSettingAction(disableSetting = it == R.id.reminder_action_bubble_turn_off) - } - } - } - setOnHideListener { - clearReminder() - true - } - } - } - - fun clearReminder() { - hide(reminderStub) - } - fun showUnverifiedBanner(identityRecords: IdentityRecordList) { show( stub = unverifiedBannerStub @@ -169,10 +139,6 @@ class ConversationBannerView @JvmOverloads constructor( val slideTransition = Slide(Gravity.TOP) val changeTransition = ChangeBounds().apply { - if (reminderStub.isVisible) { - addTarget(reminderStub.get()) - } - if (unverifiedBannerStub.isVisible) { addTarget(unverifiedBannerStub.get()) } 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 5612131f31..6c22ed092c 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 @@ -210,7 +210,6 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList import org.thoughtcrime.securesms.databinding.V2ConversationFragmentBinding import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.events.GroupCallPeekEvent -import org.thoughtcrime.securesms.events.ReminderUpdateEvent import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ItemDecoration import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackController import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy @@ -228,7 +227,6 @@ import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationInfoBotto import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationSuggestionsDialog import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult import org.thoughtcrime.securesms.invites.InviteActions -import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob import org.thoughtcrime.securesms.keyboard.KeyboardPage import org.thoughtcrime.securesms.keyboard.KeyboardPagerFragment import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel @@ -1020,35 +1018,25 @@ class ConversationFragment : val conversationBannerListener = ConversationBannerListener() binding.conversationBanner.listener = conversationBannerListener - if (RemoteConfig.newBannerUi) { - val serviceOutageObserver = ServiceOutageObserver(requireContext()) - val bannerFlows = viewModel.getBannerFlows( - context = requireContext(), - serviceOutageStatusFlow = serviceOutageObserver.flow, - groupJoinClickListener = conversationBannerListener::reviewJoinRequestsAction, - onAddMembers = { - conversationGroupViewModel.groupRecordSnapshot?.let { groupRecord -> - GroupsV1MigrationSuggestionsDialog.show(requireActivity(), groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) - } - }, - onNoThanks = conversationGroupViewModel::onSuggestedMembersBannerDismissed, - bubbleClickListener = conversationBannerListener::changeBubbleSettingAction - ) + val serviceOutageObserver = ServiceOutageObserver(requireContext()) - binding.conversationBanner.collectAndShowBanners(bannerFlows) - } else { - viewModel - .reminder - .subscribeBy { reminder -> - if (reminder.isPresent) { - binding.conversationBanner.showReminder(reminder.get()) - } else { - binding.conversationBanner.clearReminder() - } + lifecycle.addObserver(serviceOutageObserver) + + val bannerFlows = viewModel.getBannerFlows( + context = requireContext(), + serviceOutageStatusFlow = serviceOutageObserver.flow, + groupJoinClickListener = conversationBannerListener::reviewJoinRequestsAction, + onAddMembers = { + conversationGroupViewModel.groupRecordSnapshot?.let { groupRecord -> + GroupsV1MigrationSuggestionsDialog.show(requireActivity(), groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) } - .addTo(disposables) - } + }, + onNoThanks = conversationGroupViewModel::onSuggestedMembersBannerDismissed, + bubbleClickListener = conversationBannerListener::changeBubbleSettingAction + ) + + binding.conversationBanner.collectAndShowBanners(bannerFlows) viewModel .identityRecordsObservable @@ -4287,11 +4275,6 @@ class ConversationFragment : groupCallViewModel.onGroupCallPeekEvent(groupCallPeekEvent) } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onReminderUpdateEvent(reminderUpdateEvent: ReminderUpdateEvent) { - viewModel.refreshReminder() - } - @Subscribe(threadMode = ThreadMode.MAIN) fun onRecaptchaRequiredEvent(recaptchaRequiredEvent: RecaptchaRequiredEvent) { RecaptchaProofBottomSheetFragment.show(childFragmentManager) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt index 62b2e42847..888c1fa820 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt @@ -30,7 +30,6 @@ import org.signal.core.util.concurrent.MaybeCompat import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.dp import org.signal.core.util.logging.Log -import org.signal.core.util.toOptional import org.signal.paging.PagedData import org.signal.paging.PagingConfig import org.thoughtcrime.securesms.R @@ -38,13 +37,6 @@ import org.thoughtcrime.securesms.ShortcutLauncherActivity import org.thoughtcrime.securesms.attachments.TombstoneAttachment import org.thoughtcrime.securesms.avatar.fallback.FallbackAvatarDrawable import org.thoughtcrime.securesms.components.emoji.EmojiStrings -import org.thoughtcrime.securesms.components.reminder.BubbleOptOutReminder -import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder -import org.thoughtcrime.securesms.components.reminder.GroupsV1MigrationSuggestionsReminder -import org.thoughtcrime.securesms.components.reminder.PendingGroupJoinRequestsReminder -import org.thoughtcrime.securesms.components.reminder.Reminder -import org.thoughtcrime.securesms.components.reminder.ServiceOutageReminder -import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.contactshare.ContactUtil import org.thoughtcrime.securesms.conversation.ConversationMessage @@ -74,9 +66,7 @@ import org.thoughtcrime.securesms.database.model.StickerRecord import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob -import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob import org.thoughtcrime.securesms.keyboard.KeyboardUtil -import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.messagerequests.MessageRequestState import org.thoughtcrime.securesms.mms.OutgoingMessage @@ -101,7 +91,6 @@ import org.thoughtcrime.securesms.util.hasTextSlide import org.thoughtcrime.securesms.util.isViewOnceMessage import org.thoughtcrime.securesms.util.requireTextSlide import java.io.IOException -import java.util.Optional import kotlin.math.max import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @@ -303,35 +292,6 @@ class ConversationRepository( return SignalDatabase.messages.getUnreadMentionCount(threadId) } - fun getReminder(groupRecord: GroupRecord?): Maybe> { - return Maybe.fromCallable { - val reminder: Reminder? = when { - ExpiredBuildReminder.isEligible() -> ExpiredBuildReminder(applicationContext) - UnauthorizedReminder.isEligible(applicationContext) -> UnauthorizedReminder() - ServiceOutageReminder.isEligible(applicationContext) -> { - AppDependencies.jobManager.add(ServiceOutageDetectionJob()) - ServiceOutageReminder() - } - - groupRecord != null && groupRecord.actionableRequestingMembersCount > 0 -> { - PendingGroupJoinRequestsReminder(groupRecord.actionableRequestingMembersCount) - } - - groupRecord != null && groupRecord.gv1MigrationSuggestions.isNotEmpty() -> { - GroupsV1MigrationSuggestionsReminder(groupRecord.gv1MigrationSuggestions) - } - - isInBubble && !SignalStore.tooltips.hasSeenBubbleOptOutTooltip() && Build.VERSION.SDK_INT > 29 -> { - BubbleOptOutReminder() - } - - else -> null - } - - reminder.toOptional() - } - } - @Suppress("IfThenToElvis") fun getIdentityRecords(recipient: Recipient, groupRecord: GroupRecord?): Single { return Single.fromCallable { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index c2fc12e327..21ddc4dc9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -36,7 +36,6 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.merge import kotlinx.coroutines.rx3.asFlow -import org.signal.core.util.concurrent.subscribeWithSubject import org.signal.core.util.orNull import org.signal.paging.ProxyPagingController import org.thoughtcrime.securesms.banner.Banner @@ -46,7 +45,6 @@ import org.thoughtcrime.securesms.banner.banners.OutdatedBuildBanner import org.thoughtcrime.securesms.banner.banners.PendingGroupJoinRequestsBanner import org.thoughtcrime.securesms.banner.banners.ServiceOutageBanner import org.thoughtcrime.securesms.banner.banners.UnauthorizedBanner -import org.thoughtcrime.securesms.components.reminder.Reminder import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.conversation.ConversationMessage import org.thoughtcrime.securesms.conversation.ScheduledMessagesRepository @@ -87,7 +85,6 @@ import org.thoughtcrime.securesms.util.hasGiftBadge import org.thoughtcrime.securesms.util.rx.RxStore import org.thoughtcrime.securesms.wallpaper.ChatWallpaper import org.whispersystems.signalservice.api.push.ServiceId -import java.util.Optional import java.util.concurrent.TimeUnit import kotlin.time.Duration @@ -96,7 +93,7 @@ import kotlin.time.Duration */ class ConversationViewModel( val threadId: Long, - private val requestedStartingPosition: Int, + requestedStartingPosition: Int, initialChatColors: ChatColors, private val repository: ConversationRepository, recipientRepository: ConversationRecipientRepository, @@ -167,9 +164,6 @@ class ConversationViewModel( val messageRequestState: MessageRequestState get() = hasMessageRequestStateSubject.value ?: MessageRequestState() - private val refreshReminder: Subject = PublishSubject.create() - val reminder: Observable> - private val groupRecordFlow: Flow private val refreshIdentityRecords: Subject = PublishSubject.create() @@ -286,13 +280,6 @@ class ConversationViewModel( } inputReadyState = _inputReadyState.observeOn(AndroidSchedulers.mainThread()) - recipientRepository.conversationRecipient.map { Unit }.subscribeWithSubject(refreshReminder, disposables) - - reminder = Observable.combineLatest(refreshReminder.startWithItem(Unit), recipientRepository.groupRecord) { _, groupRecord -> groupRecord } - .subscribeOn(Schedulers.io()) - .flatMapMaybe { groupRecord -> repository.getReminder(groupRecord.orNull()) } - .observeOn(AndroidSchedulers.mainThread()) - groupRecordFlow = recipientRepository.groupRecord .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -356,10 +343,6 @@ class ConversationViewModel( _searchQuery.onNext(query ?: "") } - fun refreshReminder() { - refreshReminder.onNext(Unit) - } - fun onDismissReview() { val recipientId = recipientSnapshot?.id ?: return repository.dismissRequestReviewState(recipientId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index bae39f5907..f4e9bb6730 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -46,7 +46,6 @@ import android.widget.Toast; import androidx.activity.OnBackPressedCallback; import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; -import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.PluralsRes; @@ -113,16 +112,6 @@ import org.thoughtcrime.securesms.components.menu.ActionItem; import org.thoughtcrime.securesms.components.menu.SignalBottomActionBar; import org.thoughtcrime.securesms.components.menu.SignalContextMenu; import org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton; -import org.thoughtcrime.securesms.components.reminder.CdsPermanentErrorReminder; -import org.thoughtcrime.securesms.components.reminder.CdsTemporaryErrorReminder; -import org.thoughtcrime.securesms.components.reminder.DozeReminder; -import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder; -import org.thoughtcrime.securesms.components.reminder.OutdatedBuildReminder; -import org.thoughtcrime.securesms.components.reminder.Reminder; -import org.thoughtcrime.securesms.components.reminder.ReminderView; -import org.thoughtcrime.securesms.components.reminder.ServiceOutageReminder; -import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder; -import org.thoughtcrime.securesms.components.reminder.UsernameOutOfSyncReminder; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment; import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate; @@ -136,8 +125,6 @@ import org.thoughtcrime.securesms.contacts.paged.ContactSearchData; import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey; import org.thoughtcrime.securesms.contacts.paged.ContactSearchMediator; import org.thoughtcrime.securesms.contacts.paged.ContactSearchState; -import org.thoughtcrime.securesms.contacts.sync.CdsPermanentErrorBottomSheet; -import org.thoughtcrime.securesms.contacts.sync.CdsTemporaryErrorBottomSheet; import org.thoughtcrime.securesms.conversationlist.chatfilter.ConversationFilterRequest; import org.thoughtcrime.securesms.conversationlist.chatfilter.ConversationFilterSource; import org.thoughtcrime.securesms.conversationlist.chatfilter.ConversationListFilterPullView; @@ -149,10 +136,8 @@ import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadTable; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.dependencies.AppDependencies; -import org.thoughtcrime.securesms.events.ReminderUpdateEvent; import org.thoughtcrime.securesms.groups.SelectionLimits; import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob; -import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.lock.v2.CreateSvrPinActivity; import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder; @@ -170,7 +155,6 @@ import org.thoughtcrime.securesms.profiles.manage.UsernameEditFragment; import org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.registration.ui.RegistrationActivity; import org.thoughtcrime.securesms.search.MessageResult; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.sms.MessageSender; @@ -181,8 +165,6 @@ import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.AppStartup; import org.thoughtcrime.securesms.util.CachedInflater; import org.thoughtcrime.securesms.util.ConversationUtil; -import org.thoughtcrime.securesms.util.PlayStoreUtil; -import org.thoughtcrime.securesms.util.RemoteConfig; import org.thoughtcrime.securesms.util.ServiceOutageObserver; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.SignalLocalMetrics; @@ -206,12 +188,10 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import kotlin.Unit; -import kotlin.jvm.functions.Function1; import kotlinx.coroutines.flow.Flow; import static android.app.Activity.RESULT_OK; @@ -237,7 +217,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode private ActionMode actionMode; private View coordinator; private RecyclerView list; - private Stub reminderView; private Stub bannerView; private PulsingFloatingActionButton fab; private PulsingFloatingActionButton cameraFab; @@ -302,7 +281,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode coordinator = view.findViewById(R.id.coordinator); list = view.findViewById(R.id.list); bottomActionBar = view.findViewById(R.id.conversation_list_bottom_action_bar); - reminderView = new Stub<>(view.findViewById(R.id.reminder)); bannerView = new Stub<>(view.findViewById(R.id.banner_compose_view)); megaphoneContainer = new Stub<>(view.findViewById(R.id.megaphone_container)); voiceNotePlayerViewStub = new Stub<>(view.findViewById(R.id.voice_note_player)); @@ -431,10 +409,8 @@ public class ConversationListFragment extends MainFragment implements ActionMode initializeListAdapters(); initializeTypingObserver(); initializeVoiceNotePlayer(); - if (RemoteConfig.newBannerUi()) { - initializeBanners(); - maybeScheduleRefreshProfileJob(); - } + initializeBanners(); + maybeScheduleRefreshProfileJob(); RatingManager.showRatingDialogIfNecessary(requireContext()); @@ -473,7 +449,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode coordinator = null; list = null; bottomActionBar = null; - reminderView = null; megaphoneContainer = null; voiceNotePlayerViewStub = null; fab = null; @@ -493,7 +468,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode super.onResume(); initializeSearchListener(); - updateReminders(); EventBus.getDefault().register(this); itemAnimator.disable(); SpoilerAnnotation.resetRevealedSpoilers(); @@ -800,27 +774,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode dialogFragment.show(getChildFragmentManager(), "megaphone_dialog"); } - private void initializeReminderView() { - reminderView.get().setOnDismissListener(this::updateReminders); - reminderView.get().setOnActionClickListener(this::onReminderAction); - } - - private void onReminderAction(@IdRes int reminderActionId) { - if (reminderActionId == R.id.reminder_action_update_now) { - PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext()); - } else if (reminderActionId == R.id.reminder_action_cds_temporary_error_learn_more) { - CdsTemporaryErrorBottomSheet.show(getChildFragmentManager()); - } else if (reminderActionId == R.id.reminder_action_cds_permanent_error_learn_more) { - CdsPermanentErrorBottomSheet.show(getChildFragmentManager()); - } else if (reminderActionId == R.id.reminder_action_fix_username_and_link) { - startActivityForResult(AppSettingsActivity.usernameRecovery(requireContext()), UsernameEditFragment.REQUEST_CODE); - } else if (reminderActionId == R.id.reminder_action_fix_username_link) { - startActivity(AppSettingsActivity.usernameLinkSettings(requireContext())); - } else if (reminderActionId == R.id.reminder_action_re_register) { - startActivity(RegistrationActivity.newIntentForReRegistration(requireContext())); - } - } - private void hideKeyboard() { InputMethodManager imm = ServiceUtil.getInputMethodManager(requireContext()); imm.hideSoftInputFromWindow(requireView().getWindowToken(), 0); @@ -1094,46 +1047,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode viewModel.onMegaphoneVisible(megaphone); } - private void updateReminders() { - if (RemoteConfig.newBannerUi()) { - return; - } - Context context = requireContext(); - - SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - if (ExpiredBuildReminder.isEligible()) { - return Optional.of(new ExpiredBuildReminder(context)); - } else if (UnauthorizedReminder.isEligible(context)) { - return Optional.of(new UnauthorizedReminder()); - } else if (ServiceOutageReminder.isEligible(context)) { - AppDependencies.getJobManager().add(new ServiceOutageDetectionJob()); - return Optional.of(new ServiceOutageReminder()); - } else if (OutdatedBuildReminder.isEligible()) { - return Optional.of(new OutdatedBuildReminder(context)); - } else if (DozeReminder.isEligible(context)) { - return Optional.of(new DozeReminder(context)); - } else if (CdsTemporaryErrorReminder.isEligible()) { - return Optional.of(new CdsTemporaryErrorReminder()); - } else if (CdsPermanentErrorReminder.isEligible()) { - return Optional.of(new CdsPermanentErrorReminder()); - } else if (UsernameOutOfSyncReminder.isEligible()) { - AppDependencies.getJobManager().add(new RefreshOwnProfileJob()); - return Optional.of(new UsernameOutOfSyncReminder()); - } else { - return Optional.empty(); - } - }, reminder -> { - if (reminder.isPresent() && getActivity() != null && !isRemoving()) { - if (!reminderView.resolved()) { - initializeReminderView(); - } - reminderView.get().showReminder(reminder.get()); - } else if (reminderView.resolved() && !reminder.isPresent()) { - reminderView.get().hide(); - } - }); - } - private void handleCreateGroup() { getNavigator().goToGroupCreation(); } @@ -1578,11 +1491,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode endActionModeIfActive(); } - @Subscribe(threadMode = ThreadMode.MAIN) - public void onEvent(ReminderUpdateEvent event) { - updateReminders(); - } - @Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void onEvent(MessageSender.MessageSentEvent event) { EventBus.getDefault().removeStickyEvent(event); diff --git a/app/src/main/java/org/thoughtcrime/securesms/events/ReminderUpdateEvent.java b/app/src/main/java/org/thoughtcrime/securesms/events/ReminderUpdateEvent.java deleted file mode 100644 index 582143a1c9..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/events/ReminderUpdateEvent.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.thoughtcrime.securesms.events; - - -public class ReminderUpdateEvent { -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java index f2ee8ec6d6..53d0699144 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java @@ -3,10 +3,8 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.greenrobot.eventbus.EventBus; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; -import org.thoughtcrime.securesms.events.ReminderUpdateEvent; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.transport.RetryLaterException; @@ -74,7 +72,6 @@ public class ServiceOutageDetectionJob extends BaseJob { } TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis()); - EventBus.getDefault().post(new ReminderUpdateEvent()); } catch (UnknownHostException e) { throw new RetryLaterException(e); } @@ -90,7 +87,6 @@ public class ServiceOutageDetectionJob extends BaseJob { Log.i(TAG, "Service status check could not complete. Assuming success to avoid false positives due to bad network."); TextSecurePreferences.setServiceOutage(context, false); TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis()); - EventBus.getDefault().post(new ReminderUpdateEvent()); } public static final class Factory implements Job.Factory { diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java b/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java index db4f4f6233..1ab16ed8b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java @@ -66,7 +66,7 @@ public final class SignalPinReminderDialog { EditText pinEditText = (EditText) DialogCompat.requireViewById(dialog, R.id.pin); TextView pinStatus = (TextView) DialogCompat.requireViewById(dialog, R.id.pin_status); - TextView reminder = (TextView) DialogCompat.requireViewById(dialog, R.id.reminder); + TextView reminder = (TextView) DialogCompat.requireViewById(dialog, R.id.kbs_reminder_body); View skip = DialogCompat.requireViewById(dialog, R.id.skip); View submit = DialogCompat.requireViewById(dialog, R.id.submit); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java index 9839a2e42a..3a881106ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/preferences/PaymentsHomeFragment.java @@ -30,8 +30,6 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.banner.Banner; import org.thoughtcrime.securesms.banner.BannerManager; import org.thoughtcrime.securesms.banner.banners.EnclaveFailureBanner; -import org.thoughtcrime.securesms.components.reminder.EnclaveFailureReminder; -import org.thoughtcrime.securesms.components.reminder.ReminderView; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.help.HelpFragment; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -107,7 +105,6 @@ public class PaymentsHomeFragment extends LoggingFragment { View sendMoney = view.findViewById(R.id.button_end_frame); View refresh = view.findViewById(R.id.payments_home_fragment_header_refresh); LottieAnimationView refreshAnimation = view.findViewById(R.id.payments_home_fragment_header_refresh_animation); - Stub reminderView = ViewUtil.findStubById(view, R.id.reminder); Stub bannerView = ViewUtil.findStubById(view, R.id.banner_compose_view); toolbar.setNavigationOnClickListener(v -> { @@ -264,33 +261,15 @@ public class PaymentsHomeFragment extends LoggingFragment { } }); - if (RemoteConfig.newBannerUi()) { - viewModel.getEnclaveFailure().observe(getViewLifecycleOwner(), failure -> { - if (failure) { - showUpdateIsRequiredDialog(); - } - }); - final Flow enclaveFailureFlow = FlowLiveDataConversions.asFlow(viewModel.getEnclaveFailure()); - final List> bannerRepositories = List.of(EnclaveFailureBanner.Companion.mapBooleanFlowToBannerFlow(enclaveFailureFlow, requireContext())); - final BannerManager bannerManager = new BannerManager(bannerRepositories); - bannerManager.setContent(bannerView.get()); - } else { - viewModel.getEnclaveFailure().observe(getViewLifecycleOwner(), failure -> { - if (failure) { - showUpdateIsRequiredDialog(); - reminderView.get().showReminder(new EnclaveFailureReminder(requireContext())); - reminderView.get().setOnActionClickListener(actionId -> { - if (actionId == R.id.reminder_action_update_now) { - PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext()); - } else if (actionId == R.id.reminder_action_re_register) { - startActivity(RegistrationActivity.newIntentForReRegistration(requireContext())); - } - }); - } else { - reminderView.get().requestDismiss(); - } - }); - } + viewModel.getEnclaveFailure().observe(getViewLifecycleOwner(), failure -> { + if (failure) { + showUpdateIsRequiredDialog(); + } + }); + final Flow enclaveFailureFlow = FlowLiveDataConversions.asFlow(viewModel.getEnclaveFailure()); + final List> bannerRepositories = List.of(EnclaveFailureBanner.Companion.mapBooleanFlowToBannerFlow(enclaveFailureFlow, requireContext())); + final BannerManager bannerManager = new BannerManager(bannerRepositories); + bannerManager.setContent(bannerView.get()); requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressed()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt index f298ad6d7a..8e7bfc84ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt @@ -10,7 +10,6 @@ import android.view.MenuItem import android.view.View import android.widget.Toast import androidx.activity.OnBackPressedCallback -import androidx.annotation.IdRes import androidx.compose.ui.platform.ComposeView import androidx.core.app.ActivityOptionsCompat import androidx.core.app.SharedElementCallback @@ -25,8 +24,6 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.kotlin.subscribeBy import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import org.signal.core.util.concurrent.LifecycleDisposable import org.thoughtcrime.securesms.MainActivity import org.thoughtcrime.securesms.R @@ -34,10 +31,6 @@ import org.thoughtcrime.securesms.banner.BannerManager import org.thoughtcrime.securesms.banner.banners.OutdatedBuildBanner import org.thoughtcrime.securesms.banner.banners.UnauthorizedBanner import org.thoughtcrime.securesms.components.Material3SearchToolbar -import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder -import org.thoughtcrime.securesms.components.reminder.Reminder -import org.thoughtcrime.securesms.components.reminder.ReminderView -import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText @@ -48,13 +41,11 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.dependencies.AppDependencies -import org.thoughtcrime.securesms.events.ReminderUpdateEvent import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder import org.thoughtcrime.securesms.main.SearchBinder import org.thoughtcrime.securesms.mediasend.camerax.CameraXUtil import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity import org.thoughtcrime.securesms.permissions.Permissions -import org.thoughtcrime.securesms.registration.ui.RegistrationActivity import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet import org.thoughtcrime.securesms.stories.StoryTextPostModel import org.thoughtcrime.securesms.stories.StoryViewerArgs @@ -65,8 +56,6 @@ import org.thoughtcrime.securesms.stories.settings.StorySettingsActivity import org.thoughtcrime.securesms.stories.tabs.ConversationListTab import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity -import org.thoughtcrime.securesms.util.PlayStoreUtil -import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.fragments.requireListener @@ -86,7 +75,6 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l private lateinit var emptyNotice: View private lateinit var cameraFab: FloatingActionButton - private lateinit var reminderView: Stub private lateinit var bannerView: Stub private val lifecycleDisposable = LifecycleDisposable() @@ -149,63 +137,30 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - reminderView = ViewUtil.findStubById(view, R.id.reminder) bannerView = ViewUtil.findStubById(view, R.id.banner_stub) - updateReminders() + initializeBanners() } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onEvent(event: ReminderUpdateEvent?) { - updateReminders() - } - - private fun updateReminders() { - if (RemoteConfig.newBannerUi) { - val bannerFlows = listOf( - OutdatedBuildBanner.createFlow(requireContext(), OutdatedBuildBanner.ExpiryStatus.EXPIRED_ONLY), - UnauthorizedBanner.createFlow(requireContext()) - ) - val bannerManager = BannerManager(bannerFlows) - bannerManager.setContent(bannerView.get()) - } else { - if (ExpiredBuildReminder.isEligible()) { - showReminder(ExpiredBuildReminder(context)) - } else if (UnauthorizedReminder.isEligible(context)) { - showReminder(UnauthorizedReminder()) - } else { - hideReminders() + private fun initializeBanners() { + val bannerFlows = listOf( + OutdatedBuildBanner.createFlow(requireContext(), OutdatedBuildBanner.ExpiryStatus.EXPIRED_ONLY), + UnauthorizedBanner.createFlow(requireContext()) + ) + val bannerManager = BannerManager( + bannerFlows, + onNewBannerShownListener = { + if (bannerView.resolved()) { + bannerView.get().addOnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ -> + recyclerView?.setPadding(0, bottom - top, 0, 0) + } + recyclerView?.clipToPadding = false + } + }, + onNoBannerShownListener = { + recyclerView?.clipToPadding = true } - } - } - - private fun showReminder(reminder: Reminder) { - if (!reminderView.resolved()) { - reminderView.get().addOnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ -> - recyclerView?.setPadding(0, bottom - top, 0, 0) - } - recyclerView?.clipToPadding = false - } - reminderView.get().showReminder(reminder) - reminderView.get().setOnActionClickListener { reminderActionId: Int -> this.handleReminderAction(reminderActionId) } - } - - private fun hideReminders() { - if (reminderView.resolved()) { - reminderView.get().hide() - recyclerView?.clipToPadding = true - } - } - - private fun handleReminderAction(@IdRes reminderActionId: Int) { - when (reminderActionId) { - R.id.reminder_action_update_now -> { - PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext()) - } - - R.id.reminder_action_re_register -> { - startActivity(RegistrationActivity.newIntentForReRegistration(requireContext())) - } - } + ) + bannerManager.setContent(bannerView.get()) } override fun bindAdapter(adapter: MappingAdapter) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt index 03771a0e7f..d9f9e39668 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt @@ -1082,15 +1082,6 @@ object RemoteConfig { hotSwappable = true ) - /** Whether to use the new Banner system instead of the old Reminder system. */ - @JvmStatic - @get:JvmName("newBannerUi") - val newBannerUi: Boolean by remoteBoolean( - key = "android.newBannerUi", - defaultValue = false, - hotSwappable = true - ) - /** Which phase we're in for the SVR3 migration */ val svr3MigrationPhase: Int by remoteInt( key = "global.svr3.phase", diff --git a/app/src/main/res/layout/conversation_activity_reminderview_stub.xml b/app/src/main/res/layout/conversation_activity_reminderview_stub.xml deleted file mode 100644 index 0fc2790cf5..0000000000 --- a/app/src/main/res/layout/conversation_activity_reminderview_stub.xml +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/app/src/main/res/layout/conversation_list_banner_view.xml b/app/src/main/res/layout/conversation_list_banner_view.xml index 0f6602adb5..5f8564a498 100644 --- a/app/src/main/res/layout/conversation_list_banner_view.xml +++ b/app/src/main/res/layout/conversation_list_banner_view.xml @@ -8,4 +8,4 @@ android:id="@+id/banner_compose_view" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintTop_toBottomOf="@id/reminder" /> + app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/conversation_list_fragment.xml b/app/src/main/res/layout/conversation_list_fragment.xml index cfca1b0e3f..c85b052cf5 100644 --- a/app/src/main/res/layout/conversation_list_fragment.xml +++ b/app/src/main/res/layout/conversation_list_fragment.xml @@ -17,28 +17,20 @@ android:layout="@layout/voice_note_player_stub" app:layout_constraintTop_toTopOf="parent" /> - - + app:layout_constraintTop_toTopOf="parent" /> + app:constraint_referenced_ids="voice_note_player,banner_compose_view" /> - diff --git a/app/src/main/res/layout/dsl_settings_fragment_with_reminder.xml b/app/src/main/res/layout/dsl_settings_fragment_with_reminder.xml index 018a86afda..c75ae1a9be 100644 --- a/app/src/main/res/layout/dsl_settings_fragment_with_reminder.xml +++ b/app/src/main/res/layout/dsl_settings_fragment_with_reminder.xml @@ -19,14 +19,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/toolbar" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/payments_home_fragment.xml b/app/src/main/res/layout/payments_home_fragment.xml index 81ae58ffad..a71ccadfe9 100644 --- a/app/src/main/res/layout/payments_home_fragment.xml +++ b/app/src/main/res/layout/payments_home_fragment.xml @@ -20,14 +20,6 @@ app:title="@string/preferences__payments" app:titleTextAppearance="@style/Signal.Text.TitleLarge" /> - - - - - diff --git a/app/src/main/res/layout/v2_conversation_fragment.xml b/app/src/main/res/layout/v2_conversation_fragment.xml index d3005273e7..204cf37949 100644 --- a/app/src/main/res/layout/v2_conversation_fragment.xml +++ b/app/src/main/res/layout/v2_conversation_fragment.xml @@ -166,13 +166,6 @@ android:inflatedId="@+id/unverified_banner" android:layout="@layout/conversation_activity_unverified_banner_stub" /> - -