mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-21 18:26:57 +00:00
Added a new onboarding megaphone.
This commit is contained in:
@@ -52,6 +52,7 @@ public final class AppInitialization {
|
||||
|
||||
ApplicationDependencies.getMegaphoneRepository().onFirstEverAppLaunch();
|
||||
SignalStore.onFirstEverAppLaunch();
|
||||
SignalStore.onboarding().clearAll();
|
||||
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.ZOZO.getPackId(), BlessedPacks.ZOZO.getPackKey(), false));
|
||||
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.BANDIT.getPackId(), BlessedPacks.BANDIT.getPackKey(), false));
|
||||
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forReference(BlessedPacks.SWOON_HANDS.getPackId(), BlessedPacks.SWOON_HANDS.getPackKey()));
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.thoughtcrime.securesms.components.reminder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
import org.thoughtcrime.securesms.util.SmsUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
public class DefaultSmsReminder extends Reminder {
|
||||
|
||||
public DefaultSmsReminder(@NonNull Fragment fragment, short requestCode) {
|
||||
super(fragment.getString(R.string.reminder_header_sms_default_title),
|
||||
fragment.getString(R.string.reminder_header_sms_default_text));
|
||||
|
||||
final OnClickListener okListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextSecurePreferences.setPromptedDefaultSmsProvider(fragment.requireContext(), true);
|
||||
fragment.startActivityForResult(SmsUtil.getSmsRoleIntent(fragment.requireContext()), requestCode);
|
||||
}
|
||||
};
|
||||
final OnClickListener dismissListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextSecurePreferences.setPromptedDefaultSmsProvider(fragment.requireContext(), true);
|
||||
}
|
||||
};
|
||||
setOkListener(okListener);
|
||||
setDismissListener(dismissListener);
|
||||
}
|
||||
|
||||
public static boolean isEligible(Context context) {
|
||||
final boolean isDefault = Util.isDefaultSmsProvider(context);
|
||||
if (isDefault) {
|
||||
TextSecurePreferences.setPromptedDefaultSmsProvider(context, false);
|
||||
}
|
||||
|
||||
return !isDefault && !TextSecurePreferences.hasPromptedDefaultSmsProvider(context) && PhoneNumberFormatter.getLocalCountryCode() != 91;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.thoughtcrime.securesms.components.reminder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.InviteActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
public class ShareReminder extends Reminder {
|
||||
|
||||
public ShareReminder(final @NonNull Context context) {
|
||||
super(context.getString(R.string.reminder_header_share_title),
|
||||
context.getString(R.string.reminder_header_share_text));
|
||||
|
||||
setDismissListener(new OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
TextSecurePreferences.setPromptedShare(context, true);
|
||||
}
|
||||
});
|
||||
|
||||
setOkListener(new OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
TextSecurePreferences.setPromptedShare(context, true);
|
||||
context.startActivity(new Intent(context, InviteActivity.class));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isEligible(final @NonNull Context context) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
TextSecurePreferences.hasPromptedShare(context))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DatabaseFactory.getThreadDatabase(context).getUnarchivedConversationListCount() >= 1;
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,6 @@ import org.thoughtcrime.securesms.components.RatingManager;
|
||||
import org.thoughtcrime.securesms.components.SearchToolbar;
|
||||
import org.thoughtcrime.securesms.components.recyclerview.DeleteItemAnimator;
|
||||
import org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton;
|
||||
import org.thoughtcrime.securesms.components.reminder.DefaultSmsReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.DozeReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.OutdatedBuildReminder;
|
||||
@@ -88,8 +87,6 @@ import org.thoughtcrime.securesms.components.reminder.PushRegistrationReminder;
|
||||
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.ShareReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.SystemSmsImportReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationFragment;
|
||||
import org.thoughtcrime.securesms.conversationlist.model.Conversation;
|
||||
@@ -103,6 +100,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
import org.thoughtcrime.securesms.insights.InsightsLauncher;
|
||||
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphone;
|
||||
@@ -124,7 +122,6 @@ import org.thoughtcrime.securesms.util.SnapToTopDataObserver;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
@@ -156,12 +153,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
|
||||
private static final int MAXIMUM_PINNED_CONVERSATIONS = 4;
|
||||
|
||||
private static final int[] EMPTY_IMAGES = new int[] { R.drawable.empty_inbox_1,
|
||||
R.drawable.empty_inbox_2,
|
||||
R.drawable.empty_inbox_3,
|
||||
R.drawable.empty_inbox_4,
|
||||
R.drawable.empty_inbox_5 };
|
||||
|
||||
private ActionMode actionMode;
|
||||
private RecyclerView list;
|
||||
private Stub<ReminderView> reminderView;
|
||||
@@ -613,14 +604,8 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
return Optional.of(new ServiceOutageReminder(context));
|
||||
} else if (OutdatedBuildReminder.isEligible()) {
|
||||
return Optional.of(new OutdatedBuildReminder(context));
|
||||
} else if (DefaultSmsReminder.isEligible(context)) {
|
||||
return Optional.of(new DefaultSmsReminder(this, SMS_ROLE_REQUEST_CODE));
|
||||
} else if (Util.isDefaultSmsProvider(context) && SystemSmsImportReminder.isEligible(context)) {
|
||||
return Optional.of((new SystemSmsImportReminder(context)));
|
||||
} else if (PushRegistrationReminder.isEligible(context)) {
|
||||
return Optional.of((new PushRegistrationReminder(context)));
|
||||
} else if (ShareReminder.isEligible(context)) {
|
||||
return Optional.of(new ShareReminder(context));
|
||||
} else if (DozeReminder.isEligible(context)) {
|
||||
return Optional.of(new DozeReminder(context));
|
||||
} else {
|
||||
@@ -858,8 +843,8 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||
fab.startPulse(3 * 1000);
|
||||
cameraFab.startPulse(3 * 1000);
|
||||
|
||||
ImageView emptyImage = emptyState.get().findViewById(R.id.empty);
|
||||
emptyImage.setImageResource(EMPTY_IMAGES[(int) (Math.random() * EMPTY_IMAGES.length)]);
|
||||
SignalStore.onboarding().setShowNewGroup(true);
|
||||
SignalStore.onboarding().setShowInviteFriends(true);
|
||||
} else {
|
||||
list.setVisibility(View.VISIBLE);
|
||||
fab.stopPulse();
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.thoughtcrime.securesms.keyvalue;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
public final class OnboardingValues extends SignalStoreValues {
|
||||
|
||||
private static final String SHOW_NEW_GROUP = "onboarding.new_group";
|
||||
private static final String SHOW_INVITE_FRIENDS = "onboarding.invite_friends";
|
||||
private static final String SHOW_SMS = "onboarding.sms";
|
||||
|
||||
OnboardingValues(@NonNull KeyValueStore store) {
|
||||
super(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onFirstEverAppLaunch() {
|
||||
putBoolean(SHOW_NEW_GROUP, true);
|
||||
putBoolean(SHOW_INVITE_FRIENDS, true);
|
||||
putBoolean(SHOW_SMS, true);
|
||||
}
|
||||
|
||||
public void clearAll() {
|
||||
setShowNewGroup(false);
|
||||
setShowInviteFriends(false);
|
||||
setShowSms(false);
|
||||
}
|
||||
|
||||
public boolean hasOnboarding(@NonNull Context context) {
|
||||
return shouldShowNewGroup() ||
|
||||
shouldShowInviteFriends() ||
|
||||
shouldShowSms(context);
|
||||
}
|
||||
|
||||
public void setShowNewGroup(boolean value) {
|
||||
putBoolean(SHOW_NEW_GROUP, value);
|
||||
}
|
||||
|
||||
public boolean shouldShowNewGroup() {
|
||||
return getBoolean(SHOW_NEW_GROUP, false);
|
||||
}
|
||||
|
||||
public void setShowInviteFriends(boolean value) {
|
||||
putBoolean(SHOW_INVITE_FRIENDS, value);
|
||||
}
|
||||
|
||||
public boolean shouldShowInviteFriends() {
|
||||
return getBoolean(SHOW_INVITE_FRIENDS, false);
|
||||
}
|
||||
|
||||
public void setShowSms(boolean value) {
|
||||
putBoolean(SHOW_SMS, value);
|
||||
}
|
||||
|
||||
public boolean shouldShowSms(@NonNull Context context) {
|
||||
return getBoolean(SHOW_SMS, false) && !Util.isDefaultSmsProvider(context) && PhoneNumberFormatter.getLocalCountryCode() != 91;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ public final class SignalStore {
|
||||
private final SettingsValues settingsValues;
|
||||
private final CertificateValues certificateValues;
|
||||
private final PhoneNumberPrivacyValues phoneNumberPrivacyValues;
|
||||
private final OnboardingValues onboardingValues;
|
||||
|
||||
private SignalStore() {
|
||||
this.store = new KeyValueStore(ApplicationDependencies.getApplication());
|
||||
@@ -43,6 +44,7 @@ public final class SignalStore {
|
||||
this.settingsValues = new SettingsValues(store);
|
||||
this.certificateValues = new CertificateValues(store);
|
||||
this.phoneNumberPrivacyValues = new PhoneNumberPrivacyValues(store);
|
||||
this.onboardingValues = new OnboardingValues(store);
|
||||
}
|
||||
|
||||
public static void onFirstEverAppLaunch() {
|
||||
@@ -58,6 +60,7 @@ public final class SignalStore {
|
||||
settings().onFirstEverAppLaunch();
|
||||
certificateValues().onFirstEverAppLaunch();
|
||||
phoneNumberPrivacy().onFirstEverAppLaunch();
|
||||
onboarding().onFirstEverAppLaunch();
|
||||
}
|
||||
|
||||
public static @NonNull KbsValues kbsValues() {
|
||||
@@ -112,6 +115,10 @@ public final class SignalStore {
|
||||
return INSTANCE.phoneNumberPrivacyValues;
|
||||
}
|
||||
|
||||
public static @NonNull OnboardingValues onboarding() {
|
||||
return INSTANCE.onboardingValues;
|
||||
}
|
||||
|
||||
public static @NonNull GroupsV2AuthorizationSignalStoreCache groupsV2AuthorizationCache() {
|
||||
return new GroupsV2AuthorizationSignalStoreCache(getStore());
|
||||
}
|
||||
|
||||
@@ -200,6 +200,9 @@ public class Megaphone {
|
||||
/** Specialized style for announcing link previews. */
|
||||
LINK_PREVIEWS,
|
||||
|
||||
/** Specialized style for onboarding. */
|
||||
ONBOARDING,
|
||||
|
||||
/** Basic bottom of the screen megaphone with optional snooze and action buttons. */
|
||||
BASIC,
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ public class MegaphoneViewBuilder {
|
||||
return buildReactionsMegaphone(context, megaphone, listener);
|
||||
case LINK_PREVIEWS:
|
||||
return buildLinkPreviewsMegaphone(context, megaphone, listener);
|
||||
case ONBOARDING:
|
||||
return buildOnboardingMegaphone(context, megaphone, listener);
|
||||
case POPUP:
|
||||
return buildPopupMegaphone(context, megaphone, listener);
|
||||
default:
|
||||
@@ -58,6 +60,15 @@ public class MegaphoneViewBuilder {
|
||||
return view;
|
||||
}
|
||||
|
||||
private static @NonNull View buildOnboardingMegaphone(@NonNull Context context,
|
||||
@NonNull Megaphone megaphone,
|
||||
@NonNull MegaphoneActionController listener)
|
||||
{
|
||||
OnboardingMegaphoneView view = new OnboardingMegaphoneView(context);
|
||||
view.present(megaphone, listener);
|
||||
return view;
|
||||
}
|
||||
|
||||
private static @NonNull View buildPopupMegaphone(@NonNull Context context,
|
||||
@NonNull Megaphone megaphone,
|
||||
@NonNull MegaphoneActionController listener)
|
||||
|
||||
@@ -93,6 +93,7 @@ public final class Megaphones {
|
||||
put(Event.RESEARCH, shouldShowResearchMegaphone(context) ? ShowForDurationSchedule.showForDays(7) : NEVER);
|
||||
put(Event.DONATE, shouldShowDonateMegaphone(context) ? ShowForDurationSchedule.showForDays(7) : NEVER);
|
||||
put(Event.GROUP_CALLING, shouldShowGroupCallingMegaphone() ? ALWAYS : NEVER);
|
||||
put(Event.ONBOARDING, shouldShowOnboardingMegaphone(context) ? ALWAYS : NEVER);
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -116,6 +117,8 @@ public final class Megaphones {
|
||||
return buildDonateMegaphone(context);
|
||||
case GROUP_CALLING:
|
||||
return buildGroupCallingMegaphone(context);
|
||||
case ONBOARDING:
|
||||
return buildOnboardingMegaphone();
|
||||
default:
|
||||
throw new IllegalArgumentException("Event not handled!");
|
||||
}
|
||||
@@ -255,6 +258,12 @@ public final class Megaphones {
|
||||
.build();
|
||||
}
|
||||
|
||||
private static @NonNull Megaphone buildOnboardingMegaphone() {
|
||||
return new Megaphone.Builder(Event.ONBOARDING, Megaphone.Style.ONBOARDING)
|
||||
.setPriority(Megaphone.Priority.DEFAULT)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static boolean shouldShowMessageRequestsMegaphone() {
|
||||
return Recipient.self().getProfileName() == ProfileName.EMPTY;
|
||||
}
|
||||
@@ -275,6 +284,10 @@ public final class Megaphones {
|
||||
return FeatureFlags.groupCalling();
|
||||
}
|
||||
|
||||
private static boolean shouldShowOnboardingMegaphone(@NonNull Context context) {
|
||||
return SignalStore.onboarding().hasOnboarding(context);
|
||||
}
|
||||
|
||||
public enum Event {
|
||||
REACTIONS("reactions"),
|
||||
PINS_FOR_ALL("pins_for_all"),
|
||||
@@ -284,7 +297,8 @@ public final class Megaphones {
|
||||
CLIENT_DEPRECATED("client_deprecated"),
|
||||
RESEARCH("research"),
|
||||
DONATE("donate"),
|
||||
GROUP_CALLING("group_calling");
|
||||
GROUP_CALLING("group_calling"),
|
||||
ONBOARDING("onboarding");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
package org.thoughtcrime.securesms.megaphone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.InviteActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.conversationlist.ConversationListFragment;
|
||||
import org.thoughtcrime.securesms.groups.ui.creategroup.CreateGroupActivity;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.SmsUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Shows the a fun rail of cards that educate the user about some actions they can take right after
|
||||
* they install the app.
|
||||
*/
|
||||
public class OnboardingMegaphoneView extends FrameLayout {
|
||||
|
||||
private static final String TAG = Log.tag(OnboardingMegaphoneView.class);
|
||||
|
||||
private RecyclerView cardList;
|
||||
|
||||
public OnboardingMegaphoneView(Context context) {
|
||||
super(context);
|
||||
initialize(context);
|
||||
}
|
||||
|
||||
public OnboardingMegaphoneView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize(context);
|
||||
}
|
||||
|
||||
private void initialize(@NonNull Context context) {
|
||||
inflate(context, R.layout.onboarding_megaphone, this);
|
||||
|
||||
this.cardList = findViewById(R.id.onboarding_megaphone_list);
|
||||
}
|
||||
|
||||
public void present(@NonNull Megaphone megaphone, @NonNull MegaphoneActionController listener) {
|
||||
this.cardList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
this.cardList.setAdapter(new CardAdapter(getContext(), listener));
|
||||
}
|
||||
|
||||
private static class CardAdapter extends RecyclerView.Adapter<CardViewHolder> implements ActionClickListener {
|
||||
|
||||
private static final int TYPE_GROUP = 0;
|
||||
private static final int TYPE_INVITE = 1;
|
||||
private static final int TYPE_SMS = 2;
|
||||
|
||||
private final Context context;
|
||||
private final MegaphoneActionController controller;
|
||||
private final List<Integer> data;
|
||||
|
||||
CardAdapter(@NonNull Context context, @NonNull MegaphoneActionController controller) {
|
||||
this.context = context;
|
||||
this.controller = controller;
|
||||
this.data = buildData(context);
|
||||
|
||||
if (data.isEmpty()) {
|
||||
Log.i(TAG, "Nothing to show (constructor)! Considering megaphone completed.");
|
||||
controller.onMegaphoneCompleted(Megaphones.Event.ONBOARDING);
|
||||
}
|
||||
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return data.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return data.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.onboarding_megaphone_list_item, parent, false);
|
||||
switch (viewType) {
|
||||
case TYPE_GROUP: return new GroupCardViewHolder(view);
|
||||
case TYPE_INVITE: return new InviteCardViewHolder(view);
|
||||
case TYPE_SMS: return new SmsCardViewHolder(view);
|
||||
default: throw new IllegalStateException("Invalid viewType! " + viewType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CardViewHolder holder, int position) {
|
||||
holder.bind(this, controller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
data.clear();
|
||||
data.addAll(buildData(context));
|
||||
if (data.isEmpty()) {
|
||||
Log.i(TAG, "Nothing to show! Considering megaphone completed.");
|
||||
controller.onMegaphoneCompleted(Megaphones.Event.ONBOARDING);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static List<Integer> buildData(@NonNull Context context) {
|
||||
List<Integer> data = new ArrayList<>();
|
||||
|
||||
if (SignalStore.onboarding().shouldShowNewGroup()) {
|
||||
data.add(TYPE_GROUP);
|
||||
}
|
||||
|
||||
if (SignalStore.onboarding().shouldShowInviteFriends()) {
|
||||
data.add(TYPE_INVITE);
|
||||
}
|
||||
|
||||
if (SignalStore.onboarding().shouldShowSms(context)) {
|
||||
data.add(TYPE_SMS);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private interface ActionClickListener {
|
||||
void onClick();
|
||||
}
|
||||
|
||||
private static abstract class CardViewHolder extends RecyclerView.ViewHolder {
|
||||
private final ImageView image;
|
||||
private final TextView actionButton;
|
||||
private final View closeButton;
|
||||
|
||||
public CardViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
this.image = itemView.findViewById(R.id.onboarding_megaphone_item_image);
|
||||
this.actionButton = itemView.findViewById(R.id.onboarding_megaphone_item_button);
|
||||
this.closeButton = itemView.findViewById(R.id.onboarding_megaphone_item_close);
|
||||
}
|
||||
|
||||
public void bind(@NonNull ActionClickListener listener, @NonNull MegaphoneActionController controller) {
|
||||
image.setImageResource(getImageRes());
|
||||
actionButton.setText(getButtonStringRes());
|
||||
actionButton.setOnClickListener(v -> {
|
||||
onActionClicked(controller);
|
||||
listener.onClick();
|
||||
});
|
||||
closeButton.setOnClickListener(v -> {
|
||||
onCloseClicked();
|
||||
listener.onClick();
|
||||
});
|
||||
}
|
||||
|
||||
abstract @StringRes int getButtonStringRes();
|
||||
abstract @DrawableRes int getImageRes();
|
||||
abstract void onActionClicked(@NonNull MegaphoneActionController controller);
|
||||
abstract void onCloseClicked();
|
||||
}
|
||||
|
||||
private static class GroupCardViewHolder extends CardViewHolder {
|
||||
|
||||
public GroupCardViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
int getButtonStringRes() {
|
||||
return R.string.Megaphones_new_group;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getImageRes() {
|
||||
return R.drawable.ic_megaphone_start_group;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onActionClicked(@NonNull MegaphoneActionController controller) {
|
||||
controller.onMegaphoneNavigationRequested(CreateGroupActivity.newIntent(controller.getMegaphoneActivity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
void onCloseClicked() {
|
||||
SignalStore.onboarding().setShowNewGroup(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InviteCardViewHolder extends CardViewHolder {
|
||||
|
||||
public InviteCardViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
int getButtonStringRes() {
|
||||
return R.string.Megaphones_invite_friends;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getImageRes() {
|
||||
return R.drawable.ic_megaphone_invite_friends;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onActionClicked(@NonNull MegaphoneActionController controller) {
|
||||
controller.onMegaphoneNavigationRequested(new Intent(controller.getMegaphoneActivity(), InviteActivity.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
void onCloseClicked() {
|
||||
SignalStore.onboarding().setShowInviteFriends(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SmsCardViewHolder extends CardViewHolder {
|
||||
|
||||
public SmsCardViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
int getButtonStringRes() {
|
||||
return R.string.Megaphones_use_sms;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getImageRes() {
|
||||
return R.drawable.ic_megaphone_use_sms;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onActionClicked(@NonNull MegaphoneActionController controller) {
|
||||
Intent intent = SmsUtil.getSmsRoleIntent(controller.getMegaphoneActivity());
|
||||
controller.onMegaphoneNavigationRequested(intent, ConversationListFragment.SMS_ROLE_REQUEST_CODE);
|
||||
SignalStore.onboarding().setShowSms(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onCloseClicked() {
|
||||
SignalStore.onboarding().setShowSms(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.MainActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.lock.v2.KbsConstants;
|
||||
import org.thoughtcrime.securesms.lock.v2.PinKeyboardType;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
@@ -227,6 +228,7 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
||||
|
||||
private void handleSuccess() {
|
||||
cancelSpinning(pinButton);
|
||||
SignalStore.onboarding().clearAll();
|
||||
|
||||
Activity activity = requireActivity();
|
||||
|
||||
|
||||
@@ -304,6 +304,7 @@ public final class RegistrationLockFragment extends BaseRegistrationFragment {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
SimpleTask.run(() -> {
|
||||
SignalStore.onboarding().clearAll();
|
||||
return ApplicationDependencies.getJobManager().runSynchronously(new StorageAccountRestoreJob(), StorageAccountRestoreJob.LIFESPAN);
|
||||
}, result -> {
|
||||
long elapsedTime = System.currentTimeMillis() - startTime;
|
||||
|
||||
@@ -78,9 +78,7 @@ public class TextSecurePreferences {
|
||||
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
||||
private static final String SEEN_WELCOME_SCREEN_PREF = "pref_seen_welcome_screen";
|
||||
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
|
||||
private static final String PROMPTED_DEFAULT_SMS_PREF = "pref_prompted_default_sms";
|
||||
private static final String PROMPTED_OPTIMIZE_DOZE_PREF = "pref_prompted_optimize_doze";
|
||||
private static final String PROMPTED_SHARE_PREF = "pref_prompted_share";
|
||||
private static final String SIGNALING_KEY_PREF = "pref_signaling_key";
|
||||
private static final String DIRECTORY_FRESH_TIME_PREF = "pref_directory_refresh_time";
|
||||
private static final String UPDATE_APK_REFRESH_TIME_PREF = "pref_update_apk_refresh_time";
|
||||
@@ -890,14 +888,6 @@ public class TextSecurePreferences {
|
||||
setBooleanPreference(context, PROMPTED_PUSH_REGISTRATION_PREF, value);
|
||||
}
|
||||
|
||||
public static boolean hasPromptedDefaultSmsProvider(Context context) {
|
||||
return getBooleanPreference(context, PROMPTED_DEFAULT_SMS_PREF, false);
|
||||
}
|
||||
|
||||
public static void setPromptedDefaultSmsProvider(Context context, boolean value) {
|
||||
setBooleanPreference(context, PROMPTED_DEFAULT_SMS_PREF, value);
|
||||
}
|
||||
|
||||
public static void setPromptedOptimizeDoze(Context context, boolean value) {
|
||||
setBooleanPreference(context, PROMPTED_OPTIMIZE_DOZE_PREF, value);
|
||||
}
|
||||
@@ -906,14 +896,6 @@ public class TextSecurePreferences {
|
||||
return getBooleanPreference(context, PROMPTED_OPTIMIZE_DOZE_PREF, false);
|
||||
}
|
||||
|
||||
public static boolean hasPromptedShare(Context context) {
|
||||
return getBooleanPreference(context, PROMPTED_SHARE_PREF, false);
|
||||
}
|
||||
|
||||
public static void setPromptedShare(Context context, boolean value) {
|
||||
setBooleanPreference(context, PROMPTED_SHARE_PREF, value);
|
||||
}
|
||||
|
||||
public static boolean isInterceptAllMmsEnabled(Context context) {
|
||||
return getBooleanPreference(context, ALL_MMS_PREF, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user