Show mailbox onboarding/download info

if the mailbox is not yet set up.
This commit is contained in:
Torsten Grote
2022-02-08 11:32:41 -03:00
parent 8b3dae6daf
commit e14773985d
17 changed files with 882 additions and 10 deletions

View File

@@ -46,6 +46,7 @@ import org.briarproject.briar.android.login.ChangePasswordActivity;
import org.briarproject.briar.android.login.OpenDatabaseFragment;
import org.briarproject.briar.android.login.PasswordFragment;
import org.briarproject.briar.android.login.StartupActivity;
import org.briarproject.briar.android.mailbox.MailboxActivity;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import org.briarproject.briar.android.navdrawer.TransportsActivity;
import org.briarproject.briar.android.panic.PanicPreferencesActivity;
@@ -250,4 +251,6 @@ public interface ActivityComponent {
void inject(RssFeedDeleteFeedDialogFragment fragment);
void inject(ConnectViaBluetoothActivity connectViaBluetoothActivity);
void inject(MailboxActivity mailboxActivity);
}

View File

@@ -0,0 +1,75 @@
package org.briarproject.briar.android.mailbox;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.ProgressBar;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class MailboxActivity extends BriarActivity {
@Inject
ViewModelProvider.Factory viewModelFactory;
private MailboxViewModel viewModel;
private ProgressBar progressBar;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(MailboxViewModel.class);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mailbox);
progressBar = findViewById(R.id.progressBar);
if (viewModel.getState().getValue() == null) {
progressBar.setVisibility(VISIBLE);
}
if (savedInstanceState == null) {
viewModel.getState().observe(this, state -> {
if (state instanceof MailboxState.NotSetup) {
onNotSetup();
}
});
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void onNotSetup() {
progressBar.setVisibility(INVISIBLE);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragmentContainer, new SetupIntroFragment(),
SetupIntroFragment.TAG)
.commit();
}
}

View File

@@ -12,8 +12,7 @@ public interface MailboxModule {
@Binds
@IntoMap
@ViewModelKey(MailboxPairViewModel.class)
ViewModel bindMailboxViewModel(
MailboxPairViewModel mailboxPairViewModel);
@ViewModelKey(MailboxViewModel.class)
ViewModel bindMailboxViewModel(MailboxViewModel mailboxViewModel);
}

View File

@@ -0,0 +1,10 @@
package org.briarproject.briar.android.mailbox;
class MailboxState {
static class NotSetup extends MailboxState {
}
// TODO add other states
}

View File

@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
import org.briarproject.briar.android.viewmodel.DbViewModel;
@@ -24,32 +25,35 @@ import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@UiThread
@NotNullByDefault
class MailboxPairViewModel extends DbViewModel
class MailboxViewModel extends DbViewModel
implements QrCodeDecoder.ResultCallback {
private static final Logger LOG =
getLogger(MailboxPairViewModel.class.getName());
private static final int VERSION_REQUIRED = 32;
private static final Logger LOG =
getLogger(MailboxViewModel.class.getName());
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
private static final int VERSION_REQUIRED = 32;
private final CryptoComponent crypto;
private final QrCodeDecoder qrCodeDecoder;
private final MutableLiveData<MailboxState> state = new MutableLiveData<>();
@Nullable
private String onionAddress = null;
@Nullable
private String setupToken = null;
@Inject
MailboxPairViewModel(
MailboxViewModel(
Application app,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
@@ -60,9 +64,29 @@ class MailboxPairViewModel extends DbViewModel
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
this.crypto = crypto;
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
checkIfSetup();
}
@UiThread
private void checkIfSetup() {
runOnDbThread(() -> {
// TODO really check if mailbox is setup/paired/linked
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
state.postValue(new NotSetup());
});
}
@UiThread
LiveData<MailboxState> getState() {
return state;
}
@Override
@IoExecutor
public void onQrCodeDecoded(Result result) {
LOG.info("Got result from decoder");
byte[] bytes = result.getText().getBytes(ISO_8859_1);

View File

@@ -0,0 +1,76 @@
package org.briarproject.briar.android.mailbox;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import static android.content.Intent.ACTION_SEND;
import static android.content.Intent.EXTRA_TEXT;
import static android.widget.Toast.LENGTH_LONG;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class SetupDownloadFragment extends Fragment {
static final String TAG = SetupDownloadFragment.class.getName();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_mailbox_setup_download,
container, false);
Button shareLinkButton = v.findViewById(R.id.shareLinkButton);
Button scanButton = v.findViewById(R.id.scanButton);
shareLinkButton.setOnClickListener(this::shareLink);
scanButton.setOnClickListener(this::scanCode);
return v;
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.mailbox_setup_title);
}
private void shareLink(View v) {
Context ctx = requireContext();
String fdroid = ctx.getString(R.string.mailbox_share_fdroid);
String gplay = ctx.getString(R.string.mailbox_share_gplay);
String download = ctx.getString(R.string.mailbox_share_download);
String text = ctx.getString(R.string.mailbox_share_text, fdroid, gplay,
download);
Intent sendIntent = new Intent();
sendIntent.setAction(ACTION_SEND);
sendIntent.putExtra(EXTRA_TEXT, text);
sendIntent.setType("text/plain");
Intent shareIntent = Intent.createChooser(sendIntent, null);
try {
startActivity(shareIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG)
.show();
}
}
private void scanCode(View v) {
Toast.makeText(requireContext(), "TODO", LENGTH_LONG).show();
}
}

View File

@@ -0,0 +1,47 @@
package org.briarproject.briar.android.mailbox;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import static org.briarproject.briar.android.util.UiUtils.showFragment;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class SetupIntroFragment extends Fragment {
static final String TAG = SetupIntroFragment.class.getName();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_mailbox_setup_intro,
container, false);
Button button = v.findViewById(R.id.continueButton);
button.setOnClickListener(view -> {
FragmentManager fm = getParentFragmentManager();
Fragment f = new SetupDownloadFragment();
showFragment(fm, f, SetupDownloadFragment.TAG);
});
return v;
}
@Override
public void onStart() {
super.onStart();
requireActivity().setTitle(R.string.mailbox_setup_title);
}
}

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.android.settings;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
@@ -8,6 +9,7 @@ import android.view.View;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.mailbox.MailboxActivity;
import org.briarproject.briar.android.util.ActivityLaunchers.GetImageAdvanced;
import javax.inject.Inject;
@@ -74,7 +76,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
requireNonNull(findPreference(PREF_KEY_MAILBOX));
if (viewModel.shouldEnableMailbox()) {
prefMailbox.setOnPreferenceClickListener(preference -> {
// TODO show mailbox status/onboarding
Intent i = new Intent(requireContext(), MailboxActivity.class);
startActivity(i);
return true;
});
} else {