Updated PIN strings.

This commit is contained in:
Greyson Parrelli
2020-04-16 13:37:15 -04:00
parent 53b681ef67
commit 8f9e79ae37
51 changed files with 268 additions and 220 deletions

View File

@@ -18,12 +18,14 @@ import androidx.fragment.app.Fragment;
import com.airbnb.lottie.LottieAnimationView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
abstract class BaseKbsPinFragment<ViewModel extends BaseKbsPinViewModel> extends Fragment {
private TextView title;
private TextView description;
private LearnMoreTextView description;
private EditText input;
private TextView label;
private TextView keyboardToggle;
@@ -57,6 +59,10 @@ abstract class BaseKbsPinFragment<ViewModel extends BaseKbsPinViewModel> extends
keyboardToggle.setText(resolveKeyboardToggleText(keyboardType));
});
description.setOnLinkClickListener(v -> {
CommunicationActions.openBrowserLink(requireContext(), getString(R.string.BaseKbsPinFragment__learn_more_url));
});
initializeListeners();
}
@@ -75,7 +81,7 @@ abstract class BaseKbsPinFragment<ViewModel extends BaseKbsPinViewModel> extends
return title;
}
protected TextView getDescription() {
protected LearnMoreTextView getDescription() {
return description;
}

View File

@@ -62,11 +62,13 @@ public class ConfirmKbsPinFragment extends BaseKbsPinFragment<ConfirmKbsPinViewM
getDescription().setText(R.string.ConfirmKbsPinFragment__confirm_your_pin);
getKeyboardToggle().setVisibility(View.INVISIBLE);
getLabel().setText("");
getDescription().setLearnMoreVisible(false);
}
private void initializeViewStatesForPinChange() {
getTitle().setText(R.string.CreateKbsPinFragment__create_a_new_pin);
getDescription().setText(R.string.ConfirmKbsPinFragment__confirm_your_pin);
getDescription().setLearnMoreVisible(false);
getKeyboardToggle().setVisibility(View.INVISIBLE);
getLabel().setText("");
}
@@ -81,7 +83,7 @@ public class ConfirmKbsPinFragment extends BaseKbsPinFragment<ConfirmKbsPinViewM
getInput().setEnabled(false);
break;
case RE_ENTER_PIN:
getLabel().setText(R.string.ConfirmKbsPinFragment__re_enter_pin);
getLabel().setText(R.string.ConfirmKbsPinFragment__re_enter_your_pin);
break;
case PIN_DOES_NOT_MATCH:
getLabel().setText(SpanUtil.color(ContextCompat.getColor(requireContext(), R.color.red),

View File

@@ -9,8 +9,6 @@ import org.thoughtcrime.securesms.R;
public class CreateKbsPinFragment extends BaseKbsPinFragment<CreateKbsPinViewModel> {
private static final int PIN_LOCKOUT_DAYS = 7;
@Override
protected void initializeViewStates() {
CreateKbsPinFragmentArgs args = CreateKbsPinFragmentArgs.fromBundle(requireArguments());
@@ -29,18 +27,18 @@ public class CreateKbsPinFragment extends BaseKbsPinFragment<CreateKbsPinViewMod
getTitle().setText(R.string.CreateKbsPinFragment__create_a_new_pin);
if (isForgotPin) {
getDescription().setText(requireContext().getResources()
.getQuantityString(R.plurals.CreateKbsPinFragment__you_can_choose_a_new_pin_because_this_device_is_registered,
PIN_LOCKOUT_DAYS,
PIN_LOCKOUT_DAYS));
getDescription().setText(R.string.CreateKbsPinFragment__you_can_choose_a_new_pin_as_long_as_this_device_is_registered);
getDescription().setLearnMoreVisible(false);
} else {
getDescription().setText(R.string.CreateKbsPinFragment__pins_add_extra_security_to_your_account);
getDescription().setText(R.string.CreateKbsPinFragment__pins_keep_information_stored_with_signal_encrypted);
getDescription().setLearnMoreVisible(true);
}
}
private void initializeViewStatesForPinCreate() {
getTitle().setText(R.string.CreateKbsPinFragment__create_your_pin);
getDescription().setText(R.string.CreateKbsPinFragment__pins_add_extra_security_to_your_account);
getDescription().setText(R.string.CreateKbsPinFragment__pins_keep_information_stored_with_signal_encrypted);
getDescription().setLearnMoreVisible(true);
}
@Override
@@ -48,7 +46,6 @@ public class CreateKbsPinFragment extends BaseKbsPinFragment<CreateKbsPinViewMod
CreateKbsPinViewModel viewModel = ViewModelProviders.of(this).get(CreateKbsPinViewModel.class);
CreateKbsPinFragmentArgs args = CreateKbsPinFragmentArgs.fromBundle(requireArguments());
viewModel.getNavigationEvents().observe(getViewLifecycleOwner(), e -> onConfirmPin(e.getUserEntry(), e.getKeyboard(), args.getIsPinChange()));
viewModel.getKeyboard().observe(getViewLifecycleOwner(), k -> {
getLabel().setText(getLabelText(k));

View File

@@ -66,7 +66,7 @@ public final class KbsSplashFragment extends Fragment {
private void setUpRegLockDisabled() {
title.setText(R.string.KbsSplashFragment__introducing_pins);
description.setText(R.string.KbsSplashFragment__pins_add_another_level_of_security_to_your_account);
description.setText(R.string.KbsSplashFragment__pins_keep_information_stored_with_signal_encrypted);
primaryAction.setText(R.string.KbsSplashFragment__create_your_pin);
secondaryAction.setText(R.string.KbsSplashFragment__learn_more);
}

View File

@@ -138,7 +138,7 @@ public final class Megaphones {
.setMandatory(true)
.setImage(R.drawable.kbs_pin_megaphone)
.setTitle(R.string.KbsMegaphone__create_a_pin)
.setBody(R.string.KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account)
.setBody(R.string.KbsMegaphone__pins_keep_information_thats_stored_with_signal_encrytped)
.setActionButton(R.string.KbsMegaphone__create_pin, (megaphone, listener) -> {
Intent intent = CreateKbsPinActivity.getIntentForPinCreate(ApplicationDependencies.getApplication());

View File

@@ -0,0 +1,107 @@
package org.thoughtcrime.securesms.pin;
import android.content.Context;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import java.io.IOException;
import java.util.Objects;
public final class RegistrationLockV2Dialog {
private static final String TAG = Log.tag(RegistrationLockV2Dialog.class);
private RegistrationLockV2Dialog() {}
public static void showEnableDialog(@NonNull Context context, @NonNull Runnable onSuccess) {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle(R.string.RegistrationLockV2Dialog_turn_on_registration_lock)
.setView(R.layout.registration_lock_v2_dialog)
.setMessage(R.string.RegistrationLockV2Dialog_if_you_forget_your_signal_pin_when_registering_again)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.RegistrationLockV2Dialog_turn_on, null)
.create();
dialog.setOnShowListener(d -> {
ProgressBar progress = Objects.requireNonNull(dialog.findViewById(R.id.reglockv2_dialog_progress));
View positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(v -> {
progress.setIndeterminate(true);
progress.setVisibility(View.VISIBLE);
SimpleTask.run(SignalExecutors.UNBOUNDED, () -> {
try {
PinState.onEnableRegistrationLockForUserWithPin();
Log.i(TAG, "Successfully enabled registration lock.");
return true;
} catch (IOException e) {
Log.w(TAG, "Failed to enable registration lock setting.", e);
return false;
}
}, (success) -> {
progress.setVisibility(View.GONE);
if (!success) {
Toast.makeText(context, R.string.preferences_app_protection__failed_to_enable_registration_lock, Toast.LENGTH_LONG).show();
} else {
onSuccess.run();
}
dialog.dismiss();
});
});
});
dialog.show();
}
public static void showDisableDialog(@NonNull Context context, @NonNull Runnable onSuccess) {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle(R.string.RegistrationLockV2Dialog_turn_off_registration_lock)
.setView(R.layout.registration_lock_v2_dialog)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.RegistrationLockV2Dialog_turn_off, null)
.create();
dialog.setOnShowListener(d -> {
ProgressBar progress = Objects.requireNonNull(dialog.findViewById(R.id.reglockv2_dialog_progress));
View positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(v -> {
progress.setIndeterminate(true);
progress.setVisibility(View.VISIBLE);
SimpleTask.run(SignalExecutors.UNBOUNDED, () -> {
try {
PinState.onDisableRegistrationLockForUserWithPin();
Log.i(TAG, "Successfully disabled registration lock.");
return true;
} catch (IOException e) {
Log.w(TAG, "Failed to disable registration lock.", e);
return false;
}
}, (success) -> {
progress.setVisibility(View.GONE);
if (!success) {
Toast.makeText(context, R.string.preferences_app_protection__failed_to_disable_registration_lock, Toast.LENGTH_LONG).show();
} else {
onSuccess.run();
}
dialog.dismiss();
});
});
});
dialog.show();
}
}

View File

@@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
import org.thoughtcrime.securesms.lock.v2.RegistrationLockUtil;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.pin.PinState;
import org.thoughtcrime.securesms.pin.RegistrationLockV2Dialog;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
@@ -417,35 +418,16 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (boolean) newValue;
AlertDialog loading = SimpleProgressDialog.show(requireContext());
Log.i(TAG, "Getting ready to change registration lock setting to: " + value);
SimpleTask.run(SignalExecutors.UNBOUNDED, () -> {
try {
if (value) {
PinState.onEnableRegistrationLockForUserWithPin();
Log.i(TAG, "Successfully enabled registration lock.");
} else {
PinState.onDisableRegistrationLockForUserWithPin();
Log.i(TAG, "Successfully disabled registration lock.");
}
return true;
} catch (IOException e) {
Log.w(TAG, "Failed to change registration lock setting.", e);
return false;
}
}, (success) -> {
loading.dismiss();
if (value) {
RegistrationLockV2Dialog.showEnableDialog(requireContext(), () -> ((CheckBoxPreference) preference).setChecked(true));
} else {
RegistrationLockV2Dialog.showDisableDialog(requireContext(), () -> ((CheckBoxPreference) preference).setChecked(false));
}
if (!success) {
int stringRes = value ? R.string.preferences_app_protection__failed_to_enable_registration_lock
: R.string.preferences_app_protection__failed_to_disable_registration_lock;
Toast.makeText(requireContext(), stringRes, Toast.LENGTH_LONG).show();
}
});
return true;
return false;
}
}
}

View File

@@ -0,0 +1,95 @@
package org.thoughtcrime.securesms.util.views;
import android.content.Context;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ThemeUtil;
public class LearnMoreTextView extends AppCompatTextView {
private OnClickListener linkListener;
private Spannable link;
private boolean visible;
private CharSequence baseText;
public LearnMoreTextView(Context context) {
super(context);
init();
}
public LearnMoreTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setMovementMethod(LinkMovementMethod.getInstance());
ClickableSpan clickable = new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(ThemeUtil.getThemedColor(getContext(), R.attr.colorAccent));
}
@Override
public void onClick(@NonNull View widget) {
if (linkListener != null) {
linkListener.onClick(widget);
}
}
};
link = new SpannableString(getContext().getString(R.string.LearnMoreTextView_learn_more));
link.setSpan(clickable, 0, link.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
visible = true;
}
@Override
public void setText(CharSequence text, BufferType type) {
baseText = text;
setTextInternal(baseText, type);
}
@Override
public void setTextColor(int color) {
super.setTextColor(color);
}
public void setOnLinkClickListener(@Nullable OnClickListener listener) {
this.linkListener = listener;
}
public void setLearnMoreVisible(boolean visible) {
this.visible = visible;
setTextInternal(baseText, visible ? BufferType.SPANNABLE : BufferType.NORMAL);
}
private void setTextInternal(CharSequence text, BufferType type) {
if (visible) {
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(text).append(' ').append(link);
super.setText(builder, BufferType.SPANNABLE);
} else {
super.setText(text, type);
}
}
}