added interface to edit nick
This commit is contained in:
		
							parent
							
								
									aca4ba981f
								
							
						
					
					
						commit
						5012ff3545
					
				| 
						 | 
				
			
			@ -2,6 +2,7 @@ package eu.siacs.conversations.entities;
 | 
			
		|||
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
import android.support.annotation.Nullable;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
| 
						 | 
				
			
			@ -380,7 +381,12 @@ public class MucOptions {
 | 
			
		|||
        } else if (!conversation.getJid().isBareJid()) {
 | 
			
		||||
            return conversation.getJid().getResource();
 | 
			
		||||
        } else {
 | 
			
		||||
            final String displayName = account.getDisplayName();
 | 
			
		||||
            if (TextUtils.isEmpty(displayName)) {
 | 
			
		||||
                return JidHelper.localPartOrFallback(account.getJid());
 | 
			
		||||
            } else {
 | 
			
		||||
                return displayName;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ public abstract class AbstractGenerator {
 | 
			
		|||
			"http://jabber.org/protocol/caps",
 | 
			
		||||
			"http://jabber.org/protocol/disco#info",
 | 
			
		||||
			"urn:xmpp:avatar:metadata+notify",
 | 
			
		||||
			"http://jabber.org/protocol/nick+notify",
 | 
			
		||||
			Namespace.NICK+"+notify",
 | 
			
		||||
			Namespace.BOOKMARKS+"+notify",
 | 
			
		||||
			"urn:xmpp:ping",
 | 
			
		||||
			"jabber:iq:version",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,8 +127,15 @@ public class IqGenerator extends AbstractGenerator {
 | 
			
		|||
 | 
			
		||||
	public IqPacket publishNick(String nick) {
 | 
			
		||||
		final Element item = new Element("item");
 | 
			
		||||
		item.addChild("nick", "http://jabber.org/protocol/nick").setContent(nick);
 | 
			
		||||
		return publish("http://jabber.org/protocol/nick", item);
 | 
			
		||||
		item.addChild("nick", Namespace.NICK).setContent(nick);
 | 
			
		||||
		return publish(Namespace.NICK, item);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public IqPacket deleteNode(String node) {
 | 
			
		||||
		IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
 | 
			
		||||
		final Element pubsub = packet.addChild("pubsub", Namespace.PUBSUB_OWNER);
 | 
			
		||||
		pubsub.addChild("delete").setAttribute("node",node);
 | 
			
		||||
		return packet;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public IqPacket publishAvatar(Avatar avatar) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -194,16 +194,11 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 | 
			
		|||
                    mXmppConnectionService.fetchAvatar(account, avatar);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
		} else if ("http://jabber.org/protocol/nick".equals(node)) {
 | 
			
		||||
        } else if (Namespace.NICK.equals(node)) {
 | 
			
		||||
            final Element i = items.findChild("item");
 | 
			
		||||
            final String nick = i == null ? null : i.findChildContent("nick", Namespace.NICK);
 | 
			
		||||
            if (nick != null) {
 | 
			
		||||
				Contact contact = account.getRoster().getContact(from);
 | 
			
		||||
				if (contact.setPresenceName(nick)) {
 | 
			
		||||
					mXmppConnectionService.getAvatarService().clear(contact);
 | 
			
		||||
				}
 | 
			
		||||
				mXmppConnectionService.updateConversationUi();
 | 
			
		||||
				mXmppConnectionService.updateAccountUi();
 | 
			
		||||
                setNick(account, from, nick);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) {
 | 
			
		||||
            Element item = items.findChild("item");
 | 
			
		||||
| 
						 | 
				
			
			@ -221,6 +216,31 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void parseDeleteEvent(final Element event, final Jid from, final Account account) {
 | 
			
		||||
        final Element delete = event.findChild("delete");
 | 
			
		||||
        if (delete == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        String node = delete.getAttribute("node");
 | 
			
		||||
        if (Namespace.NICK.equals(node)) {
 | 
			
		||||
            Log.d(Config.LOGTAG, "parsing nick delete event from " + from);
 | 
			
		||||
            setNick(account, from, null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setNick(Account account, Jid user, String nick) {
 | 
			
		||||
        if (user.asBareJid().equals(account.getJid().asBareJid())) {
 | 
			
		||||
            account.setDisplayName(nick);
 | 
			
		||||
        } else {
 | 
			
		||||
            Contact contact = account.getRoster().getContact(user);
 | 
			
		||||
            if (contact.setPresenceName(nick)) {
 | 
			
		||||
                mXmppConnectionService.getAvatarService().clear(contact);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        mXmppConnectionService.updateConversationUi();
 | 
			
		||||
        mXmppConnectionService.updateAccountUi();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean handleErrorMessage(Account account, MessagePacket packet) {
 | 
			
		||||
        if (packet.getType() == MessagePacket.TYPE_ERROR) {
 | 
			
		||||
            Jid from = packet.getFrom();
 | 
			
		||||
| 
						 | 
				
			
			@ -757,9 +777,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Element event = original.findChild("event", "http://jabber.org/protocol/pubsub#event");
 | 
			
		||||
        final Element event = original.findChild("event", "http://jabber.org/protocol/pubsub#event");
 | 
			
		||||
        if (event != null && InvalidJid.hasValidFrom(original)) {
 | 
			
		||||
            if (event.hasChild("items")) {
 | 
			
		||||
                parseEvent(event, original.getFrom(), account);
 | 
			
		||||
            } else if (event.hasChild("delete")) {
 | 
			
		||||
                parseDeleteEvent(event, original.getFrom(), account);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final String nick = packet.findChildContent("nick", Namespace.NICK);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,11 +285,19 @@ public class XmppConnectionService extends Service {
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            boolean needsUpdating = account.setOption(Account.OPTION_LOGGED_IN_SUCCESSFULLY, true);
 | 
			
		||||
            needsUpdating |= account.setOption(Account.OPTION_HTTP_UPLOAD_AVAILABLE, account.getXmppConnection().getFeatures().httpUpload(0));
 | 
			
		||||
            if (needsUpdating) {
 | 
			
		||||
            boolean loggedInSuccessfully = account.setOption(Account.OPTION_LOGGED_IN_SUCCESSFULLY, true);
 | 
			
		||||
            boolean gainedFeature = account.setOption(Account.OPTION_HTTP_UPLOAD_AVAILABLE, account.getXmppConnection().getFeatures().httpUpload(0));
 | 
			
		||||
            if (loggedInSuccessfully || gainedFeature) {
 | 
			
		||||
                databaseBackend.updateAccount(account);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (loggedInSuccessfully) {
 | 
			
		||||
                if (!TextUtils.isEmpty(account.getDisplayName())) {
 | 
			
		||||
                    Log.d(Config.LOGTAG,account.getJid().asBareJid()+": display name wasn't empty on first log in. publishing");
 | 
			
		||||
                    publishDisplayName(account);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            account.getRoster().clearPresences();
 | 
			
		||||
            mJingleConnectionManager.cancelInTransmission();
 | 
			
		||||
            mQuickConversationsService.considerSyncBackground(false);
 | 
			
		||||
| 
						 | 
				
			
			@ -3828,15 +3836,18 @@ public class XmppConnectionService extends Service {
 | 
			
		|||
 | 
			
		||||
	public void publishDisplayName(Account account) {
 | 
			
		||||
		String displayName = account.getDisplayName();
 | 
			
		||||
		if (displayName != null && !displayName.isEmpty()) {
 | 
			
		||||
			IqPacket publish = mIqGenerator.publishNick(displayName);
 | 
			
		||||
			sendIqPacket(account, publish, (account1, packet) -> {
 | 
			
		||||
		final IqPacket request;
 | 
			
		||||
		if (TextUtils.isEmpty(displayName)) {
 | 
			
		||||
            request = mIqGenerator.deleteNode(Namespace.NICK);
 | 
			
		||||
		} else {
 | 
			
		||||
            request = mIqGenerator.publishNick(displayName);
 | 
			
		||||
        }
 | 
			
		||||
        sendIqPacket(account, request, (account1, packet) -> {
 | 
			
		||||
            if (packet.getType() == IqPacket.TYPE.ERROR) {
 | 
			
		||||
					Log.d(Config.LOGTAG, account1.getJid().asBareJid() + ": could not publish nick");
 | 
			
		||||
                Log.d(Config.LOGTAG, account1.getJid().asBareJid() + ": unable to modify nick name "+packet.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public ServiceDiscoveryResult getCachedServiceDiscoveryResult(Pair<String, String> key) {
 | 
			
		||||
		ServiceDiscoveryResult result = discoCache.get(key);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,20 +80,52 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
 | 
			
		||||
    private static final int REQUEST_DATA_SAVER = 0xf244;
 | 
			
		||||
    private static final int REQUEST_CHANGE_STATUS = 0xee11;
 | 
			
		||||
 | 
			
		||||
    private final PendingItem<PresenceTemplate> mPendingPresenceTemplate = new PendingItem<>();
 | 
			
		||||
    private AlertDialog mCaptchaDialog = null;
 | 
			
		||||
 | 
			
		||||
    private Jid jidToEdit;
 | 
			
		||||
    private boolean mInitMode = false;
 | 
			
		||||
    private boolean mUsernameMode = Config.DOMAIN_LOCK != null;
 | 
			
		||||
    private boolean mShowOptions = false;
 | 
			
		||||
    private Account mAccount;
 | 
			
		||||
    private final OnClickListener mCancelButtonClickListener = v -> {
 | 
			
		||||
        deleteAccountAndReturnIfNecessary();
 | 
			
		||||
        finish();
 | 
			
		||||
    };
 | 
			
		||||
    private final UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void userInputRequried(final PendingIntent pi, final Avatar avatar) {
 | 
			
		||||
            finishInitialSetup(avatar);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void success(final Avatar avatar) {
 | 
			
		||||
            finishInitialSetup(avatar);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void error(final int errorCode, final Avatar avatar) {
 | 
			
		||||
            finishInitialSetup(avatar);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    private final OnClickListener mAvatarClickListener = new OnClickListener() {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onClick(final View view) {
 | 
			
		||||
            if (mAccount != null) {
 | 
			
		||||
                final Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
 | 
			
		||||
                intent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().asBareJid().toString());
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    private String messageFingerprint;
 | 
			
		||||
 | 
			
		||||
	private final PendingItem<PresenceTemplate> mPendingPresenceTemplate = new PendingItem<>();
 | 
			
		||||
 | 
			
		||||
    private boolean mFetchingAvatar = false;
 | 
			
		||||
 | 
			
		||||
    private Toast mFetchingMamPrefsToast;
 | 
			
		||||
    private String mSavedInstanceAccount;
 | 
			
		||||
    private boolean mSavedInstanceInit = false;
 | 
			
		||||
    private XmppUri pendingUri = null;
 | 
			
		||||
    private boolean mUseTor;
 | 
			
		||||
    private ActivityEditAccountBinding binding;
 | 
			
		||||
    private final OnClickListener mSaveButtonClickListener = new OnClickListener() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
| 
						 | 
				
			
			@ -236,16 +268,71 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
	private final OnClickListener mCancelButtonClickListener = v -> {
 | 
			
		||||
		deleteAccountAndReturnIfNecessary();
 | 
			
		||||
		finish();
 | 
			
		||||
    private final TextWatcher mTextWatcher = new TextWatcher() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
 | 
			
		||||
            updatePortLayout();
 | 
			
		||||
            updateSaveButton();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void afterTextChanged(final Editable s) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
	private Toast mFetchingMamPrefsToast;
 | 
			
		||||
	private String mSavedInstanceAccount;
 | 
			
		||||
	private boolean mSavedInstanceInit = false;
 | 
			
		||||
	private XmppUri pendingUri = null;
 | 
			
		||||
	private boolean mUseTor;
 | 
			
		||||
	private ActivityEditAccountBinding binding;
 | 
			
		||||
    private View.OnFocusChangeListener mEditTextFocusListener = new View.OnFocusChangeListener() {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onFocusChange(View view, boolean b) {
 | 
			
		||||
            EditText et = (EditText) view;
 | 
			
		||||
            if (b) {
 | 
			
		||||
                int resId = mUsernameMode ? R.string.username : R.string.account_settings_example_jabber_id;
 | 
			
		||||
                if (view.getId() == R.id.hostname) {
 | 
			
		||||
                    resId = mUseTor ? R.string.hostname_or_onion : R.string.hostname_example;
 | 
			
		||||
                }
 | 
			
		||||
                final int res = resId;
 | 
			
		||||
                new Handler().postDelayed(() -> et.setHint(res), 200);
 | 
			
		||||
            } else {
 | 
			
		||||
                et.setHint(null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private static void setAvailabilityRadioButton(Presence.Status status, DialogPresenceBinding binding) {
 | 
			
		||||
        if (status == null) {
 | 
			
		||||
            binding.online.setChecked(true);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        switch (status) {
 | 
			
		||||
            case DND:
 | 
			
		||||
                binding.dnd.setChecked(true);
 | 
			
		||||
                break;
 | 
			
		||||
            case XA:
 | 
			
		||||
                binding.xa.setChecked(true);
 | 
			
		||||
                break;
 | 
			
		||||
            case AWAY:
 | 
			
		||||
                binding.xa.setChecked(true);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                binding.online.setChecked(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Presence.Status getAvailabilityRadioButton(DialogPresenceBinding binding) {
 | 
			
		||||
        if (binding.dnd.isChecked()) {
 | 
			
		||||
            return Presence.Status.DND;
 | 
			
		||||
        } else if (binding.xa.isChecked()) {
 | 
			
		||||
            return Presence.Status.XA;
 | 
			
		||||
        } else if (binding.away.isChecked()) {
 | 
			
		||||
            return Presence.Status.AWAY;
 | 
			
		||||
        } else {
 | 
			
		||||
            return Presence.Status.ONLINE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void refreshUiReal() {
 | 
			
		||||
        invalidateOptionsMenu();
 | 
			
		||||
| 
						 | 
				
			
			@ -296,70 +383,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        refreshUi();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	private final UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void userInputRequried(final PendingIntent pi, final Avatar avatar) {
 | 
			
		||||
			finishInitialSetup(avatar);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void success(final Avatar avatar) {
 | 
			
		||||
			finishInitialSetup(avatar);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void error(final int errorCode, final Avatar avatar) {
 | 
			
		||||
			finishInitialSetup(avatar);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	private final TextWatcher mTextWatcher = new TextWatcher() {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
 | 
			
		||||
			updatePortLayout();
 | 
			
		||||
			updateSaveButton();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public void afterTextChanged(final Editable s) {
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	private View.OnFocusChangeListener mEditTextFocusListener = new View.OnFocusChangeListener() {
 | 
			
		||||
		@Override
 | 
			
		||||
		public void onFocusChange(View view, boolean b) {
 | 
			
		||||
			EditText et = (EditText) view;
 | 
			
		||||
			if (b) {
 | 
			
		||||
				int resId = mUsernameMode ? R.string.username : R.string.account_settings_example_jabber_id;
 | 
			
		||||
				if (view.getId() == R.id.hostname) {
 | 
			
		||||
					resId = mUseTor ? R.string.hostname_or_onion : R.string.hostname_example;
 | 
			
		||||
				}
 | 
			
		||||
				final int res = resId;
 | 
			
		||||
				new Handler().postDelayed(() -> et.setHint(res), 200);
 | 
			
		||||
			} else {
 | 
			
		||||
				et.setHint(null);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private final OnClickListener mAvatarClickListener = new OnClickListener() {
 | 
			
		||||
		@Override
 | 
			
		||||
		public void onClick(final View view) {
 | 
			
		||||
			if (mAccount != null) {
 | 
			
		||||
				final Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
 | 
			
		||||
				intent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().asBareJid().toString());
 | 
			
		||||
				startActivity(intent);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    protected void finishInitialSetup(final Avatar avatar) {
 | 
			
		||||
        runOnUiThread(() -> {
 | 
			
		||||
            SoftKeyboardUtils.hideSoftKeyboard(EditAccountActivity.this);
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +429,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        processFingerprintVerification(uri, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected void processFingerprintVerification(XmppUri uri, boolean showWarningToast) {
 | 
			
		||||
        if (mAccount != null && mAccount.getJid().asBareJid().equals(uri.getJid()) && uri.hasFingerprints()) {
 | 
			
		||||
            if (xmppConnectionService.verifyFingerprints(mAccount, uri.getFingerprints())) {
 | 
			
		||||
| 
						 | 
				
			
			@ -534,6 +556,17 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        if (Config.DISALLOW_REGISTRATION_IN_UI) {
 | 
			
		||||
            this.binding.accountRegisterNew.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
        this.binding.actionEditYourName.setOnClickListener(this::onEditYourNameClicked);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onEditYourNameClicked(View view) {
 | 
			
		||||
        quickEdit(mAccount.getDisplayName(), R.string.your_name, value -> {
 | 
			
		||||
            final String displayName = value.trim();
 | 
			
		||||
            updateDisplayName(displayName);
 | 
			
		||||
            mAccount.setDisplayName(displayName);
 | 
			
		||||
            xmppConnectionService.publishDisplayName(mAccount);
 | 
			
		||||
            return null;
 | 
			
		||||
        }, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			@ -824,38 +857,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	private static void setAvailabilityRadioButton(Presence.Status status, DialogPresenceBinding binding) {
 | 
			
		||||
		if (status == null) {
 | 
			
		||||
			binding.online.setChecked(true);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		switch (status) {
 | 
			
		||||
			case DND:
 | 
			
		||||
				binding.dnd.setChecked(true);
 | 
			
		||||
				break;
 | 
			
		||||
			case XA:
 | 
			
		||||
				binding.xa.setChecked(true);
 | 
			
		||||
				break;
 | 
			
		||||
			case AWAY:
 | 
			
		||||
				binding.xa.setChecked(true);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				binding.online.setChecked(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Presence.Status getAvailabilityRadioButton(DialogPresenceBinding binding) {
 | 
			
		||||
		if (binding.dnd.isChecked()) {
 | 
			
		||||
			return Presence.Status.DND;
 | 
			
		||||
		} else if (binding.xa.isChecked()) {
 | 
			
		||||
			return Presence.Status.XA;
 | 
			
		||||
		} else if (binding.away.isChecked()) {
 | 
			
		||||
			return Presence.Status.AWAY;
 | 
			
		||||
		} else {
 | 
			
		||||
			return Presence.Status.ONLINE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void alias(String alias) {
 | 
			
		||||
        if (alias != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -887,6 +888,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        this.binding.accountJid.setFocusableInTouchMode(editable);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        final String displayName = mAccount.getDisplayName();
 | 
			
		||||
        updateDisplayName(displayName);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) || !mAccount.isOptionSet(Account.OPTION_LOGGED_IN_SUCCESSFULLY)) {
 | 
			
		||||
            this.binding.accountPasswordLayout.setPasswordVisibilityToggleEnabled(true);
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1055,6 +1060,16 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateDisplayName(String displayName) {
 | 
			
		||||
        if (TextUtils.isEmpty(displayName)) {
 | 
			
		||||
            this.binding.yourName.setText(R.string.no_name_set_instructions);
 | 
			
		||||
            this.binding.yourName.setTextAppearance(this, R.style.TextAppearance_Conversations_Body1_Tertiary);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.binding.yourName.setText(displayName);
 | 
			
		||||
            this.binding.yourName.setTextAppearance(this, R.style.TextAppearance_Conversations_Body1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void removeErrorsOnAllBut(TextInputLayout exception) {
 | 
			
		||||
        if (this.binding.accountJidLayout != exception) {
 | 
			
		||||
            this.binding.accountJidLayout.setErrorEnabled(false);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ public final class Namespace {
 | 
			
		|||
	public static final String PUBSUB = "http://jabber.org/protocol/pubsub";
 | 
			
		||||
	public static final String PUBSUB_PUBLISH_OPTIONS = PUBSUB+"#publish-options";
 | 
			
		||||
	public static final String PUBSUB_ERROR = PUBSUB+"#errors";
 | 
			
		||||
	public static final String PUBSUB_OWNER = PUBSUB+"#owner";
 | 
			
		||||
	public static final String NICK = "http://jabber.org/protocol/nick";
 | 
			
		||||
	public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
 | 
			
		||||
	public static final String BIND = "urn:ietf:params:xml:ns:xmpp-bind";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -470,11 +470,53 @@
 | 
			
		|||
                        </TableLayout>
 | 
			
		||||
 | 
			
		||||
                        <RelativeLayout
 | 
			
		||||
                            android:id="@+id/pgp_fingerprint_box"
 | 
			
		||||
                            android:id="@+id/your_name_box"
 | 
			
		||||
                            android:layout_width="wrap_content"
 | 
			
		||||
                            android:layout_height="match_parent"
 | 
			
		||||
                            android:layout_marginTop="32dp">
 | 
			
		||||
 | 
			
		||||
                            <LinearLayout
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
                                android:layout_alignParentLeft="true"
 | 
			
		||||
                                android:layout_centerVertical="true"
 | 
			
		||||
                                android:layout_toLeftOf="@+id/action_edit_your_name"
 | 
			
		||||
                                android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
                                <TextView
 | 
			
		||||
                                    android:id="@+id/your_name"
 | 
			
		||||
                                    android:layout_width="wrap_content"
 | 
			
		||||
                                    android:layout_height="wrap_content"
 | 
			
		||||
                                    android:text="@string/no_name_set_instructions"
 | 
			
		||||
                                    android:textAppearance="@style/TextAppearance.Conversations.Body1.Tertiary"/>
 | 
			
		||||
 | 
			
		||||
                                <TextView
 | 
			
		||||
                                    android:id="@+id/your_name_desc"
 | 
			
		||||
                                    android:layout_width="wrap_content"
 | 
			
		||||
                                    android:layout_height="wrap_content"
 | 
			
		||||
                                    android:text="@string/your_name"
 | 
			
		||||
                                    android:textAppearance="@style/TextAppearance.Conversations.Caption"/>
 | 
			
		||||
                            </LinearLayout>
 | 
			
		||||
 | 
			
		||||
                            <ImageButton
 | 
			
		||||
                                android:id="@+id/action_edit_your_name"
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
                                android:layout_alignParentRight="true"
 | 
			
		||||
                                android:layout_centerVertical="true"
 | 
			
		||||
                                android:alpha="?attr/icon_alpha"
 | 
			
		||||
                                android:background="?attr/selectableItemBackgroundBorderless"
 | 
			
		||||
                                android:padding="@dimen/image_button_padding"
 | 
			
		||||
                                android:src="?attr/icon_edit_body"
 | 
			
		||||
                                android:visibility="visible"/>
 | 
			
		||||
                        </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
                        <RelativeLayout
 | 
			
		||||
                            android:id="@+id/pgp_fingerprint_box"
 | 
			
		||||
                            android:layout_width="wrap_content"
 | 
			
		||||
                            android:layout_height="match_parent"
 | 
			
		||||
                            android:layout_marginTop="16dp">
 | 
			
		||||
 | 
			
		||||
                            <LinearLayout
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
| 
						 | 
				
			
			@ -514,7 +556,7 @@
 | 
			
		|||
                            android:id="@+id/axolotl_fingerprint_box"
 | 
			
		||||
                            android:layout_width="wrap_content"
 | 
			
		||||
                            android:layout_height="match_parent"
 | 
			
		||||
                            android:layout_marginTop="24dp">
 | 
			
		||||
                            android:layout_marginTop="16dp">
 | 
			
		||||
 | 
			
		||||
                            <LinearLayout
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -515,6 +515,9 @@
 | 
			
		|||
    <string name="share_uri_with">Share URI with…</string>
 | 
			
		||||
    <string name="welcome_header" translatable="false">Join the Conversation</string>
 | 
			
		||||
    <string name="welcome_text">Jabber is a provider independent instant messaging network. You can use this client with what ever Jabber 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="welcome_header_quicksy" translatable="false">Have some Quick Conversations</string>
 | 
			
		||||
    <string name="welcome_text_quicksy"><![CDATA[Quicksy is a spin off of the popular Jabber/XMPP client Conversations with automatic contact discovery.<br><br>You sign up with your phone number and Quicksy will automatically—based on the phone numbers in your address book—suggest possible contacts to you.<br><br>By signing up you agree to our <a href="https://quicksy.im/#privacy">privacy policy</a>.]]></string>
 | 
			
		||||
    <string name="agree_and_continue">Agree & continue</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>
 | 
			
		||||
| 
						 | 
				
			
			@ -789,4 +792,9 @@
 | 
			
		|||
    <string name="too_many_attempts">Too many attempts</string>
 | 
			
		||||
    <string name="the_app_is_out_of_date">You are using an out of date version of this app.</string>
 | 
			
		||||
    <string name="update">Update</string>
 | 
			
		||||
    <string name="logged_in_with_another_device">This phone number is currently logged in with another device.</string>
 | 
			
		||||
    <string name="enter_your_name_instructions">Please enter your name to let people, who don’t have you in their address books, know who you are.</string>
 | 
			
		||||
    <string name="your_name">Your name</string>
 | 
			
		||||
    <string name="enter_your_name">Enter your name</string>
 | 
			
		||||
    <string name="no_name_set_instructions">Use the edit button to set your name.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,10 @@
 | 
			
		|||
        <item name="android:textColor">?android:textColorSecondary</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Conversations.Body1.Tertiary" parent="TextAppearance.Conversations.Body1">
 | 
			
		||||
        <item name="android:textColor">?android:textColorTertiary</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Conversations.Fingerprint" parent="TextAppearance.Conversations.Body1">
 | 
			
		||||
        <item name="android:fontFamily" tools:targetApi="jelly_bean">monospace</item>
 | 
			
		||||
        <item name="android:typeface">monospace</item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,5 +19,15 @@
 | 
			
		|||
            android:launchMode="singleTask"
 | 
			
		||||
            android:label="@string/verify_your_phone_number"/>
 | 
			
		||||
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".ui.TosActivity"
 | 
			
		||||
            android:launchMode="singleTask"
 | 
			
		||||
            android:label="@string/app_name"/>
 | 
			
		||||
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".ui.EnterNameActivity"
 | 
			
		||||
            android:launchMode="singleTask"
 | 
			
		||||
            android:label="@string/enter_your_name"/>
 | 
			
		||||
 | 
			
		||||
    </application>
 | 
			
		||||
</manifest>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.view.View;
 | 
			
		||||
 | 
			
		||||
import eu.siacs.conversations.R;
 | 
			
		||||
import eu.siacs.conversations.databinding.ActivityEnterNameBinding;
 | 
			
		||||
import eu.siacs.conversations.entities.Account;
 | 
			
		||||
import eu.siacs.conversations.utils.AccountUtils;
 | 
			
		||||
 | 
			
		||||
public class EnterNameActivity extends XmppActivity {
 | 
			
		||||
 | 
			
		||||
    private ActivityEnterNameBinding binding;
 | 
			
		||||
 | 
			
		||||
    private Account account;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(final Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        this.binding = DataBindingUtil.setContentView(this, R.layout.activity_enter_name);
 | 
			
		||||
        setSupportActionBar((Toolbar) this.binding.toolbar);
 | 
			
		||||
        this.binding.next.setOnClickListener(this::next);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void next(View view) {
 | 
			
		||||
        if (account != null) {
 | 
			
		||||
 | 
			
		||||
            String name = this.binding.name.getText().toString().trim();
 | 
			
		||||
 | 
			
		||||
            account.setDisplayName(name);
 | 
			
		||||
 | 
			
		||||
            xmppConnectionService.publishDisplayName(account);
 | 
			
		||||
 | 
			
		||||
            Intent intent = new Intent(this, PublishProfilePictureActivity.class);
 | 
			
		||||
            intent.putExtra(PublishProfilePictureActivity.EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
 | 
			
		||||
            intent.putExtra("setup", true);
 | 
			
		||||
            startActivity(intent);
 | 
			
		||||
        }
 | 
			
		||||
        finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void refreshUiReal() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    void onBackendConnected() {
 | 
			
		||||
        this.account = AccountUtils.getFirst(xmppConnectionService);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
package eu.siacs.conversations.ui;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
import android.content.pm.ActivityInfo;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.preference.PreferenceManager;
 | 
			
		||||
import android.support.v7.app.ActionBar;
 | 
			
		||||
import android.support.v7.app.AppCompatActivity;
 | 
			
		||||
import android.text.Html;
 | 
			
		||||
import android.text.method.LinkMovementMethod;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import eu.siacs.conversations.R;
 | 
			
		||||
import eu.siacs.conversations.entities.Account;
 | 
			
		||||
import eu.siacs.conversations.utils.XmppUri;
 | 
			
		||||
 | 
			
		||||
public class TosActivity extends XmppActivity {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void refreshUiReal() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    void onBackendConnected() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStart() {
 | 
			
		||||
        super.onStart();
 | 
			
		||||
        final int theme = findTheme();
 | 
			
		||||
        if (this.mTheme != theme) {
 | 
			
		||||
            recreate();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onNewIntent(Intent intent) {
 | 
			
		||||
        if (intent != null) {
 | 
			
		||||
            setIntent(intent);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(final Bundle savedInstanceState) {
 | 
			
		||||
        if (getResources().getBoolean(R.bool.portrait_only)) {
 | 
			
		||||
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 | 
			
		||||
        }
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_tos);
 | 
			
		||||
        setSupportActionBar(findViewById(R.id.toolbar));
 | 
			
		||||
        final ActionBar ab = getSupportActionBar();
 | 
			
		||||
        if (ab != null) {
 | 
			
		||||
            ab.setDisplayShowHomeEnabled(false);
 | 
			
		||||
            ab.setDisplayHomeAsUpEnabled(false);
 | 
			
		||||
        }
 | 
			
		||||
        final Button agreeButton = findViewById(R.id.agree);
 | 
			
		||||
        final TextView welcomeText = findViewById(R.id.welcome_text);
 | 
			
		||||
        agreeButton.setOnClickListener(v -> {
 | 
			
		||||
            final Intent intent = new Intent(this, EnterPhoneNumberActivity.class);
 | 
			
		||||
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
 | 
			
		||||
            preferences.edit().putBoolean("tos", true).apply();
 | 
			
		||||
            addInviteUri(intent);
 | 
			
		||||
            startActivity(intent);
 | 
			
		||||
            finish();
 | 
			
		||||
        });
 | 
			
		||||
        welcomeText.setText(Html.fromHtml(getString(R.string.welcome_text_quicksy)));
 | 
			
		||||
        welcomeText.setMovementMethod(LinkMovementMethod.getInstance());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addInviteUri(Intent intent) {
 | 
			
		||||
        StartConversationActivity.addInviteUri(intent, getIntent());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -269,9 +269,7 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
 | 
			
		|||
 | 
			
		||||
    private void performPostVerificationRedirect() {
 | 
			
		||||
        if (redirectInProgress.compareAndSet(false, true)) {
 | 
			
		||||
            Intent intent = new Intent(this, PublishProfilePictureActivity.class);
 | 
			
		||||
            intent.putExtra(PublishProfilePictureActivity.EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
 | 
			
		||||
            intent.putExtra("setup", true);
 | 
			
		||||
            Intent intent = new Intent(this, EnterNameActivity.class);
 | 
			
		||||
            startActivity(intent);
 | 
			
		||||
            finish();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,9 @@ public class ApiDialogHelper {
 | 
			
		|||
            case 403:
 | 
			
		||||
                res = R.string.the_app_is_out_of_date;
 | 
			
		||||
                break;
 | 
			
		||||
            case 409:
 | 
			
		||||
                res = R.string.logged_in_with_another_device;
 | 
			
		||||
                break;
 | 
			
		||||
            case 500:
 | 
			
		||||
                res = R.string.something_went_wrong_processing_your_request;
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@ package eu.siacs.conversations.utils;
 | 
			
		|||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
import android.preference.PreferenceManager;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import eu.siacs.conversations.Config;
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +11,7 @@ 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.TosActivity;
 | 
			
		||||
import eu.siacs.conversations.ui.VerifyActivity;
 | 
			
		||||
 | 
			
		||||
public class SignupUtils {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +31,12 @@ public class SignupUtils {
 | 
			
		|||
                intent = new Intent(activity, StartConversationActivity.class);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
 | 
			
		||||
            if (preferences.getBoolean("tos",false)) {
 | 
			
		||||
                intent = getSignUpIntent(activity);
 | 
			
		||||
            } else {
 | 
			
		||||
                intent = new Intent(activity, TosActivity.class);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
<?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: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">
 | 
			
		||||
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:id="@+id/instructions"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:padding="16dp"
 | 
			
		||||
                    android:gravity="center_horizontal"
 | 
			
		||||
                    android:textAppearance="@style/TextAppearance.Conversations.Body1"
 | 
			
		||||
                    android:text="@string/enter_your_name_instructions"/>
 | 
			
		||||
 | 
			
		||||
                <LinearLayout
 | 
			
		||||
                    android:id="@+id/name_box"
 | 
			
		||||
                    android:layout_width="256dp"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:layout_above="@+id/next"
 | 
			
		||||
                    android:layout_below="@+id/instructions"
 | 
			
		||||
                    android:layout_centerHorizontal="true"
 | 
			
		||||
                    android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
                    <EditText
 | 
			
		||||
                        android:imeOptions="flagNoExtractUi"
 | 
			
		||||
                        android:id="@+id/name"
 | 
			
		||||
                        style="@style/Widget.Conversations.EditText"
 | 
			
		||||
                        android:layout_width="match_parent"
 | 
			
		||||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:hint="@string/your_name"
 | 
			
		||||
                        android:longClickable="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"/>
 | 
			
		||||
            </RelativeLayout>
 | 
			
		||||
        </ScrollView>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</layout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout
 | 
			
		||||
    xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
    <include 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"
 | 
			
		||||
            android:background="?attr/color_background_primary">
 | 
			
		||||
 | 
			
		||||
            <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">
 | 
			
		||||
                <Space
 | 
			
		||||
                    android:layout_width="match_parent"
 | 
			
		||||
                    android:layout_height="0dp"
 | 
			
		||||
                    android:layout_weight="1"/>
 | 
			
		||||
                <LinearLayout
 | 
			
		||||
                    android:layout_width="match_parent"
 | 
			
		||||
                    android:layout_height="match_parent"
 | 
			
		||||
                    android:paddingLeft="16dp"
 | 
			
		||||
                    android:paddingRight="16dp"
 | 
			
		||||
                    android:paddingBottom="16dp"
 | 
			
		||||
                    android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:text="@string/welcome_header_quicksy"
 | 
			
		||||
                    android:textAppearance="@style/TextAppearance.Conversations.Title"/>
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:id="@+id/welcome_text"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:layout_marginTop="8dp"
 | 
			
		||||
                    android:text="@string/welcome_text_quicksy"
 | 
			
		||||
                    android:textAppearance="@style/TextAppearance.Conversations.Body1"/>
 | 
			
		||||
                </LinearLayout>
 | 
			
		||||
                <Button
 | 
			
		||||
                    android:id="@+id/agree"
 | 
			
		||||
                    style="@style/Widget.Conversations.Button.Borderless"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:layout_gravity="end"
 | 
			
		||||
                    android:text="@string/agree_and_continue"
 | 
			
		||||
                    android:textColor="?colorAccent"/>
 | 
			
		||||
            </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">
 | 
			
		||||
                <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>
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
		Loading…
	
		Reference in New Issue