Merge branch '2309-troubleshooting-wizard' into 'master'

Troubleshooting wizard for mailbox

Closes #2309

See merge request briar/briar!1640
This commit is contained in:
akwizgran
2022-05-18 17:00:50 +00:00
11 changed files with 637 additions and 41 deletions

View File

@@ -45,6 +45,7 @@ import org.briarproject.briar.android.hotspot.QrHotspotFragment;
import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.login.SignInReminderReceiver;
import org.briarproject.briar.android.mailbox.ErrorFragment;
import org.briarproject.briar.android.mailbox.ErrorWizardFragment;
import org.briarproject.briar.android.mailbox.MailboxScanFragment;
import org.briarproject.briar.android.mailbox.MailboxStatusFragment;
import org.briarproject.briar.android.mailbox.OfflineFragment;
@@ -257,4 +258,6 @@ public interface AndroidComponent
void inject(ErrorFragment errorFragment);
void inject(MailboxStatusFragment mailboxStatusFragment);
void inject(ErrorWizardFragment errorWizardFragment);
}

View File

@@ -0,0 +1,202 @@
package org.briarproject.briar.android.mailbox;
import android.animation.ValueAnimator;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import com.google.android.material.animation.ArgbEvaluatorCompat;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.view.BriarButton;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.transition.AutoTransition;
import androidx.transition.Transition;
import static android.view.View.FOCUS_DOWN;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static androidx.core.content.ContextCompat.getColor;
import static androidx.transition.TransitionManager.beginDelayedTransition;
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ErrorWizardFragment extends Fragment {
static final String TAG = ErrorWizardFragment.class.getName();
@Inject
ViewModelProvider.Factory viewModelFactory;
private MailboxViewModel viewModel;
private ScrollView scrollView;
private ValueAnimator colorAnim;
private final Transition transition = new AutoTransition();
@Override
public void onAttach(Context context) {
super.onAttach(context);
FragmentActivity activity = requireActivity();
getAndroidComponent(activity).inject(this);
viewModel = new ViewModelProvider(activity, viewModelFactory)
.get(MailboxViewModel.class);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_mailbox_error_wizard,
container, false);
scrollView = (ScrollView) v;
int startColor =
getColor(v.getContext(), R.color.briar_accent);
int endColor = getColor(v.getContext(), R.color.window_background);
colorAnim = ValueAnimator
.ofObject(new ArgbEvaluatorCompat(), startColor, endColor);
colorAnim.setDuration(2500);
return v;
}
@Override
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
RadioGroup radioGroup1 = v.findViewById(R.id.radioGroup1);
List<RadioButton> radioButtons1 = new ArrayList<>(3);
radioButtons1.add(v.findViewById(R.id.radioButton1));
radioButtons1.add(v.findViewById(R.id.radioButton2));
radioButtons1.add(v.findViewById(R.id.radioButton3));
List<View> views1 = new ArrayList<>(3);
View info1 = v.findViewById(R.id.info1);
views1.add(info1);
views1.add(v.findViewById(R.id.info2));
View info3 = v.findViewById(R.id.info3);
views1.add(info3);
setUpRadioGroup(radioGroup1, radioButtons1, views1);
RadioGroup radioGroup1_1 = info1.findViewById(R.id.radioGroup1_1);
List<RadioButton> radioButtons1_1 = new ArrayList<>(3);
radioButtons1_1.add(info1.findViewById(R.id.radioButton1_1));
radioButtons1_1.add(info1.findViewById(R.id.radioButton1_2));
radioButtons1_1.add(info1.findViewById(R.id.radioButton1_3));
radioButtons1_1.add(info1.findViewById(R.id.radioButton1_4));
List<View> views1_1 = new ArrayList<>(3);
views1_1.add(info1.findViewById(R.id.info1_1_1));
views1_1.add(info1.findViewById(R.id.info1_1_2));
views1_1.add(info1.findViewById(R.id.info1_1_3));
views1_1.add(info1.findViewById(R.id.info1_1_4));
setUpRadioGroup(radioGroup1_1, radioButtons1_1, views1_1);
// set up unlink buttons
BriarButton button3 = info3.findViewById(R.id.button3);
BriarButton button1_1_1 = info1.findViewById(R.id.button1_1_1);
BriarButton button1_1_2 = info1.findViewById(R.id.button1_1_2);
button3.setOnClickListener(this::onUnlinkButtonClicked);
button1_1_1.setOnClickListener(this::onUnlinkButtonClicked);
button1_1_2.setOnClickListener(this::onUnlinkButtonClicked);
// set up check connection button
BriarButton button1_1_3 = info1.findViewById(R.id.button1_1_3);
button1_1_3.setOnClickListener(this::onCheckConnectionButtonClicked);
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.mailbox_error_wizard_title);
}
private void setUpRadioGroup(RadioGroup radioGroup,
List<RadioButton> radioButtons, List<View> views) {
if (radioButtons.size() != views.size()) {
throw new IllegalArgumentException();
}
radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
onCheckedChanged();
for (int i = 0; i < radioButtons.size(); i++) {
RadioButton radioButton = radioButtons.get(i);
View view = views.get(i);
if (checkedId == radioButton.getId()) {
animateColor(view);
view.setVisibility(VISIBLE);
} else {
view.setVisibility(GONE);
}
}
});
}
private void onUnlinkButtonClicked(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext(),
R.style.BriarDialogTheme);
builder.setTitle(R.string.mailbox_status_unlink_dialog_title);
builder.setMessage(R.string.mailbox_status_unlink_dialog_question);
builder.setPositiveButton(R.string.cancel,
(dialog, which) -> dialog.cancel());
builder.setNegativeButton(R.string.mailbox_status_unlink_button,
(dialog, which) -> viewModel.unlink());
builder.setOnCancelListener(dialog -> ((BriarButton) v).reset());
builder.show();
}
private void onCheckConnectionButtonClicked(View v) {
viewModel.checkConnectionFromWizard();
}
private void animateColor(View v) {
if (colorAnim.isRunning()) colorAnim.end();
colorAnim.removeAllUpdateListeners();
colorAnim.addUpdateListener(animation ->
v.setBackgroundColor((int) animation.getAnimatedValue())
);
colorAnim.start();
}
private void onCheckedChanged() {
transition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(@NonNull Transition transition) {
}
@Override
public void onTransitionEnd(@NonNull Transition transition) {
scrollView.fullScroll(FOCUS_DOWN);
}
@Override
public void onTransitionCancel(@NonNull Transition transition) {
}
@Override
public void onTransitionPause(@NonNull Transition transition) {
}
@Override
public void onTransitionResume(@NonNull Transition transition) {
}
});
beginDelayedTransition(scrollView, transition);
}
}

View File

@@ -17,6 +17,7 @@ import org.briarproject.bramble.api.mailbox.MailboxStatus;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.view.BriarButton;
import javax.inject.Inject;
@@ -29,6 +30,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static androidx.core.content.ContextCompat.getColor;
@@ -38,6 +40,7 @@ import static org.briarproject.briar.android.AppModule.getAndroidComponent;
import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION;
import static org.briarproject.briar.android.util.UiUtils.formatDate;
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
import static org.briarproject.briar.android.util.UiUtils.showFragment;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -58,6 +61,7 @@ public class MailboxStatusFragment extends Fragment {
private ImageView imageView;
private TextView statusTitleView;
private TextView statusInfoView;
private Button wizardButton;
private Button unlinkButton;
private ProgressBar unlinkProgress;
@@ -83,18 +87,11 @@ public class MailboxStatusFragment extends Fragment {
public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
Button checkButton = v.findViewById(R.id.checkButton);
ProgressBar checkProgress = v.findViewById(R.id.checkProgress);
checkButton.setOnClickListener(view -> {
beginDelayedTransition((ViewGroup) v);
checkButton.setVisibility(INVISIBLE);
checkProgress.setVisibility(VISIBLE);
observeOnce(viewModel.checkConnection(), this, result -> {
beginDelayedTransition((ViewGroup) v);
checkButton.setVisibility(VISIBLE);
checkProgress.setVisibility(INVISIBLE);
});
});
BriarButton checkButton = v.findViewById(R.id.checkButton);
checkButton.setOnClickListener(view ->
observeOnce(viewModel.checkConnection(), this, result ->
checkButton.reset()
));
imageView = v.findViewById(R.id.imageView);
statusTitleView = v.findViewById(R.id.statusTitleView);
@@ -102,8 +99,13 @@ public class MailboxStatusFragment extends Fragment {
viewModel.getStatus()
.observe(getViewLifecycleOwner(), this::onMailboxStateChanged);
// TODO
// * Implement UI for warning user when mailbox is unreachable #2175
wizardButton = v.findViewById(R.id.wizardButton);
wizardButton.setOnClickListener(view -> {
Fragment f = new ErrorWizardFragment();
String tag = ErrorWizardFragment.TAG;
showFragment(getParentFragmentManager(), f, tag, false);
});
unlinkButton = v.findViewById(R.id.unlinkButton);
unlinkProgress = v.findViewById(R.id.unlinkProgress);
unlinkButton.setOnClickListener(view ->
@@ -135,16 +137,19 @@ public class MailboxStatusFragment extends Fragment {
title = getString(R.string.mailbox_status_connected_title);
tintRes = R.color.briar_brand_green;
showUnlinkWarning = true;
wizardButton.setVisibility(GONE);
} else if (status.getAttemptsSinceSuccess() < NUM_FAILURES) {
iconRes = R.drawable.ic_help_outline_white;
title = getString(R.string.mailbox_status_problem_title);
tintRes = R.color.briar_orange_500;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
} else {
tintRes = R.color.briar_red_500;
title = getString(R.string.mailbox_status_failure_title);
iconRes = R.drawable.alerts_and_states_error;
showUnlinkWarning = false;
wizardButton.setVisibility(VISIBLE);
}
imageView.setImageResource(iconRes);
int color = getColor(requireContext(), tintRes);

View File

@@ -204,21 +204,39 @@ class MailboxViewModel extends DbViewModel
LiveData<Boolean> checkConnection() {
MutableLiveData<Boolean> liveData = new MutableLiveData<>();
checkConnection(success -> {
liveData.postValue(success);
if (!success) onConnectionCheckFailure();
});
return liveData;
}
void checkConnectionFromWizard() {
checkConnection(success -> {
if (!success) onConnectionCheckFailure();
boolean isOnline = isTorActive();
// make UI move back to status fragment by changing pairingState
pairingState.postEvent(new MailboxState.IsPaired(isOnline));
});
}
private void checkConnection(@IoExecutor Consumer<Boolean> consumer) {
ioExecutor.execute(() -> {
boolean success = mailboxManager.checkConnection();
if (LOG.isLoggable(INFO)) {
LOG.info("Got result from connection check: " + success);
}
liveData.postValue(success);
if (!success) { // force failure screen
MailboxStatus lastStatus = status.getValue();
long lastSuccess = lastStatus == null ?
-1 : lastStatus.getTimeOfLastSuccess();
long now = System.currentTimeMillis();
status.postValue(new MailboxStatus(now, lastSuccess, 999));
}
consumer.accept(success);
});
return liveData;
}
private void onConnectionCheckFailure() {
MailboxStatus lastStatus = status.getValue();
long lastSuccess = lastStatus == null ?
-1 : lastStatus.getTimeOfLastSuccess();
long now = System.currentTimeMillis();
// force failure screen
status.postValue(new MailboxStatus(now, lastSuccess, 999));
}
@UiThread

View File

@@ -0,0 +1,75 @@
package org.briarproject.briar.android.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.AppCompatButton;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
import static androidx.transition.TransitionManager.beginDelayedTransition;
@NotNullByDefault
public class BriarButton extends FrameLayout {
private final Button button;
private final ProgressBar progressBar;
public BriarButton(Context context) {
this(context, null);
}
public BriarButton(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BriarButton(Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.briar_button, this, true);
TypedArray attributes =
context.obtainStyledAttributes(attrs, R.styleable.BriarButton);
String text = attributes.getString(R.styleable.BriarButton_text);
int style = attributes
.getResourceId(R.styleable.BriarButton_buttonStyle, 0);
attributes.recycle();
ContextThemeWrapper wrapper = new ContextThemeWrapper(context, style);
button = new AppCompatButton(wrapper, null, style);
button.setText(text);
addView(button);
progressBar = findViewById(R.id.briar_button_progress_bar);
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
if (l == null) button.setOnClickListener(null);
else {
button.setOnClickListener(v -> {
beginDelayedTransition(this);
progressBar.setVisibility(VISIBLE);
button.setVisibility(INVISIBLE);
l.onClick(this);
});
}
}
public void reset() {
beginDelayedTransition(this);
progressBar.setVisibility(INVISIBLE);
button.setVisibility(VISIBLE);
}
}

View File

@@ -0,0 +1,17 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:layout_height="wrap_content"
tools:layout_width="wrap_content"
tools:parentTag="android.widget.FrameLayout">
<!-- Button gets added programmatically so we can pass on the styles -->
<ProgressBar
android:id="@+id/briar_button_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
tools:visibility="visible" />
</merge>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".android.mailbox.MailboxActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/question1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_question1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/mailbox_error_wizard_answer1" />
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/mailbox_error_wizard_answer2" />
<RadioButton
android:id="@+id/radioButton3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/mailbox_error_wizard_answer3" />
</RadioGroup>
<include
android:id="@+id/info1"
layout="@layout/fragment_mailbox_error_wizard_access"
android:visibility="gone" />
<TextView
android:id="@+id/info2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info2"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/info3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info3"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<org.briarproject.briar.android.view.BriarButton
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:buttonStyle="@style/BriarButtonFlat.Negative"
app:text="@string/mailbox_status_unlink_button" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".android.mailbox.MailboxActivity">
<TextView
android:id="@+id/info1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info1_1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<TextView
android:id="@+id/question1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_question1_1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<RadioGroup
android:id="@+id/radioGroup1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp">
<RadioButton
android:id="@+id/radioButton1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/mailbox_error_wizard_answer1_1" />
<RadioButton
android:id="@+id/radioButton1_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/mailbox_error_wizard_answer1_2" />
<RadioButton
android:id="@+id/radioButton1_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/mailbox_error_wizard_answer1_3" />
<RadioButton
android:id="@+id/radioButton1_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/mailbox_error_wizard_answer1_4" />
</RadioGroup>
<LinearLayout
android:id="@+id/info1_1_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info1_1_1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<org.briarproject.briar.android.view.BriarButton
android:id="@+id/button1_1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:buttonStyle="@style/BriarButtonFlat.Negative"
app:text="@string/mailbox_status_unlink_button" />
</LinearLayout>
<LinearLayout
android:id="@+id/info1_1_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info_1_1_2"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<org.briarproject.briar.android.view.BriarButton
android:id="@+id/button1_1_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:buttonStyle="@style/BriarButtonFlat.Negative"
app:text="@string/mailbox_status_unlink_button" />
</LinearLayout>
<LinearLayout
android:id="@+id/info1_1_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info1_1_3"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
<org.briarproject.briar.android.view.BriarButton
android:id="@+id/button1_1_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:buttonStyle="@style/BriarButtonFlat.Positive"
app:text="@string/mailbox_status_check_button" />
</LinearLayout>
<LinearLayout
android:id="@+id/info1_1_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/mailbox_error_wizard_info1_1_4"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
</LinearLayout>
</LinearLayout>

View File

@@ -37,28 +37,17 @@
app:layout_constraintTop_toBottomOf="@+id/imageView"
tools:text="@string/mailbox_status_problem_title" />
<Button
<org.briarproject.briar.android.view.BriarButton
android:id="@+id/checkButton"
style="@style/BriarButtonFlat.Neutral"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/mailbox_status_check_button"
app:buttonStyle="@style/BriarButtonFlat.Neutral"
app:layout_constraintBottom_toTopOf="@+id/statusInfoView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/statusTitleView" />
<ProgressBar
android:id="@+id/checkProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/checkButton"
app:layout_constraintEnd_toEndOf="@+id/checkButton"
app:layout_constraintStart_toStartOf="@+id/checkButton"
app:layout_constraintTop_toTopOf="@+id/checkButton"
tools:visibility="visible" />
app:layout_constraintTop_toBottomOf="@+id/statusTitleView"
app:text="@string/mailbox_status_check_button" />
<TextView
android:id="@+id/statusInfoView"
@@ -72,6 +61,22 @@
app:layout_constraintTop_toBottomOf="@+id/checkButton"
tools:text="@string/mailbox_status_connected_info" />
<Button
android:id="@+id/wizardButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/mailbox_error_wizard_button"
android:visibility="gone"
app:drawableTint="@color/briar_button_text_positive"
app:layout_constraintBottom_toTopOf="@+id/unlinkButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/statusInfoView"
app:layout_constraintVertical_bias="0.0"
tools:visibility="visible" />
<Button
android:id="@+id/unlinkButton"
style="@style/BriarButtonFlat.Negative"

View File

@@ -37,14 +37,19 @@
<declare-styleable name="LargeTextInputView">
<attr name="buttonText" format="string"/>
<attr name="maxLines" format="integer"/>
<attr name="fillHeight" format="boolean"/>
<attr name="fillHeight" format="boolean" />
</declare-styleable>
<declare-styleable name="UnreadMessageButton">
<attr name="direction" format="enum">
<enum name="up" value="0"/>
<enum name="down" value="1"/>
<enum name="up" value="0" />
<enum name="down" value="1" />
</attr>
</declare-styleable>
<declare-styleable name="BriarButton">
<attr name="text" format="string" />
<attr name="buttonStyle" format="reference" />
</declare-styleable>
</resources>

View File

@@ -652,6 +652,28 @@
<string name="mailbox_status_unlink_no_wipe_title">Your Mailbox has been unlinked</string>
<string name="mailbox_status_unlink_no_wipe_message">Next time you have access to your Mailbox device, please open the Mailbox app and tap the \"Unlink\" button to complete the process.\n\nIf you no longer have access to your Mailbox device, don\'t worry. Your data is encrypted so it will remain secure even if you don\'t complete the process.</string>
<string name="mailbox_error_wizard_button">Fix problem</string>
<string name="mailbox_error_wizard_title">Mailbox troubleshooting wizard</string>
<string name="mailbox_error_wizard_question1">Do you have access to your Mailbox device?</string>
<string name="mailbox_error_wizard_answer1">Yes, I have access to it right now.</string>
<string name="mailbox_error_wizard_answer2">Not right now, but I can get access to it later.</string>
<string name="mailbox_error_wizard_answer3">No, I no longer have access to it.</string>
<string name="mailbox_error_wizard_info1_1">Check that the Mailbox device is turned on and connected to the Internet.</string>
<string name="mailbox_error_wizard_question1_1">Open the Mailbox app. What do you see?</string>
<string name="mailbox_error_wizard_answer1_1">I see instructions for setting up the Mailbox</string>
<string name="mailbox_error_wizard_answer1_2">I see a QR code</string>
<string name="mailbox_error_wizard_answer1_3">I see \"Mailbox is running\"</string>
<string name="mailbox_error_wizard_answer1_4">I see \"Device offline\"</string>
<string name="mailbox_error_wizard_info1_1_1">Please unlink your Mailbox using the button below, then follow the instructions on the Mailbox device to link it again.</string>
<string name="mailbox_error_wizard_info_1_1_2">Please unlink your Mailbox using the button below, then scan the QR code to link it again.</string>
<string name="mailbox_error_wizard_info1_1_3">Please use the button below to check the connection between Briar and the Mailbox.\n\n
If the connection fails again:\n
\u2022 Check that the Mailbox and Briar apps are updated to the latest version.\n
\u2022 Restart your Mailbox and Briar devices and try again.</string>
<string name="mailbox_error_wizard_info1_1_4">Check that the mailbox device is properly connected to the Internet.\n\nCheck that the clock on the Mailbox device shows the right time, date and timezone.\n\nCheck that the Mailbox and Briar apps are updated to the latest version.\n\nRestart your Mailbox and Briar devices and try again.</string>
<string name="mailbox_error_wizard_info2">Please come back to this screen when you have access to the device.</string>
<string name="mailbox_error_wizard_info3">Please unlink your mailbox using the button below.\n\nAfter unlinking your old Mailbox, you can set up a new Mailbox at any time.</string>
<!-- Conversation Settings -->
<string name="disappearing_messages_title">Disappearing messages</string>
<string name="disappearing_messages_explanation_long">Turning on this setting will make new