Detailed changes
@@ -54,6 +54,7 @@ public class Account extends AbstractEntity {
public static final int OPTION_REQUIRES_ACCESS_MODE_CHANGE = 5;
public static final int OPTION_LOGGED_IN_SUCCESSFULLY = 6;
public static final int OPTION_HTTP_UPLOAD_AVAILABLE = 7;
+ public static final int OPTION_UNVERIFIED = 8;
private static final String KEY_PGP_SIGNATURE = "pgp_signature";
private static final String KEY_PGP_ID = "pgp_id";
public final HashSet<Pair<String, String>> inProgressDiscoFetches = new HashSet<>();
@@ -32,6 +32,14 @@ public class AccountUtils {
return null;
}
+ public static Account getFirst(XmppConnectionService service) {
+ final List<Account> accounts = service.getAccounts();
+ for(Account account : accounts) {
+ return account;
+ }
+ return null;
+ }
+
public static Account getPendingAccount(XmppConnectionService service) {
Account pending = null;
for (Account account : service.getAccounts()) {
@@ -53,7 +61,7 @@ public class AccountUtils {
}
public static void launchManageAccount(XmppActivity xmppActivity) {
- Account account = getFirstEnabled(xmppActivity.xmppConnectionService);
+ Account account = getFirst(xmppActivity.xmppConnectionService);
xmppActivity.switchToAccount(account);
}
@@ -759,4 +759,9 @@
<string name="not_a_valid_phone_number">%s is not a valid phone number.</string>
<string name="please_enter_your_phone_number">Please enter your phone number.</string>
<string name="search_countries">Search countries</string>
+ <string name="verify_x">Verify %s</string>
+ <string name="we_have_sent_you_an_sms"><![CDATA[We have sent you an SMS to <b>%s</b>.]]></string>
+ <string name="please_enter_pin">Please enter the 6 digit pin below.</string>
+ <string name="resend_sms">Resend SMS</string>
+ <string name="back">back</string>
</resources>
@@ -14,5 +14,10 @@
android:label="@string/choose_a_country"
android:launchMode="singleTask" />
+ <activity
+ android:name=".ui.VerifyActivity"
+ android:launchMode="singleTask"
+ android:label="@string/verify_your_phone_number"/>
+
</application>
</manifest>
@@ -3,12 +3,14 @@ package eu.siacs.conversations.services;
import android.util.Log;
+import java.security.SecureRandom;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
import io.michaelrocks.libphonenumber.android.Phonenumber;
import rocks.xmpp.addr.Jid;
@@ -39,7 +41,9 @@ public class QuickConversationsService {
public void requestVerification(Phonenumber.PhoneNumber phoneNumber) {
String local = PhoneNumberUtilWrapper.normalize(service, phoneNumber);
Log.d(Config.LOGTAG,"requesting verification for "+PhoneNumberUtilWrapper.normalize(service,phoneNumber));
- Account account = new Account(Jid.of(local,"quick.conversations.im",null),"foo");
+ Account account = new Account(Jid.of(local,"quick.conversations.im",null), CryptoHelper.createPassword(new SecureRandom()));
+ account.setOption(Account.OPTION_DISABLED, true);
+ account.setOption(Account.OPTION_UNVERIFIED, true);
service.createAccount(account);
synchronized (mOnVerificationRequested) {
for(OnVerificationRequested onVerificationRequested : mOnVerificationRequested) {
@@ -165,6 +165,9 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
@Override
public void onVerificationRequested() {
- Log.d(Config.LOGTAG,"requested");
+ runOnUiThread(() -> {
+ startActivity(new Intent(this,VerifyActivity.class));
+ finish();
+ });
}
}
@@ -0,0 +1,54 @@
+package eu.siacs.conversations.ui;
+
+import android.content.Intent;
+import android.databinding.DataBindingUtil;
+import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
+import android.text.Html;
+import android.view.View;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.ActivityVerifyBinding;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.ui.util.PinEntryWrapper;
+import eu.siacs.conversations.utils.AccountUtils;
+import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
+
+public class VerifyActivity extends XmppActivity {
+
+ private ActivityVerifyBinding binding;
+ private Account account;
+ private PinEntryWrapper pinEntryWrapper;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_verify);
+ setSupportActionBar((Toolbar) this.binding.toolbar);
+ this.pinEntryWrapper = new PinEntryWrapper(binding.pinBox);
+ binding.back.setOnClickListener(this::onBackButton);
+ }
+
+ private void onBackButton(View view) {
+ if (this.account != null) {
+ xmppConnectionService.deleteAccount(account);
+ Intent intent = new Intent(this,EnterPhoneNumberActivity.class);
+ startActivity(intent);
+ finish();
+ }
+ }
+
+ @Override
+ protected void refreshUiReal() {
+
+ }
+
+ @Override
+ void onBackendConnected() {
+ this.account = AccountUtils.getFirst(xmppConnectionService);
+ if (this.account == null) {
+ return;
+ }
+ this.binding.weHaveSent.setText(Html.fromHtml(getString(R.string.we_have_sent_you_an_sms, PhoneNumberUtilWrapper.prettyPhoneNumber(this, this.account.getJid()))));
+ }
+}
@@ -0,0 +1,93 @@
+package eu.siacs.conversations.ui.util;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PinEntryWrapper {
+
+ private final List<EditText> digits = new ArrayList<>();
+
+ private final TextWatcher textWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ int current = -1;
+ for (int i = 0; i < digits.size(); ++i) {
+ if (s.hashCode() == digits.get(i).getText().hashCode()) {
+ current = i;
+ }
+ }
+ if (current == -1) {
+ return;
+ }
+ if (s.length() > 0) {
+ if (current < digits.size() - 1) {
+ digits.get(current + 1).requestFocus();
+ }
+ } else {
+ int focusOn = current;
+ for (int i = current - 1; i >= 0; --i) {
+ if (digits.get(i).getText().length() == 0) {
+ focusOn = i;
+ } else {
+ break;
+ }
+ }
+ digits.get(focusOn).requestFocus();
+ }
+ }
+ };
+
+ private final View.OnKeyListener keyListener = (v, keyCode, event) -> {
+ if (event.getAction() != KeyEvent.ACTION_DOWN) {
+ return false;
+ }
+ if (v instanceof EditText) {
+ final EditText editText = (EditText) v;
+ if (keyCode == KeyEvent.KEYCODE_DEL && editText.getText().length() == 0) {
+ final int current = digits.indexOf(editText);
+ for (int i = current - 1; i >= 0; --i) {
+ if (digits.get(i).getText().length() > 0) {
+ digits.get(i).getText().clear();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ };
+
+ public PinEntryWrapper(LinearLayout linearLayout) {
+ for (int i = 0; i < linearLayout.getChildCount(); ++i) {
+ View view = linearLayout.getChildAt(i);
+ if (view instanceof EditText) {
+ this.digits.add((EditText) view);
+ }
+ }
+ registerListeners();
+ }
+
+ private void registerListeners() {
+ for (EditText editText : digits) {
+ editText.addTextChangedListener(textWatcher);
+ editText.setOnKeyListener(keyListener);
+ }
+ }
+
+}
@@ -10,6 +10,7 @@ import java.util.Locale;
import io.michaelrocks.libphonenumber.android.NumberParseException;
import io.michaelrocks.libphonenumber.android.PhoneNumberUtil;
import io.michaelrocks.libphonenumber.android.Phonenumber;
+import rocks.xmpp.addr.Jid;
public class PhoneNumberUtilWrapper {
@@ -40,6 +41,16 @@ public class PhoneNumberUtilWrapper {
return locale.getCountry();
}
+ public static String prettyPhoneNumber(Context context, Jid jid) {
+ PhoneNumberUtil phoneNumberUtil = getInstance(context);
+ try {
+ Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(jid.getEscapedLocal(), "de");
+ return phoneNumberUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
+ } catch (Exception e) {
+ return jid.getEscapedLocal();
+ }
+ }
+
public static String normalize(Context context, String number) throws NumberParseException {
return normalize(context, getInstance(context).parse(number, getUserCountry(context)));
}
@@ -5,8 +5,11 @@ import android.content.Intent;
import android.util.Log;
import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.ui.ConversationsActivity;
import eu.siacs.conversations.ui.EnterPhoneNumberActivity;
+import eu.siacs.conversations.ui.StartConversationActivity;
+import eu.siacs.conversations.ui.VerifyActivity;
public class SignupUtils {
@@ -16,7 +19,18 @@ public class SignupUtils {
}
public static Intent getRedirectionIntent(ConversationsActivity activity) {
- final Intent intent = getSignUpIntent(activity);
+ final Intent intent;
+ final Account account = AccountUtils.getFirst(activity.xmppConnectionService);
+ if (account != null) {
+ if (account.isOptionSet(Account.OPTION_UNVERIFIED)) {
+ intent = new Intent(activity, VerifyActivity.class);
+ } else {
+ intent = new Intent(activity, StartConversationActivity.class);
+ }
+ } else {
+ intent = getSignUpIntent(activity);
+
+ }
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
return intent;
}
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/color_background_primary"
+ android:orientation="vertical">
+
+ <include
+ android:id="@+id/toolbar"
+ layout="@layout/toolbar"/>
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="true">
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:id="@+id/instructions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/we_have_sent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/we_have_sent_you_an_sms"
+ android:textAppearance="@style/TextAppearance.Conversations.Subhead" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/please_enter_pin"
+ android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/pin_box"
+ android:layout_width="230sp"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/instructions"
+ android:layout_centerHorizontal="true">
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <EditText
+ android:layout_width="35sp"
+ android:layout_height="wrap_content"
+ android:digits="1234567890"
+ android:inputType="number"
+ android:maxLength="1"
+ android:textSize="40sp"
+ android:gravity="center"
+ android:textIsSelectable="false"
+ />
+ </LinearLayout>
+ <Button
+ android:id="@+id/next"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ style="@style/Widget.Conversations.Button.Borderless"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/next"
+ android:textColor="?colorAccent"/>
+
+ <Button
+ android:id="@+id/back"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentStart="true"
+ style="@style/Widget.Conversations.Button.Borderless"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/back"
+ android:textColor="?android:textColorSecondary" />
+ <Button
+ android:layout_centerHorizontal="true"
+ android:layout_below="@+id/pin_box"
+ android:id="@+id/resend_sms"
+ style="@style/Widget.Conversations.Button.Borderless"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resend_sms"
+ android:textColor="?android:textColorSecondary"/>
+ </RelativeLayout>
+ </ScrollView>
+ </LinearLayout>
+</layout>