Delete the reminders system.
This commit is contained in:
parent
4002dea05d
commit
9a24455085
37 changed files with 73 additions and 1277 deletions
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<RecipientId> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<Action> 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<Action> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ReminderActionsAdapter.ActionViewHolder> {
|
||||
|
||||
private final Reminder.Importance importance;
|
||||
private final List<Reminder.Action> actions;
|
||||
private final ReminderView.OnActionClickListener actionClickListener;
|
||||
|
||||
ReminderActionsAdapter(Reminder.Importance importance, List<Reminder.Action> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Reminder.Action> 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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ReminderView>
|
||||
private lateinit var bannerView: Stub<ComposeView>
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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<UnverifiedBannerView> by lazy { ViewUtil.findStubById(this, R.id.unverified_banner_stub) }
|
||||
private val reminderStub: Stub<ReminderView> by lazy { ViewUtil.findStubById(this, R.id.reminder_stub) }
|
||||
private val bannerStub: Stub<ComposeView> by lazy { ViewUtil.findStubById(this, R.id.banner_stub) }
|
||||
private val reviewBannerStub: Stub<ReviewBannerView> by lazy { ViewUtil.findStubById(this, R.id.review_banner_stub) }
|
||||
private val voiceNotePlayerStub: Stub<View> 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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<Optional<Reminder>> {
|
||||
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<IdentityRecordsState> {
|
||||
return Single.fromCallable {
|
||||
|
|
|
@ -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<Unit> = PublishSubject.create()
|
||||
val reminder: Observable<Optional<Reminder>>
|
||||
|
||||
private val groupRecordFlow: Flow<GroupRecord>
|
||||
|
||||
private val refreshIdentityRecords: Subject<Unit> = 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)
|
||||
|
|
|
@ -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> reminderView;
|
||||
private Stub<ComposeView> 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.<Reminder>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);
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package org.thoughtcrime.securesms.events;
|
||||
|
||||
|
||||
public class ReminderUpdateEvent {
|
||||
}
|
|
@ -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<ServiceOutageDetectionJob> {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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> reminderView = ViewUtil.findStubById(view, R.id.reminder);
|
||||
Stub<ComposeView> 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<Boolean> enclaveFailureFlow = FlowLiveDataConversions.asFlow(viewModel.getEnclaveFailure());
|
||||
final List<Flow<? extends Banner>> 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<Boolean> enclaveFailureFlow = FlowLiveDataConversions.asFlow(viewModel.getEnclaveFailure());
|
||||
final List<Flow<? extends Banner>> bannerRepositories = List.of(EnclaveFailureBanner.Companion.mapBooleanFlowToBannerFlow(enclaveFailureFlow, requireContext()));
|
||||
final BannerManager bannerManager = new BannerManager(bannerRepositories);
|
||||
bannerManager.setContent(bannerView.get());
|
||||
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressed());
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ReminderView>
|
||||
private lateinit var bannerView: Stub<ComposeView>
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:viewBindingIgnore="true"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
|
@ -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" />
|
||||
|
|
|
@ -17,28 +17,20 @@
|
|||
android:layout="@layout/voice_note_player_stub"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/reminder"
|
||||
android:layout="@layout/conversation_list_reminder_view"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/banner_compose_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/banner_compose_view"
|
||||
android:layout="@layout/conversation_list_banner_view"
|
||||
app:layout_constraintTop_toBottomOf="@id/reminder" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/banner_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="reminder,voice_note_player,banner_compose_view" />
|
||||
app:constraint_referenced_ids="voice_note_player,banner_compose_view" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:viewBindingIgnore="true"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar_barrier" />
|
|
@ -19,14 +19,6 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/reminder_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/reminder"
|
||||
android:layout="@layout/conversation_activity_reminderview_stub"
|
||||
app:layout_constraintTop_toTopOf="@id/recycler"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/banner_stub"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminder"
|
||||
android:id="@+id/kbs_reminder_body"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:lineSpacingMultiplier="1.3"
|
||||
|
@ -76,7 +76,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/KbsReminderDialog__submit"
|
||||
app:layout_constraintTop_toBottomOf="@id/reminder"
|
||||
app:layout_constraintTop_toBottomOf="@id/kbs_reminder_body"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -20,14 +20,6 @@
|
|||
app:title="@string/preferences__payments"
|
||||
app:titleTextAppearance="@style/Signal.Text.TitleLarge" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/reminder"
|
||||
android:layout="@layout/conversation_list_reminder_view"
|
||||
app:layout_constraintTop_toBottomOf="@id/payments_home_fragment_toolbar" />
|
||||
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/banner_compose_view"
|
||||
|
|
|
@ -100,14 +100,6 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/reminder"
|
||||
android:layout="@layout/stories_landing_reminder_view"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/banner_stub"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:viewBindingIgnore="true"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/reminder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
|
@ -166,13 +166,6 @@
|
|||
android:inflatedId="@+id/unverified_banner"
|
||||
android:layout="@layout/conversation_activity_unverified_banner_stub" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/reminder_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/reminder"
|
||||
android:layout="@layout/conversation_activity_reminderview_stub" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/review_banner_stub"
|
||||
android:layout_width="match_parent"
|
||||
|
|
Loading…
Add table
Reference in a new issue