kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add tooltip to opt-out of bubbles.
rodzic
63c98e92f2
commit
b6f84dfa16
|
@ -0,0 +1,16 @@
|
|||
package org.thoughtcrime.securesms.components.reminder
|
||||
|
||||
import android.content.Context
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
class BubbleOptOutReminder(context: Context) : Reminder(null, context.getString(R.string.BubbleOptOutTooltip__description)) {
|
||||
|
||||
init {
|
||||
addAction(Action(context.getString(R.string.BubbleOptOutTooltip__turn_off), R.id.reminder_action_turn_off))
|
||||
addAction(Action(context.getString(R.string.BubbleOptOutTooltip__not_now), R.id.reminder_action_not_now))
|
||||
}
|
||||
|
||||
override fun isDismissable(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
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;
|
||||
|
@ -15,10 +18,12 @@ 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(List<Reminder.Action> actions, 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;
|
||||
}
|
||||
|
@ -26,7 +31,14 @@ final class ReminderActionsAdapter extends RecyclerView.Adapter<ReminderActionsA
|
|||
@NonNull
|
||||
@Override
|
||||
public ActionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ActionViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.reminder_action_button, parent, false));
|
||||
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_accent_primary));
|
||||
}
|
||||
|
||||
return new ActionViewHolder(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.signal.core.util.DimensionUnit;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -28,6 +29,7 @@ public final class ReminderView extends FrameLayout {
|
|||
private ProgressBar progressBar;
|
||||
private TextView progressText;
|
||||
private ViewGroup container;
|
||||
private View background;
|
||||
private ImageButton closeButton;
|
||||
private TextView title;
|
||||
private TextView text;
|
||||
|
@ -56,6 +58,7 @@ public final class ReminderView extends FrameLayout {
|
|||
progressBar = findViewById(R.id.reminder_progress);
|
||||
progressText = findViewById(R.id.reminder_progress_text);
|
||||
container = findViewById(R.id.container);
|
||||
background = findViewById(R.id.background);
|
||||
closeButton = findViewById(R.id.cancel);
|
||||
title = findViewById(R.id.reminder_title);
|
||||
text = findViewById(R.id.reminder_text);
|
||||
|
@ -79,24 +82,30 @@ public final class ReminderView extends FrameLayout {
|
|||
}
|
||||
|
||||
text.setText(reminder.getText());
|
||||
text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_button_primary_text));
|
||||
|
||||
switch (reminder.getImportance()) {
|
||||
case NORMAL:
|
||||
container.setBackgroundResource(R.drawable.reminder_background_normal);
|
||||
background.setBackgroundResource(R.drawable.reminder_background_normal);
|
||||
title.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_text_primary));
|
||||
text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_text_primary));
|
||||
break;
|
||||
case ERROR:
|
||||
container.setBackgroundResource(R.drawable.reminder_background_error);
|
||||
background.setBackgroundResource(R.drawable.reminder_background_error);
|
||||
title.setTextColor(ContextCompat.getColor(getContext(), R.color.core_black));
|
||||
text.setTextColor(ContextCompat.getColor(getContext(), R.color.core_black));
|
||||
break;
|
||||
case TERMINAL:
|
||||
container.setBackgroundResource(R.drawable.reminder_background_terminal);
|
||||
background.setBackgroundResource(R.drawable.reminder_background_terminal);
|
||||
title.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_button_primary_text));
|
||||
text.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_button_primary_text));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
setOnClickListener(reminder.getOkListener());
|
||||
if (reminder.getOkListener() != null) {
|
||||
setOnClickListener(reminder.getOkListener());
|
||||
}
|
||||
|
||||
closeButton.setVisibility(reminder.isDismissable() ? View.VISIBLE : View.GONE);
|
||||
closeButton.setOnClickListener(new OnClickListener() {
|
||||
|
@ -121,10 +130,12 @@ public final class ReminderView extends FrameLayout {
|
|||
|
||||
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(actions, this::handleActionClicked));
|
||||
actionsRecycler.setAdapter(new ReminderActionsAdapter(reminder.getImportance(), actions, this::handleActionClicked));
|
||||
}
|
||||
|
||||
container.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -38,6 +38,7 @@ import android.os.Bundle;
|
|||
import android.os.Vibrator;
|
||||
import android.provider.Browser;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
|
@ -124,6 +125,7 @@ import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
|
|||
import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalPlace;
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
||||
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;
|
||||
|
@ -1874,6 +1876,19 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
|||
});
|
||||
reminderView.get().setOnDismissListener(() -> {
|
||||
});
|
||||
} else if (isInBubble() && !SignalStore.tooltips().hasSeenBubbleOptOutTooltip() && Build.VERSION.SDK_INT > 29) {
|
||||
reminderView.get().showReminder(new BubbleOptOutReminder(this));
|
||||
reminderView.get().setOnActionClickListener(actionId -> {
|
||||
SignalStore.tooltips().markBubbleOptOutTooltipSeen();
|
||||
reminderView.get().hide();
|
||||
|
||||
if (actionId == R.id.reminder_action_turn_off) {
|
||||
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS)
|
||||
.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
} else if (reminderView.resolved()) {
|
||||
reminderView.get().hide();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public class TooltipValues extends SignalStoreValues {
|
|||
private static final String GROUP_CALL_SPEAKER_VIEW = "tooltip.group_call_speaker_view";
|
||||
private static final String GROUP_CALL_TOOLTIP_DISPLAY_COUNT = "tooltip.group_call_tooltip_display_count";
|
||||
private static final String MULTI_FORWARD_DIALOG = "tooltip.multi.forward.dialog";
|
||||
private static final String BUBBLE_OPT_OUT = "tooltip.bubble.opt.out";
|
||||
|
||||
|
||||
TooltipValues(@NonNull KeyValueStore store) {
|
||||
|
@ -64,4 +65,12 @@ public class TooltipValues extends SignalStoreValues {
|
|||
public void markMultiForwardDialogSeen() {
|
||||
putBoolean(MULTI_FORWARD_DIALOG, false);
|
||||
}
|
||||
|
||||
public boolean hasSeenBubbleOptOutTooltip() {
|
||||
return getBoolean(BUBBLE_OPT_OUT, false);
|
||||
}
|
||||
|
||||
public void markBubbleOptOutTooltipSeen() {
|
||||
putBoolean(BUBBLE_OPT_OUT, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" android:drawable="@color/core_ultramarine_dark" />
|
||||
<item android:state_focused="true" android:drawable="@color/core_ultramarine" />
|
||||
<item android:drawable="@color/core_ultramarine" />
|
||||
<item android:state_pressed="true" android:drawable="@color/signal_background_secondary" />
|
||||
<item android:state_focused="true" android:drawable="@color/signal_background_tertiary" />
|
||||
<item android:drawable="@color/signal_background_tertiary" />
|
||||
</selector>
|
||||
|
|
|
@ -239,7 +239,6 @@
|
|||
android:inflatedId="@+id/review_banner"
|
||||
android:layout="@layout/review_banner_view" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:paddingStart="16dp"
|
||||
|
|
|
@ -5,13 +5,19 @@
|
|||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/reminder_background_normal"
|
||||
android:focusable="true"
|
||||
android:nextFocusRight="@+id/cancel"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<View
|
||||
android:id="@+id/background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/reminder_background_normal"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/reminder_actions" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/reminder_progress"
|
||||
style="@style/Widget.ProgressBar.Horizontal"
|
||||
|
@ -105,11 +111,17 @@
|
|||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/reminder_text"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:reverseLayout="true"
|
||||
tools:itemCount="2"
|
||||
tools:listitem="@layout/reminder_action_button" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@drawable/toolbar_shadow"
|
||||
app:layout_constraintTop_toBottomOf="@id/background" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<item name="reminder_action_gv1_suggestion_no_thanks" type="id" />
|
||||
<item name="reminder_action_gv1_suggestion_add_members" type="id" />
|
||||
|
||||
<item name="reminder_action_not_now" type="id" />
|
||||
<item name="reminder_action_turn_off" type="id" />
|
||||
|
||||
<item name="status_bar_guideline" type="id" />
|
||||
<item name="navigation_bar_guideline" type="id" />
|
||||
</resources>
|
||||
|
|
|
@ -2024,6 +2024,14 @@
|
|||
<!-- conversation_fragment -->
|
||||
<string name="conversation_fragment__scroll_to_the_bottom_content_description">Scroll to the bottom</string>
|
||||
|
||||
<!-- BubbleOptOutTooltip -->
|
||||
<!-- Message to inform the user of what Android chat bubbles are -->
|
||||
<string name="BubbleOptOutTooltip__description">Bubbles are an Android feature that you can turn off for Signal chats.</string>
|
||||
<!-- Button to dismiss the tooltip for opting out of using Android bubbles -->
|
||||
<string name="BubbleOptOutTooltip__not_now">Not now</string>
|
||||
<!-- Button to move to the system settings to control the use of Android bubbles -->
|
||||
<string name="BubbleOptOutTooltip__turn_off">Turn off</string>
|
||||
|
||||
<!-- safety_number_change_dialog -->
|
||||
<string name="safety_number_change_dialog__safety_number_changes">Safety Number Changes</string>
|
||||
<string name="safety_number_change_dialog__accept">Accept</string>
|
||||
|
|
Ładowanie…
Reference in New Issue