added magic create welcome screen

Daniel Gultsch created

Change summary

art/render.rb                                                            |   1 
src/main/AndroidManifest.xml                                             |  16 
src/main/java/eu/siacs/conversations/Config.java                         |   1 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  12 
src/main/java/eu/siacs/conversations/ui/ConversationActivity.java        |  13 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java         |   4 
src/main/java/eu/siacs/conversations/ui/MagicCreateActivity.java         | 113 
src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java             |  37 
src/main/res/drawable-hdpi/main_logo.png                                 |   0 
src/main/res/drawable-mdpi/main_logo.png                                 |   0 
src/main/res/drawable-xhdpi/main_logo.png                                |   0 
src/main/res/drawable-xxhdpi/main_logo.png                               |   0 
src/main/res/drawable-xxxhdpi/main_logo.png                              |   0 
src/main/res/layout/magic_create.xml                                     |  83 
src/main/res/layout/welcome.xml                                          |  69 
src/main/res/values/strings.xml                                          |   7 
16 files changed, 349 insertions(+), 7 deletions(-)

Detailed changes

art/render.rb πŸ”—

@@ -12,6 +12,7 @@ resolutions = {
 
 images = {
 	'conversations_baloon.svg' => ['ic_launcher', 48],
+   'conversations_baloon.svg' => ['main_logo', 200],
 	'conversations_mono.svg' => ['ic_notification', 24],
 	'ic_received_indicator.svg' => ['ic_received_indicator', 12],
 	'ic_send_text_offline.svg' => ['ic_send_text_offline', 36],

src/main/AndroidManifest.xml πŸ”—

@@ -77,6 +77,16 @@
                 <data android:scheme="xmpp"/>
             </intent-filter>
         </activity>
+        <activity
+            android:name=".ui.WelcomeActivity"
+            android:label="@string/app_name"
+            android:screenOrientation="portrait"
+            android:launchMode="singleTask"/>
+        <activity
+            android:name=".ui.MagicCreateActivity"
+            android:label="@string/create_account"
+            android:screenOrientation="portrait"
+            android:launchMode="singleTask"/>
         <activity
             android:name=".ui.SettingsActivity"
             android:label="@string/title_activity_settings"/>
@@ -139,7 +149,7 @@
             </intent-filter>
             <meta-data
                 android:name="android.service.chooser.chooser_target_service"
-                android:value=".services.ContactChooserTargetService" />
+                android:value=".services.ContactChooserTargetService"/>
         </activity>
         <activity
             android:name=".ui.TrustKeysActivity"
@@ -157,12 +167,12 @@
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value="eu.siacs.conversations.ui.SettingsActivity"/>
         </activity>
-        <activity android:name="com.soundcloud.android.crop.CropImageActivity" />
+        <activity android:name="com.soundcloud.android.crop.CropImageActivity"/>
         <service android:name=".services.ExportLogsService"/>
         <service android:name=".services.ContactChooserTargetService"
                  android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
             <intent-filter>
-                <action android:name="android.service.chooser.ChooserTargetService" />
+                <action android:name="android.service.chooser.ChooserTargetService"/>
             </intent-filter>
         </service>
     </application>

src/main/java/eu/siacs/conversations/Config.java πŸ”—

@@ -38,6 +38,7 @@ public final class Config {
 
 
 	public static final String DOMAIN_LOCK = null; //only allow account creation for this domain
+	public static final String MAGIC_CREATE_DOMAIN = null;
 	public static final String CONFERENCE_DOMAIN_LOCK = null; //only allow conference creation for this domain
 	public static final boolean LOCK_DOMAINS_IN_CONVERSATIONS = false; //only add contacts and conferences for own domains
 

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java πŸ”—

@@ -3217,6 +3217,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		return mPushManagementService;
 	}
 
+	public Account getPendingAccount() {
+		Account pending = null;
+		for(Account account : getAccounts()) {
+			if (account.isOptionSet(Account.OPTION_REGISTER)) {
+				pending = account;
+			} else {
+				return null;
+			}
+		}
+		return pending;
+	}
+
 	public interface OnMamPreferencesFetched {
 		void onPreferencesFetched(Element prefs);
 		void onPreferencesFetchFailed();

src/main/java/eu/siacs/conversations/ui/ConversationActivity.java πŸ”—

@@ -1125,6 +1125,8 @@ public class ConversationActivity extends XmppActivity
 			if (mRedirected.compareAndSet(false, true)) {
 				if (Config.X509_VERIFICATION) {
 					startActivity(new Intent(this, ManageAccountActivity.class));
+				} else if (Config.MAGIC_CREATE_DOMAIN != null) {
+					startActivity(new Intent(this, WelcomeActivity.class));
 				} else {
 					startActivity(new Intent(this, EditAccountActivity.class));
 				}
@@ -1132,9 +1134,14 @@ public class ConversationActivity extends XmppActivity
 			}
 		} else if (conversationList.size() <= 0) {
 			if (mRedirected.compareAndSet(false, true)) {
-				Intent intent = new Intent(this, StartConversationActivity.class);
-				intent.putExtra("init", true);
-				startActivity(intent);
+				Account pendingAccount = xmppConnectionService.getPendingAccount();
+				if (pendingAccount == null) {
+					Intent intent = new Intent(this, StartConversationActivity.class);
+					intent.putExtra("init", true);
+					startActivity(intent);
+				} else {
+					switchToAccount(pendingAccount, true);
+				}
 				finish();
 			}
 		} else if (getIntent() != null && VIEW_CONVERSATION.equals(getIntent().getType())) {

src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java πŸ”—

@@ -546,7 +546,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
 				}
 				updateAccountInformation(true);
 			}
-		} else if (this.xmppConnectionService.getAccounts().size() == 0) {
+		}
+		if (this.xmppConnectionService.getAccounts().size() == 0
+				|| this.mAccount == xmppConnectionService.getPendingAccount()) {
 			if (getActionBar() != null) {
 				getActionBar().setDisplayHomeAsUpEnabled(false);
 				getActionBar().setDisplayShowHomeEnabled(false);

src/main/java/eu/siacs/conversations/ui/MagicCreateActivity.java πŸ”—

@@ -0,0 +1,113 @@
+package eu.siacs.conversations.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.security.SecureRandom;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.xmpp.jid.InvalidJidException;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
+public class MagicCreateActivity extends XmppActivity implements TextWatcher {
+
+	private TextView mFullJidDisplay;
+	private EditText mUsername;
+	private SecureRandom mRandom;
+
+	private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456780+-/#$!?";
+	private static final int PW_LENGTH = 10;
+
+	@Override
+	protected void refreshUiReal() {
+
+	}
+
+	@Override
+	void onBackendConnected() {
+
+	}
+
+	@Override
+	protected void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.magic_create);
+		mFullJidDisplay = (TextView) findViewById(R.id.full_jid);
+		mUsername = (EditText) findViewById(R.id.username);
+		mRandom = new SecureRandom();
+		Button next = (Button) findViewById(R.id.create_account);
+		next.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				String username = mUsername.getText().toString();
+				if (username.contains("@") || username.length() < 3) {
+					mUsername.setError(getString(R.string.invalid_username));
+					mUsername.requestFocus();
+				} else {
+					mUsername.setError(null);
+					try {
+						Jid jid = Jid.fromParts(username.toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null);
+						Account account = xmppConnectionService.findAccountByJid(jid);
+						if (account == null) {
+							account = new Account(jid, createPassword());
+							account.setOption(Account.OPTION_REGISTER, true);
+							account.setOption(Account.OPTION_DISABLED, true);
+							xmppConnectionService.createAccount(account);
+						}
+						Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class);
+						intent.putExtra("jid", account.getJid().toBareJid().toString());
+						intent.putExtra("init", true);
+						intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+						startActivity(intent);
+					} catch (InvalidJidException e) {
+						mUsername.setError(getString(R.string.invalid_username));
+						mUsername.requestFocus();
+					}
+				}
+			}
+		});
+		mUsername.addTextChangedListener(this);
+	}
+
+	private String createPassword() {
+		StringBuilder builder = new StringBuilder(PW_LENGTH);
+		for(int i = 0; i < PW_LENGTH; ++i) {
+			builder.append(CHARS.charAt(mRandom.nextInt(CHARS.length() - 1)));
+		}
+		return builder.toString();
+	}
+
+	@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) {
+		if (s.toString().trim().length() > 0) {
+			try {
+				mFullJidDisplay.setVisibility(View.VISIBLE);
+				Jid jid = Jid.fromParts(s.toString().toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null);
+				mFullJidDisplay.setText(getString(R.string.your_full_jid_will_be, jid.toString()));
+			} catch (InvalidJidException e) {
+				mFullJidDisplay.setVisibility(View.INVISIBLE);
+			}
+
+		} else {
+			mFullJidDisplay.setVisibility(View.INVISIBLE);
+		}
+	}
+}

src/main/java/eu/siacs/conversations/ui/WelcomeActivity.java πŸ”—

@@ -0,0 +1,37 @@
+package eu.siacs.conversations.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import eu.siacs.conversations.R;
+
+public class WelcomeActivity extends Activity {
+
+	@Override
+	protected void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.welcome);
+		final Button createAccount = (Button) findViewById(R.id.create_account);
+		createAccount.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				Intent intent = new Intent(WelcomeActivity.this, MagicCreateActivity.class);
+				intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+				startActivity(intent);
+			}
+		});
+		final Button useOwnProvider = (Button) findViewById(R.id.use_own_provider);
+		useOwnProvider.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				startActivity(new Intent(WelcomeActivity.this, EditAccountActivity.class));
+				finish();
+			}
+		});
+
+	}
+
+}

src/main/res/layout/magic_create.xml πŸ”—

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:fillViewport="true">
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/grey50">
+
+        <LinearLayout
+            android:id="@+id/linearLayout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:minHeight="256dp"
+            android:orientation="vertical"
+            android:paddingBottom="8dp"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp">
+            <Space
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/pick_your_username"
+                android:textColor="@color/black87"
+                android:textSize="?attr/TextSizeHeadline"
+                android:textStyle="bold"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:text="@string/magic_create_text"
+                android:textColor="@color/black87"
+                android:textSize="?attr/TextSizeBody"/>
+            <EditText
+                android:id="@+id/username"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:hint="@string/username_hint"
+                android:inputType="textNoSuggestions"
+                android:textSize="?attr/TextSizeBody"/>
+            <TextView
+                android:id="@+id/full_jid"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:text="@string/your_full_jid_will_be"
+                android:textColor="@color/black54"
+                android:textSize="?attr/TextSizeInfo"
+                android:visibility="invisible"/>
+            <Button
+                android:id="@+id/create_account"
+                style="?android:attr/borderlessButtonStyle"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:text="@string/next"
+                android:textColor="@color/accent"/>
+        </LinearLayout>
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_above="@+id/linearLayout"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_alignParentTop="true">
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerHorizontal="true"
+                android:layout_centerVertical="true"
+                android:padding="8dp"
+                android:src="@drawable/main_logo"/>
+        </RelativeLayout>
+    </RelativeLayout>
+</ScrollView>

src/main/res/layout/welcome.xml πŸ”—

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+android:background="@color/grey50">
+
+    <LinearLayout
+        android:id="@+id/linearLayout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true"
+        android:orientation="vertical"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
+        android:paddingBottom="8dp"
+        android:minHeight="256dp">
+        <Space
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/welcome_header"
+            android:textColor="@color/black87"
+            android:textSize="?attr/TextSizeHeadline"
+            android:textStyle="bold"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:text="@string/welcome_text"
+            android:textColor="@color/black87"
+            android:textSize="?attr/TextSizeBody"/>
+        <Button
+            android:id="@+id/create_account"
+            style="?android:attr/borderlessButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="right"
+            android:text="@string/create_account"
+            android:textColor="@color/accent"/>
+        <Button
+            android:id="@+id/use_own_provider"
+            style="?android:attr/borderlessButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="right"
+            android:text="@string/use_own_provider"
+            android:textColor="@color/black54"/>
+    </LinearLayout>
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_above="@+id/linearLayout"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true">
+        <ImageView
+            android:padding="8dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:src="@drawable/main_logo"/>
+    </RelativeLayout>
+</RelativeLayout>

src/main/res/values/strings.xml πŸ”—

@@ -618,4 +618,11 @@
 	<string name="security_error_invalid_file_access">Security error: Invalid file access</string>
 	<string name="no_application_to_share_uri">No application found to share URI</string>
 	<string name="share_uri_with">Share URI with…</string>
+	<string name="welcome_header">Join the Conversation</string>
+	<string name="welcome_text">XMPP is a provider independent protocol. You can use this client with what ever XMPP server you choose.\nHowever for your convenience we made it easy to create an account on conversations.im; a provider specially suited for the use with Conversations.</string>
+	<string name="magic_create_text">We will guide you through the process of creating an account on conversations.im.\nWhen picking conversations.im as a provider you will be able to communicate with users of other providers by giving them your full Jabber ID.</string>
+	<string name="your_full_jid_will_be">Your full Jabber ID will be: %s</string>
+	<string name="create_account">Create Account</string>
+	<string name="use_own_provider">Use my own provider</string>
+	<string name="pick_your_username">Pick your username</string>
 </resources>