Detailed changes
@@ -17,15 +17,18 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
+import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import java.util.HashSet;
+import java.util.UUID;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ActivityWelcomeBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.Compatibility;
import eu.siacs.conversations.utils.InstallReferrerUtils;
import eu.siacs.conversations.utils.SignupUtils;
@@ -35,11 +38,12 @@ import eu.siacs.conversations.xmpp.Jid;
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
-public class WelcomeActivity extends XmppActivity implements XmppConnectionService.OnAccountCreated, KeyChainAliasCallback {
+public class WelcomeActivity extends XmppActivity implements XmppConnectionService.OnAccountCreated, XmppConnectionService.OnAccountUpdate, KeyChainAliasCallback {
private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
private XmppUri inviteUri;
+ private Account onboardingAccount = null;
public static void launch(AppCompatActivity activity) {
Intent intent = new Intent(activity, WelcomeActivity.class);
@@ -82,8 +86,21 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
}
@Override
- protected void refreshUiReal() {
+ protected synchronized void refreshUiReal() {
+ if (onboardingAccount == null) return;
+ if (onboardingAccount.getStatus() != Account.State.ONLINE) return;
+ Intent intent = new Intent(this, StartConversationActivity.class);
+ intent.putExtra("init", true);
+ intent.putExtra(EXTRA_ACCOUNT, onboardingAccount.getJid().asBareJid().toEscapedString());
+ onboardingAccount = null;
+ startActivity(intent);
+ finish();
+ }
+
+ @Override
+ public void onAccountUpdate() {
+ refreshUi();
}
@Override
@@ -124,9 +141,18 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar(), false);
binding.registerNewAccount.setOnClickListener(v -> {
- final Intent intent = new Intent(this, MagicCreateActivity.class);
- addInviteUri(intent);
- startActivity(intent);
+ if (hasInviteUri()) {
+ final Intent intent = new Intent(this, MagicCreateActivity.class);
+ addInviteUri(intent);
+ startActivity(intent);
+ } else {
+ binding.registerNewAccount.setText("Working...");
+ binding.registerNewAccount.setEnabled(false);
+ onboardingAccount = new Account(Jid.ofLocalAndDomain(UUID.randomUUID().toString(), Config.ONBOARDING_DOMAIN.toEscapedString()), CryptoHelper.createPassword(new SecureRandom()));
+ onboardingAccount.setOption(Account.OPTION_REGISTER, true);
+ onboardingAccount.setOption(Account.OPTION_FIXED_USERNAME, true);
+ xmppConnectionService.createAccount(onboardingAccount);
+ }
});
binding.useExisting.setOnClickListener(v -> {
final List<Account> accounts = xmppConnectionService.getAccounts();
@@ -235,6 +261,12 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
}
}
+ protected boolean hasInviteUri() {
+ final Intent from = getIntent();
+ if (from != null && from.hasExtra(StartConversationActivity.EXTRA_INVITE_URI)) return true;
+ return this.inviteUri != null;
+ }
+
public void addInviteUri(Intent to) {
final Intent from = getIntent();
if (from != null && from.hasExtra(StartConversationActivity.EXTRA_INVITE_URI)) {
@@ -62,7 +62,7 @@ public class SignupUtils {
if (Config.X509_VERIFICATION) {
intent = new Intent(activity, ManageAccountActivity.class);
} else if (Config.MAGIC_CREATE_DOMAIN != null) {
- intent = getSignUpIntent(activity);
+ intent = activity.xmppConnectionService.getPreferences().contains("onboarding_action") ? new Intent(activity, MagicCreateActivity.class) : getSignUpIntent(activity);
} else {
intent = new Intent(activity, EditAccountActivity.class);
}
@@ -70,8 +70,7 @@ public class SignupUtils {
intent = new Intent(activity, StartConversationActivity.class);
}
}
- intent.putExtra("init", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
return intent;
}
-}
+}
@@ -48,6 +48,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 = "chatterboxtown.us";
public static final Jid QUICKSY_DOMAIN = Jid.of("cheogram.com");
+ public static final Jid ONBOARDING_DOMAIN = Jid.of("onboarding.cheogram.com");
public static final String CHANNEL_DISCOVERY = "https://search.jabber.network";
@@ -3,6 +3,7 @@ package eu.siacs.conversations.entities;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.drawable.BitmapDrawable;
@@ -102,6 +103,7 @@ import eu.siacs.conversations.persistance.DatabaseBackend;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.UriHandlerActivity;
import eu.siacs.conversations.ui.text.FixedURLSpan;
import eu.siacs.conversations.ui.util.ShareUtil;
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
@@ -1301,8 +1303,12 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
pagerAdapter.startCommand(command, xmppConnectionService);
}
- public void setupViewPager(ViewPager pager, TabLayout tabs) {
- pagerAdapter.setupViewPager(pager, tabs);
+ public boolean switchToSession(final String node) {
+ return pagerAdapter.switchToSession(node);
+ }
+
+ public void setupViewPager(ViewPager pager, TabLayout tabs, boolean onboarding) {
+ pagerAdapter.setupViewPager(pager, tabs, onboarding);
}
public void showViewPager() {
@@ -1341,10 +1347,12 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
ArrayList<CommandSession> sessions = null;
protected View page1 = null;
protected View page2 = null;
+ protected boolean mOnboarding = false;
- public void setupViewPager(ViewPager pager, TabLayout tabs) {
+ public void setupViewPager(ViewPager pager, TabLayout tabs, boolean onboarding) {
mPager = pager;
mTabs = tabs;
+ mOnboarding = onboarding;
if (mPager == null) return;
if (sessions != null) show();
@@ -1370,7 +1378,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
sessions = new ArrayList<>();
notifyDataSetChanged();
}
- if (mTabs != null) mTabs.setVisibility(View.VISIBLE);
+ if (!mOnboarding && mTabs != null) mTabs.setVisibility(View.VISIBLE);
}
public void hide() {
@@ -1390,27 +1398,32 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
final Element c = packet.addChild("command", Namespace.COMMANDS);
c.setAttribute("node", command.getAttribute("node"));
c.setAttribute("action", "execute");
- View v = mPager;
+
+ final TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ if (getAccount().getStatus() != Account.State.ONLINE) {
+ new Timer().schedule(this, 1000);
+ } else {
+ xmppConnectionService.sendIqPacket(getAccount(), packet, (a, iq) -> {
+ session.updateWithResponse(iq);
+ });
+ }
+ }
+ };
+ task.run();
if (command.getAttribute("node").equals("jabber:iq:register") && packet.getTo().asBareJid().equals(Jid.of("cheogram.com"))) {
- new com.cheogram.android.CheogramLicenseChecker(v.getContext(), (signedData, signature) -> {
+ new com.cheogram.android.CheogramLicenseChecker(mPager.getContext(), (signedData, signature) -> {
if (signedData != null && signature != null) {
c.addChild("license", "https://ns.cheogram.com/google-play").setContent(signedData);
c.addChild("licenseSignature", "https://ns.cheogram.com/google-play").setContent(signature);
}
- xmppConnectionService.sendIqPacket(getAccount(), packet, (a, iq) -> {
- v.post(() -> {
- session.updateWithResponse(iq);
- });
- });
+ task.run();
}).checkLicense();
} else {
- xmppConnectionService.sendIqPacket(getAccount(), packet, (a, iq) -> {
- v.post(() -> {
- session.updateWithResponse(iq);
- });
- });
+ task.run();
}
sessions.add(session);
@@ -1423,6 +1436,21 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
notifyDataSetChanged();
}
+ public boolean switchToSession(final String node) {
+ if (sessions == null) return false;
+
+ int i = 0;
+ for (CommandSession session : sessions) {
+ if (session.mNode.equals(node)) {
+ if (mPager != null) mPager.setCurrentItem(i + 2);
+ return true;
+ }
+ i++;
+ }
+
+ return false;
+ }
+
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
@@ -2376,6 +2404,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
protected GridLayoutManager layoutManager;
protected WebView actionToWebview = null;
protected int fillableFieldCount = 0;
+ protected IqPacket pendingResponsePacket = null;
CommandSession(String title, String node, XmppConnectionService xmppConnectionService) {
loading();
@@ -2401,7 +2430,15 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
return mTitle;
}
- public void updateWithResponse(IqPacket iq) {
+ public void updateWithResponse(final IqPacket iq) {
+ if (getView() != null && getView().isAttachedToWindow()) {
+ getView().post(() -> updateWithResponseUiThread(iq));
+ } else {
+ pendingResponsePacket = iq;
+ }
+ }
+
+ protected void updateWithResponseUiThread(final IqPacket iq) {
this.loadingTimer.cancel();
this.loadingTimer = new Timer();
this.loading = false;
@@ -2476,6 +2513,13 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
this.responseElement = el;
break;
}
+ if (scheme.equals("xmpp")) {
+ final Intent intent = new Intent(getView().getContext(), UriHandlerActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ getView().getContext().startActivity(intent);
+ break;
+ }
}
}
if (el.getName().equals("note") && el.getNamespace().equals("http://jabber.org/protocol/commands")) {
@@ -2485,6 +2529,16 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
if (responseElement == null && command.getAttribute("status") != null && (command.getAttribute("status").equals("completed") || command.getAttribute("status").equals("canceled"))) {
+ if (mNode.equals("jabber:iq:register") && command.getAttribute("status").equals("canceled")) {
+ if (xmppConnectionService.isOnboarding()) {
+ if (!xmppConnectionService.getPreferences().contains("onboarding_action")) {
+ xmppConnectionService.getPreferences().edit().putString("onboarding_action", "cancel").commit();
+ }
+ xmppConnectionService.deleteAccount(getAccount());
+ }
+ xmppConnectionService.archiveConversation(Conversation.this);
+ }
+
removeSession(this);
return;
}
@@ -2498,7 +2552,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
if (!actionsAdapter.isEmpty() || fillableFieldCount > 0) {
if (command.getAttribute("status").equals("completed") || command.getAttribute("status").equals("canceled")) {
actionsAdapter.add(Pair.create("close", "close"));
- } else if (actionsAdapter.getPosition("cancel") < 0) {
+ } else if (actionsAdapter.getPosition("cancel") < 0 && !xmppConnectionService.isOnboarding()) {
actionsAdapter.insert(Pair.create("cancel", "cancel"), 0);
}
}
@@ -2508,6 +2562,25 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
actionsAdapter.add(Pair.create("close", "close"));
}
+ actionsAdapter.sort((x, y) -> {
+ if (x.first.equals("cancel")) return -1;
+ if (y.first.equals("cancel")) return 1;
+ if (x.first.equals("prev") && xmppConnectionService.isOnboarding()) return -1;
+ if (y.first.equals("prev") && xmppConnectionService.isOnboarding()) return 1;
+ return 0;
+ });
+
+ Data dataForm = null;
+ if (responseElement != null && responseElement.getName().equals("x") && responseElement.getNamespace().equals("jabber:x:data")) dataForm = Data.parse(responseElement);
+ if (mNode.equals("jabber:iq:register") &&
+ xmppConnectionService.getPreferences().contains("onboarding_action") &&
+ dataForm != null && dataForm.getFieldByName("gateway-jid") != null) {
+
+
+ dataForm.put("gateway-jid", xmppConnectionService.getPreferences().getString("onboarding_action", ""));
+ execute();
+ }
+ xmppConnectionService.getPreferences().edit().remove("onboarding_action").commit();
notifyDataSetChanged();
}
@@ -2693,6 +2766,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
public View getView() {
+ if (mBinding == null) return null;
return mBinding.getRoot();
}
@@ -2750,6 +2824,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
c.setAttribute("action", "execute");
}
+ if (mNode.equals("jabber:iq:register") && xmppConnectionService.isOnboarding() && form.getValue("gateway-jid") != null) {
+ xmppConnectionService.getPreferences().edit().putString("onboarding_action", form.getValue("gateway-jid")).commit();
+ }
+
responseElement.setAttribute("type", "submit");
Element rsm = responseElement.findChild("set", "http://jabber.org/protocol/rsm");
if (rsm != null) {
@@ -2764,9 +2842,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
if (c.getAttribute("action") == null) c.setAttribute("action", action);
xmppConnectionService.sendIqPacket(getAccount(), packet, (a, iq) -> {
- getView().post(() -> {
- updateWithResponse(iq);
- });
+ updateWithResponse(iq);
});
loading();
@@ -2861,6 +2937,12 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
});
actionsAdapter.notifyDataSetChanged();
+
+ if (pendingResponsePacket != null) {
+ final IqPacket pending = pendingResponsePacket;
+ pendingResponsePacket = null;
+ updateWithResponseUiThread(pending);
+ }
}
// https://stackoverflow.com/a/36037991/8611
@@ -1805,6 +1805,10 @@ public class XmppConnectionService extends Service {
sendMessage(message, true, delay);
}
+ public boolean isOnboarding() {
+ return getAccounts().size() == 1 && getAccounts().get(0).getJid().getDomain().equals(Config.ONBOARDING_DOMAIN);
+ }
+
public void requestEasyOnboardingInvite(final Account account, final EasyOnboardingInvite.OnInviteRequested callback) {
final XmppConnection connection = account.getXmppConnection();
final Jid jid = connection == null ? null : connection.getJidForCommand(Namespace.EASY_ONBOARDING_INVITE);
@@ -1202,6 +1202,8 @@ public class ConversationFragment extends XmppFragment
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
+ if (activity.xmppConnectionService.isOnboarding()) return;
+
menuInflater.inflate(R.menu.fragment_conversation, menu);
final MenuItem menuMucDetails = menu.findItem(R.id.action_muc_details);
final MenuItem menuContactDetails = menu.findItem(R.id.action_contact_details);
@@ -1357,7 +1359,7 @@ public class ConversationFragment extends XmppFragment
messageListAdapter.setOnContactPictureClicked(null);
messageListAdapter.setOnContactPictureLongClicked(null);
messageListAdapter.setOnInlineImageLongClicked(null);
- if (conversation != null) conversation.setupViewPager(null, null);
+ if (conversation != null) conversation.setupViewPager(null, null, false);
}
private void quoteText(String text) {
@@ -2836,12 +2838,12 @@ public class ConversationFragment extends XmppFragment
.setOpenConversation(this.conversation);
if (commandAdapter != null && conversation != originalConversation) {
- originalConversation.setupViewPager(null, null);
- conversation.setupViewPager(binding.conversationViewPager, binding.tabLayout);
+ originalConversation.setupViewPager(null, null, false);
+ conversation.setupViewPager(binding.conversationViewPager, binding.tabLayout, activity.xmppConnectionService.isOnboarding());
refreshCommands(false);
}
if (commandAdapter == null && conversation != null) {
- conversation.setupViewPager(binding.conversationViewPager, binding.tabLayout);
+ conversation.setupViewPager(binding.conversationViewPager, binding.tabLayout, activity.xmppConnectionService.isOnboarding());
commandAdapter = new CommandAdapter((XmppActivity) getActivity());
binding.commandsView.setAdapter(commandAdapter);
binding.commandsView.setOnItemClickListener((parent, view, position, id) -> {
@@ -2862,6 +2864,9 @@ public class ConversationFragment extends XmppFragment
if (commandAdapter == null) return;
Jid commandJid = conversation.getContact().resourceWhichSupport(Namespace.COMMANDS);
+ if (commandJid == null && conversation.getJid().isDomainJid()) {
+ commandJid = conversation.getJid();
+ }
if (commandJid == null) {
conversation.hideViewPager();
} else {
@@ -3006,6 +3011,11 @@ public class ConversationFragment extends XmppFragment
if (message != null) {
startDownloadable(message);
}
+ if (activity.xmppConnectionService.isOnboarding() && conversation.getJid().equals(Jid.of("cheogram.com"))) {
+ if (!conversation.switchToSession("jabber:iq:register")) {
+ conversation.startCommand(commandFor(Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"), "jabber:iq:register"), activity.xmppConnectionService);
+ }
+ }
}
private Element commandFor(final Jid jid, final String node) {
@@ -199,6 +199,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
if (xmppConnectionService == null) {
return false;
}
+
boolean isConversationsListEmpty = xmppConnectionService.isConversationsListEmpty(ignore);
if (isConversationsListEmpty && mRedirectInProcess.compareAndSet(false, true)) {
final Intent intent = SignupUtils.getRedirectionIntent(this);
@@ -216,7 +217,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
private void showDialogsIfMainIsOverview() {
- if (xmppConnectionService == null) {
+ if (xmppConnectionService == null || xmppConnectionService.isOnboarding()) {
return;
}
final Fragment fragment = getFragmentManager().findFragmentById(R.id.main_fragment);
@@ -486,7 +487,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
getMenuInflater().inflate(R.menu.activity_conversations, menu);
final MenuItem qrCodeScanMenuItem = menu.findItem(R.id.action_scan_qr_code);
if (qrCodeScanMenuItem != null) {
- if (isCameraFeatureAvailable()) {
+ if (isCameraFeatureAvailable() && (xmppConnectionService == null || !xmppConnectionService.isOnboarding())) {
Fragment fragment = getFragmentManager().findFragmentById(R.id.main_fragment);
boolean visible = getResources().getBoolean(R.bool.show_qr_code_scan)
&& fragment instanceof ConversationsOverviewFragment;
@@ -576,7 +577,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
final Conversation conversation = xmppConnectionService.findUniqueConversationByJid(xmppUri);
if (conversation != null) {
if (xmppUri.isAction("command")) {
- startCommand(conversation.getAccount(), conversation.getJid(), xmppUri.getParameter("node"));
+ startCommand(conversation.getAccount(), xmppUri.getJid(), xmppUri.getParameter("node"));
} else {
Bundle extras = new Bundle();
extras.putString(Intent.EXTRA_TEXT, xmppUri.getBody());
@@ -740,10 +741,10 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
if (conversation != null) {
actionBar.setTitle(conversation.getName());
- actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(!xmppConnectionService.isOnboarding());
ActionBarUtil.setActionBarOnClickListener(
binding.toolbar,
- (v) -> openConversationDetails(conversation)
+ (v) -> { if(!xmppConnectionService.isOnboarding()) openConversationDetails(conversation); }
);
return;
}
@@ -316,6 +316,13 @@ public class ConversationsOverviewFragment extends XmppFragment {
AccountUtils.showHideMenuItems(menu);
final MenuItem easyOnboardInvite = menu.findItem(R.id.action_easy_invite);
easyOnboardInvite.setVisible(EasyOnboardingInvite.anyHasSupport(activity == null ? null : activity.xmppConnectionService));
+ if (activity.xmppConnectionService != null && activity.xmppConnectionService.isOnboarding()) {
+ final MenuItem manageAccounts = menu.findItem(R.id.action_accounts);
+ if (manageAccounts != null) manageAccounts.setVisible(false);
+
+ final MenuItem settings = menu.findItem(R.id.action_settings);
+ if (settings != null) settings.setVisible(false);
+ }
}
@Override
@@ -380,6 +387,11 @@ public class ConversationsOverviewFragment extends XmppFragment {
@Override
public void onBackendConnected() {
refresh();
+ if (activity.xmppConnectionService.isOnboarding()) {
+ binding.fab.setVisibility(View.GONE);
+ } else {
+ binding.fab.setVisibility(View.VISIBLE);
+ }
}
@Override
@@ -95,9 +95,13 @@ import eu.siacs.conversations.ui.widget.SwipeRefreshListFragment;
import eu.siacs.conversations.utils.AccountUtils;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.XmppUri;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.XmppConnection;
+import eu.siacs.conversations.xmpp.forms.Data;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class StartConversationActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, CreatePrivateGroupChatDialog.CreateConferenceDialogListener, JoinConferenceDialog.JoinConferenceDialogListener, SwipeRefreshLayout.OnRefreshListener, CreatePublicChannelDialog.CreatePublicChannelDialogListener {
@@ -913,13 +917,19 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
configureHomeButton();
Intent intent = pendingViewIntent.pop();
- if (intent != null && intent.getBooleanExtra("init", false)) {
+ final boolean onboardingCancel = xmppConnectionService.getPreferences().getString("onboarding_action", "").equals("cancel");
+ if (onboardingCancel) xmppConnectionService.getPreferences().edit().remove("onboarding_action").commit();
+
+ if (intent != null && intent.getBooleanExtra("init", false) && !onboardingCancel) {
Account selectedAccount = xmppConnectionService.getAccounts().get(0);
final String accountJid = intent.getStringExtra(EXTRA_ACCOUNT);
intent = null;
boolean hasPstnOrSms = false;
+ Account onboardingAccount = null;
outer:
for (Account account : xmppConnectionService.getAccounts()) {
+ if (onboardingAccount == null && account.getJid().getDomain().equals(Config.ONBOARDING_DOMAIN)) onboardingAccount = account;
+
if (accountJid != null) {
if(account.getJid().asBareJid().toEscapedString().equals(accountJid)) {
selectedAccount = account;
@@ -941,9 +951,88 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
}
if (!hasPstnOrSms) {
- startCommand(selectedAccount, Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"), "jabber:iq:register");
- finish();
- return;
+ if (onboardingAccount != null && !selectedAccount.getJid().equals(onboardingAccount.getJid())) {
+ final Account onboardAccount = onboardingAccount;
+ final Account newAccount = selectedAccount;
+ final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
+ packet.setTo(Jid.of("cheogram.com"));
+ final Element c = packet.addChild("command", Namespace.COMMANDS);
+ c.setAttribute("node", "change jabber id");
+ c.setAttribute("action", "execute");
+
+ xmppConnectionService.sendIqPacket(onboardingAccount, packet, (a, iq) -> {
+ Element command = iq.findChild("command", "http://jabber.org/protocol/commands");
+ if (command == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
+ return;
+ }
+
+ Element form = command.findChild("x", "jabber:x:data");
+ Data dataForm = form == null ? null : Data.parse(form);
+ if (dataForm == null || dataForm.getFieldByName("new-jid") == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
+ return;
+ }
+
+ dataForm.put("new-jid", newAccount.getJid().toEscapedString());
+ dataForm.submit();
+ command.setAttribute("action", "execute");
+ iq.setTo(iq.getFrom());
+ iq.setAttribute("type", "set");
+ iq.removeAttribute("from");
+ iq.removeAttribute("id");
+ xmppConnectionService.sendIqPacket(a, iq, (a2, iq2) -> {
+ Element command2 = iq2.findChild("command", "http://jabber.org/protocol/commands");
+ if (command2 != null && command2.getAttribute("status") != null && command2.getAttribute("status").equals("completed")) {
+ final IqPacket regPacket = new IqPacket(IqPacket.TYPE.SET);
+ regPacket.setTo(Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"));
+ final Element c2 = regPacket.addChild("command", Namespace.COMMANDS);
+ c2.setAttribute("node", "jabber:iq:register");
+ c2.setAttribute("action", "execute");
+ xmppConnectionService.sendIqPacket(newAccount, regPacket, (a3, iq3) -> {
+ Element command3 = iq3.findChild("command", "http://jabber.org/protocol/commands");
+ if (command3 == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
+ return;
+ }
+
+ Element form3 = command3.findChild("x", "jabber:x:data");
+ Data dataForm3 = form3 == null ? null : Data.parse(form3);
+ if (dataForm3 == null || dataForm3.getFieldByName("confirm") == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
+ return;
+ }
+
+ dataForm3.put("confirm", "true");
+ dataForm3.submit();
+ command3.setAttribute("action", "execute");
+ iq3.setTo(iq3.getFrom());
+ iq3.setAttribute("type", "set");
+ iq3.removeAttribute("from");
+ iq3.removeAttribute("id");
+ xmppConnectionService.sendIqPacket(newAccount, iq3, (a4, iq4) -> {
+ Element command4 = iq2.findChild("command", "http://jabber.org/protocol/commands");
+ if (command4 != null && command4.getAttribute("status") != null && command4.getAttribute("status").equals("completed")) {
+ xmppConnectionService.createContact(newAccount.getRoster().getContact(iq4.getFrom().asBareJid()), true);
+ Conversation withCheogram = xmppConnectionService.findOrCreateConversation(newAccount, iq4.getFrom().asBareJid(), true, true, true);
+ xmppConnectionService.markRead(withCheogram);
+ xmppConnectionService.clearConversationHistory(withCheogram);
+ xmppConnectionService.deleteAccount(onboardAccount);
+ } else {
+ Log.e(Config.LOGTAG, "Error confirming jid switch, got: " + iq4);
+ }
+ });
+ });
+ } else {
+ Log.e(Config.LOGTAG, "Error during jid switch, got: " + iq2);
+ }
+ });
+ });
+ } else {
+ startCommand(selectedAccount, Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"), "jabber:iq:register");
+ finish();
+ return;
+ }
}
}
@@ -1119,7 +1208,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
final boolean sopranicaDeleted = getPreferences().getBoolean("cheogram_sopranica_bookmark_deleted", false);
- if (!sopranicaDeleted && !foundSopranica && (needle == null || needle.equals(""))) {
+ if (!sopranicaDeleted && !foundSopranica && (needle == null || needle.equals("")) && xmppConnectionService.getAccounts().size() > 0) {
Bookmark bookmark = new Bookmark(
xmppConnectionService.getAccounts().get(0),
Jid.of("discuss@conference.soprani.ca")
@@ -14,7 +14,7 @@ public class Option {
public static List<Option> forField(Element field) {
List<Option> options = new ArrayList<>();
for (Element el : field.getChildren()) {
- if (!el.getNamespace().equals("jabber:x:data")) continue;
+ if (el.getNamespace() == null || !el.getNamespace().equals("jabber:x:data")) continue;
if (!el.getName().equals("option")) continue;
options.add(new Option(el));
}