finished 'Set Status Message' dialog

Daniel Gultsch created

Change summary

src/main/AndroidManifest.xml                                             |   6 
src/main/java/eu/siacs/conversations/crypto/PgpEngine.java               |  11 
src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java    |  12 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  43 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java         |  91 
src/main/java/eu/siacs/conversations/ui/SetPresenceActivity.java         | 213 
src/main/java/eu/siacs/conversations/ui/SettingsActivity.java            |   3 
src/main/java/eu/siacs/conversations/ui/XmppActivity.java                |  13 
src/main/res/layout/dialog_presence.xml                                  |   8 
src/main/res/menu/editaccount.xml                                        |   2 
src/main/res/values/strings.xml                                          |   9 
11 files changed, 127 insertions(+), 284 deletions(-)

Detailed changes

src/main/AndroidManifest.xml πŸ”—

@@ -107,12 +107,6 @@
             android:name=".ui.MagicCreateActivity"
             android:label="@string/create_account"
             android:launchMode="singleTask"/>
-        <activity
-            android:name=".ui.SetPresenceActivity"
-            android:configChanges="orientation|screenSize"
-            android:label="@string/change_presence"
-            android:launchMode="singleTop"
-            android:windowSoftInputMode="stateHidden|adjustResize" />
         <activity
             android:name=".ui.SettingsActivity"
             android:label="@string/title_activity_settings" />

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

@@ -198,7 +198,7 @@ public class PgpEngine {
 		});
 	}
 
-	public void generateSignature(Intent intent, final Account account, String status, final UiCallback<Account> callback) {
+	public void generateSignature(Intent intent, final Account account, String status, final UiCallback<String> callback) {
 		if (account.getPgpId() == 0) {
 			return;
 		}
@@ -232,19 +232,18 @@ public class PgpEngine {
 							}
 						}
 					} catch (IOException e) {
-						callback.error(R.string.openpgp_error, account);
+						callback.error(R.string.openpgp_error, null);
 						return;
 					}
-					account.setPgpSignature(signatureBuilder.toString());
-					callback.success(account);
+					callback.success(signatureBuilder.toString());
 					return;
 				case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
-					callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), account);
+					callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), status);
 					return;
 				case OpenPgpApi.RESULT_CODE_ERROR:
 					OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
 					if (error != null && "signing subkey not found!".equals(error.getMessage())) {
-						callback.error(0, account);
+						callback.error(0, null);
 					} else {
 						logError(account, error);
 						callback.error(R.string.unable_to_connect_to_keychain, null);

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

@@ -644,6 +644,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 
 	public void insertPresenceTemplate(PresenceTemplate template) {
 		SQLiteDatabase db = this.getWritableDatabase();
+		String whereToDelete = PresenceTemplate.MESSAGE+"=?";
+		String[] whereToDeleteArgs = {template.getStatusMessage()};
+		db.delete(PresenceTemplate.TABELNAME,whereToDelete,whereToDeleteArgs);
+		db.delete(PresenceTemplate.TABELNAME,PresenceTemplate.UUID+" not in (select "+PresenceTemplate.UUID+" from "+PresenceTemplate.TABELNAME+" order by "+PresenceTemplate.LAST_USED+" desc limit 9)",null);
 		db.insert(PresenceTemplate.TABELNAME, null, template.getContentValues());
 	}
 
@@ -658,14 +662,6 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 		return templates;
 	}
 
-	public void deletePresenceTemplate(PresenceTemplate template) {
-		Log.d(Config.LOGTAG,"deleting presence template with uuid "+template.getUuid());
-		SQLiteDatabase db = this.getWritableDatabase();
-		String where = PresenceTemplate.UUID+"=?";
-		String[] whereArgs = {template.getUuid()};
-		db.delete(PresenceTemplate.TABELNAME,where,whereArgs);
-	}
-
 	public CopyOnWriteArrayList<Conversation> getConversations(int status) {
 		CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
 		SQLiteDatabase db = this.getReadableDatabase();

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

@@ -3474,15 +3474,16 @@ public class XmppConnectionService extends Service {
 	}
 
 	private void sendPresence(final Account account, final boolean includeIdleTimestamp) {
-		PresencePacket packet;
+		Presence.Status status;
 		if (manuallyChangePresence()) {
-			packet = mPresenceGenerator.selfPresence(account, account.getPresenceStatus());
-			String message = account.getPresenceStatusMessage();
-			if (message != null && !message.isEmpty()) {
-				packet.addChild(new Element("status").setContent(message));
-			}
+			status = account.getPresenceStatus();
 		} else {
-			packet = mPresenceGenerator.selfPresence(account, getTargetPresence());
+			status = getTargetPresence();
+		}
+		PresencePacket packet = mPresenceGenerator.selfPresence(account,status);
+		String message = account.getPresenceStatusMessage();
+		if (message != null && !message.isEmpty()) {
+			packet.addChild(new Element("status").setContent(message));
 		}
 		if (mLastActivity > 0 && includeIdleTimestamp) {
 			long since = Math.min(mLastActivity, System.currentTimeMillis()); //don't send future dates
@@ -3779,29 +3780,15 @@ public class XmppConnectionService extends Service {
 		return pending;
 	}
 
-	public void changeStatus(Account account, Presence.Status status, String statusMessage, boolean send) {
-		if (!statusMessage.isEmpty()) {
-			databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
+	public void changeStatus(Account account, PresenceTemplate template, String signature) {
+		if (!template.getStatusMessage().isEmpty()) {
+			databaseBackend.insertPresenceTemplate(template);
 		}
-		changeStatusReal(account, status, statusMessage, send);
-	}
-
-	private void changeStatusReal(Account account, Presence.Status status, String statusMessage, boolean send) {
-		account.setPresenceStatus(status);
-		account.setPresenceStatusMessage(statusMessage);
+		account.setPgpSignature(signature);
+		account.setPresenceStatus(template.getStatus());
+		account.setPresenceStatusMessage(template.getStatusMessage());
 		databaseBackend.updateAccount(account);
-		if (account.isEnabled() && send) {
-			sendPresence(account);
-		}
-	}
-
-	public void changeStatus(Presence.Status status, String statusMessage) {
-		if (!statusMessage.isEmpty()) {
-			databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
-		}
-		for (Account account : getAccounts()) {
-			changeStatusReal(account, status, statusMessage, true);
-		}
+		sendPresence(account);
 	}
 
 	public List<PresenceTemplate> getPresenceTemplates(Account account) {

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

@@ -1,9 +1,11 @@
 package eu.siacs.conversations.ui;
 
+import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.ActivityNotFoundException;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.content.SharedPreferences;
 import android.databinding.DataBindingUtil;
 import android.graphics.Bitmap;
@@ -15,7 +17,6 @@ import android.provider.Settings;
 import android.security.KeyChain;
 import android.security.KeyChainAliasCallback;
 import android.support.design.widget.TextInputLayout;
-import android.support.v4.content.ContextCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AlertDialog.Builder;
@@ -26,8 +27,6 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.AutoCompleteTextView;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
@@ -57,6 +56,7 @@ import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
 import eu.siacs.conversations.databinding.ActivityEditAccountBinding;
 import eu.siacs.conversations.databinding.DialogPresenceBinding;
 import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Presence;
 import eu.siacs.conversations.entities.PresenceTemplate;
 import eu.siacs.conversations.services.BarcodeProvider;
 import eu.siacs.conversations.services.XmppConnectionService;
@@ -64,6 +64,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested;
 import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 import eu.siacs.conversations.ui.adapter.PresenceTemplateAdapter;
+import eu.siacs.conversations.ui.util.PendingItem;
 import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.UIHelper;
@@ -82,6 +83,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 		OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched {
 
 	private static final int REQUEST_DATA_SAVER = 0xf244;
+	private static final int REQUEST_CHANGE_STATUS = 0xee11;
 	private TextInputLayout mAccountJidLayout;
 	private EditText mPassword;
 	private TextInputLayout mPasswordLayout;
@@ -126,6 +128,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 	private Account mAccount;
 	private String messageFingerprint;
 
+	private final PendingItem<PresenceTemplate> mPendingPresenceTemplate = new PendingItem<>();
+
 	private boolean mFetchingAvatar = false;
 
 	private final OnClickListener mSaveButtonClickListener = new OnClickListener() {
@@ -429,6 +433,14 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 		if (requestCode == REQUEST_BATTERY_OP || requestCode == REQUEST_DATA_SAVER) {
 			updateAccountInformation(mAccount == null);
 		}
+		if (requestCode == REQUEST_CHANGE_STATUS) {
+			PresenceTemplate template = mPendingPresenceTemplate.pop();
+			if (template != null && resultCode == Activity.RESULT_OK) {
+				generateSignature(data,template);
+			} else {
+				Log.d(Config.LOGTAG,"pgp result not ok");
+			}
+		}
 	}
 
 	@Override
@@ -843,21 +855,88 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 		boolean manualStatus = sharedPreferences.getBoolean(SettingsActivity.MANUALLY_CHANGE_PRESENCE, getResources().getBoolean(R.bool.manually_change_presence));
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
 		final DialogPresenceBinding binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.dialog_presence,null,false);
+		String current = mAccount.getPresenceStatusMessage();
+		if (current != null && !current.trim().isEmpty()) {
+			binding.statusMessage.append(current);
+		}
+		setAvailabilityRadioButton(mAccount.getPresenceStatus(),binding);
 		binding.show.setVisibility(manualStatus ? View.VISIBLE : View.GONE);
 		List<PresenceTemplate> templates = xmppConnectionService.getPresenceTemplates(mAccount);
 		PresenceTemplateAdapter presenceTemplateAdapter = new PresenceTemplateAdapter(this,R.layout.simple_list_item,templates);
 		binding.statusMessage.setAdapter(presenceTemplateAdapter);
 		binding.statusMessage.setOnItemClickListener((parent, view, position, id) -> {
 			PresenceTemplate template = (PresenceTemplate) parent.getItemAtPosition(position);
-			Log.d(Config.LOGTAG,"selected: "+template.getStatusMessage());
+			setAvailabilityRadioButton(template.getStatus(), binding);
 		});
-		builder.setTitle(R.string.change_presence);
+		builder.setTitle(R.string.edit_status_message_title);
 		builder.setView(binding.getRoot());
 		builder.setNegativeButton(R.string.cancel,null);
-		builder.setPositiveButton(R.string.confirm,null);
+		builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
+			PresenceTemplate template = new PresenceTemplate(getAvailabilityRadioButton(binding),binding.statusMessage.getText().toString().trim());
+			if (mAccount.getPgpId() != 0 && hasPgp()) {
+				generateSignature(null, template);
+			} else {
+				xmppConnectionService.changeStatus(mAccount, template, null);
+			}
+		});
 		builder.create().show();
 	}
 
+	private void generateSignature(Intent intent, PresenceTemplate template) {
+		xmppConnectionService.getPgpEngine().generateSignature(intent, mAccount, template.getStatusMessage(), new UiCallback<String>() {
+			@Override
+			public void success(String signature) {
+				xmppConnectionService.changeStatus(mAccount,template,signature);
+			}
+
+			@Override
+			public void error(int errorCode, String object) {
+
+			}
+
+			@Override
+			public void userInputRequried(PendingIntent pi, String object) {
+				mPendingPresenceTemplate.push(template);
+				try {
+					startIntentSenderForResult(pi.getIntentSender(), REQUEST_CHANGE_STATUS, null, 0, 0, 0);
+				} catch (final IntentSender.SendIntentException ignored) {
+				}
+			}
+		});
+	}
+
+	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) {

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

@@ -1,213 +0,0 @@
-package eu.siacs.conversations.ui;
-
-import android.content.Intent;
-import android.databinding.DataBindingUtil;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import java.util.List;
-
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.databinding.ActivitySetPresenceBinding;
-import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.entities.ListItem;
-import eu.siacs.conversations.entities.Presence;
-import eu.siacs.conversations.entities.PresenceTemplate;
-import eu.siacs.conversations.utils.UIHelper;
-
-public class SetPresenceActivity extends XmppActivity implements View.OnClickListener {
-
-	//data
-	protected Account mAccount;
-	private List<PresenceTemplate> mTemplates;
-
-	private ActivitySetPresenceBinding binding;
-
-	private Pair<Integer, Intent> mPostponedActivityResult;
-
-	private Runnable onPresenceChanged = new Runnable() {
-		@Override
-		public void run() {
-			finish();
-		}
-	};
-
-	protected void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		this.binding = DataBindingUtil.setContentView(this,R.layout.activity_set_presence);
-		ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
-				R.array.presence_show_options,
-				R.layout.simple_list_item);
-		this.binding.presenceShow.setAdapter(adapter);
-		this.binding.presenceShow.setSelection(1);
-		this.binding.changePresence.setOnClickListener(v -> executeChangePresence());
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu) {
-		getMenuInflater().inflate(R.menu.change_presence, menu);
-		return super.onCreateOptionsMenu(menu);
-	}
-
-	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
-		if (item.getItemId() == R.id.action_account_details) {
-			if (mAccount != null) {
-				switchToAccount(mAccount);
-			}
-			return true;
-		} else {
-			return super.onOptionsItemSelected(item);
-		}
-	}
-
-	@Override
-	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-		super.onActivityResult(requestCode, resultCode, data);
-		if (resultCode == RESULT_OK) {
-			if (xmppConnectionServiceBound && mAccount != null) {
-				if (requestCode == REQUEST_ANNOUNCE_PGP) {
-					announcePgp(mAccount, null,data, onPresenceChanged);
-				}
-				this.mPostponedActivityResult = null;
-			} else {
-				this.mPostponedActivityResult = new Pair<>(requestCode, data);
-			}
-		}
-	}
-
-	private void executeChangePresence() {
-		Presence.Status status = getStatusFromSpinner();
-		boolean allAccounts = this.binding.allAccounts.isChecked();
-		String statusMessage = this.binding.presenceStatusMessage.getText().toString().trim();
-		if (allAccounts && noAccountUsesPgp()) {
-			xmppConnectionService.changeStatus(status, statusMessage);
-			finish();
-		} else if (mAccount != null) {
-			if (mAccount.getPgpId() == 0 || !hasPgp()) {
-				xmppConnectionService.changeStatus(mAccount, status, statusMessage, true);
-				finish();
-			} else {
-				xmppConnectionService.changeStatus(mAccount, status, statusMessage, false);
-				announcePgp(mAccount, null,null, onPresenceChanged);
-			}
-		}
-	}
-
-	private Presence.Status getStatusFromSpinner() {
-		switch (this.binding.presenceShow.getSelectedItemPosition()) {
-			case 0:
-				return Presence.Status.CHAT;
-			case 2:
-				return Presence.Status.AWAY;
-			case 3:
-				return Presence.Status.XA;
-			case 4:
-				return Presence.Status.DND;
-			default:
-				return Presence.Status.ONLINE;
-		}
-	}
-
-	private void setStatusInSpinner(Presence.Status status) {
-		switch(status) {
-			case AWAY:
-				this.binding.presenceShow.setSelection(2);
-				break;
-			case XA:
-				this.binding.presenceShow.setSelection(3);
-				break;
-			case CHAT:
-				this.binding.presenceShow.setSelection(0);
-				break;
-			case DND:
-				this.binding.presenceShow.setSelection(4);
-				break;
-			default:
-				this.binding.presenceShow.setSelection(1);
-				break;
-		}
-	}
-
-	@Override
-	protected void refreshUiReal() {
-
-	}
-
-	@Override
-	void onBackendConnected() {
-		mAccount = extractAccount(getIntent());
-		if (mAccount != null) {
-			setStatusInSpinner(mAccount.getPresenceStatus());
-			String message = mAccount.getPresenceStatusMessage();
-			if (this.binding.presenceStatusMessage.getText().length() == 0 && message != null) {
-				this.binding.presenceStatusMessage.append(message);
-			}
-			mTemplates = xmppConnectionService.getPresenceTemplates(mAccount);
-			if (this.mPostponedActivityResult != null) {
-				this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
-			}
-			boolean e = noAccountUsesPgp();
-			this.binding.allAccounts.setEnabled(e);
-		}
-		redrawTemplates();
-	}
-
-	private void redrawTemplates() {
-		if (mTemplates == null || mTemplates.size() == 0) {
-			this.binding.templatesCard.setVisibility(View.GONE);
-		} else {
-			this.binding.templates.removeAllViews();
-			this.binding.templatesCard.setVisibility(View.VISIBLE);
-			LayoutInflater inflater = getLayoutInflater();
-			for (PresenceTemplate template : mTemplates) {
-				View templateLayout = inflater.inflate(R.layout.presence_template, this.binding.templates, false);
-				templateLayout.setTag(template);
-				setListItemBackgroundOnView(templateLayout);
-				templateLayout.setOnClickListener(this);
-				TextView message = (TextView) templateLayout.findViewById(R.id.presence_status_message);
-				TextView status = (TextView) templateLayout.findViewById(R.id.status);
-				ImageButton button = (ImageButton) templateLayout.findViewById(R.id.delete_button);
-				button.setTag(template);
-				button.setOnClickListener(this);
-				ListItem.Tag tag = UIHelper.getTagForStatus(this, template.getStatus());
-				status.setText(tag.getName());
-				status.setBackgroundColor(tag.getColor());
-				message.setText(template.getStatusMessage());
-				this.binding.templates.addView(templateLayout);
-			}
-		}
-	}
-
-	@Override
-	public void onClick(View v) {
-		PresenceTemplate template = (PresenceTemplate) v.getTag();
-		if (template == null) {
-			return;
-		}
-		if (v.getId() == R.id.presence_template) {
-			setStatusInSpinner(template.getStatus());
-			this.binding.presenceStatusMessage.getEditableText().clear();
-			this.binding.presenceStatusMessage.getEditableText().append(template.getStatusMessage());
-			new Handler().post(() -> this.binding.scrollView.smoothScrollTo(0,0));
-		} else if (v.getId() == R.id.delete_button) {
-			xmppConnectionService.databaseBackend.deletePresenceTemplate(template);
-			mTemplates.remove(template);
-			redrawTemplates();
-		}
-	}
-}

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

@@ -338,9 +338,6 @@ public class SettingsActivity extends XmppActivity implements
 				if (name.equals(AWAY_WHEN_SCREEN_IS_OFF) || name.equals(MANUALLY_CHANGE_PRESENCE)) {
 					xmppConnectionService.toggleScreenEventReceiver();
 				}
-				if (name.equals(MANUALLY_CHANGE_PRESENCE) && !noAccountUsesPgp()) {
-					Toast.makeText(this, R.string.republish_pgp_keys, Toast.LENGTH_LONG).show();
-				}
 				xmppConnectionService.refreshAllPresences();
 			}
 		} else if (name.equals("dont_trust_system_cas")) {

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

@@ -562,7 +562,7 @@ public abstract class XmppActivity extends AppCompatActivity {
 		startActivityForResult(ChooseContactActivity.create(this,conversation), REQUEST_INVITE_TO_CONVERSATION);
 	}
 
-	protected void announcePgp(Account account, final Conversation conversation, Intent intent, final Runnable onSuccess) {
+	protected void announcePgp(final Account account, final Conversation conversation, Intent intent, final Runnable onSuccess) {
 		if (account.getPgpId() == 0) {
 			choosePgpSignId(account);
 		} else {
@@ -573,10 +573,10 @@ public abstract class XmppActivity extends AppCompatActivity {
 			if (status == null) {
 				status = "";
 			}
-			xmppConnectionService.getPgpEngine().generateSignature(intent, account, status, new UiCallback<Account>() {
+			xmppConnectionService.getPgpEngine().generateSignature(intent, account, status, new UiCallback<String>() {
 
 				@Override
-				public void userInputRequried(PendingIntent pi, Account account) {
+				public void userInputRequried(PendingIntent pi, String signature) {
 					try {
 						startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
 					} catch (final SendIntentException ignored) {
@@ -584,7 +584,8 @@ public abstract class XmppActivity extends AppCompatActivity {
 				}
 
 				@Override
-				public void success(Account account) {
+				public void success(String signature) {
+					account.setPgpSignature(signature);
 					xmppConnectionService.databaseBackend.updateAccount(account);
 					xmppConnectionService.sendPresence(account);
 					if (conversation != null) {
@@ -598,8 +599,8 @@ public abstract class XmppActivity extends AppCompatActivity {
 				}
 
 				@Override
-				public void error(int error, Account account) {
-					if (error == 0 && account != null) {
+				public void error(int error, String signature) {
+					if (error == 0) {
 						account.setPgpSignId(0);
 						account.unsetPgpSignature();
 						xmppConnectionService.databaseBackend.updateAccount(account);

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

@@ -15,23 +15,25 @@
         android:layout_marginBottom="?attr/dialog_vertical_padding">
 
         <RadioButton
+            android:id="@+id/online"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/presence_online"/>
 
         <RadioButton
-            android:id="@+id/radioButton"
+            android:id="@+id/away"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/presence_away"/>
 
         <RadioButton
-            android:id="@+id/radioButton2"
+            android:id="@+id/xa"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/presence_xa"/>
 
         <RadioButton
+            android:id="@+id/dnd"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/presence_dnd"/>
@@ -46,7 +48,7 @@
         android:layout_height="wrap_content"
         android:ems="10"
         android:hint="@string/status_message"
-        android:inputType="textPersonName"/>
+        android:inputType="textShortMessage"/>
     </android.support.design.widget.TextInputLayout>
 
 </LinearLayout>

src/main/res/menu/editaccount.xml πŸ”—

@@ -5,7 +5,7 @@
         android:id="@+id/action_change_presence"
         android:icon="@drawable/ic_announcement_white_24dp"
         app:showAsAction="always"
-        android:title="@string/change_presence"/>
+        android:title="@string/edit_status_message"/>
 
     <item
         android:id="@+id/action_share"

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

@@ -164,7 +164,6 @@
 	<string name="unpublish_pgp">Remove OpenPGP public key</string>
 	<string name="unpublish_pgp_message">Are you sure you want to remove your OpenPGP public key from your presence announcement?\nYour contacts will no longer be able to send you OpenPGP encrypted messages.</string>
 	<string name="openpgp_has_been_published">OpenPGP public key has been published.</string>
-	<string name="republish_pgp_keys">Remember to republish your OpenPGP public keys!</string>
 	<string name="mgmt_account_enable">Enable account</string>
 	<string name="mgmt_account_are_you_sure">Are you sure?</string>
 	<string name="mgmt_account_delete_confirm_text">If you delete your account, your entire conversation history will be lost</string>
@@ -483,7 +482,7 @@
 	<string name="account_status_bind_failure">Bind failure</string>
 	<string name="account_status_host_unknown">Server not responsible for domain</string>
 	<string name="server_info_broken">Broken</string>
-	<string name="pref_presence_settings">Presence</string>
+	<string name="pref_presence_settings">Availability</string>
 	<string name="pref_away_when_screen_off">Away when screen is off</string>
 	<string name="pref_away_when_screen_off_summary">Marks your resource as away when the screen is turned off</string>
 	<string name="pref_dnd_on_silent_mode">β€œDo not disturb” in silent mode</string>
@@ -568,8 +567,8 @@
 	<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>
-	<string name="pref_manually_change_presence">Manually change presence</string>
-	<string name="pref_manually_change_presence_summary">Touch your avatar to change your presence</string>
+	<string name="pref_manually_change_presence">Manage availability manually</string>
+	<string name="pref_manually_change_presence_summary">Set your availability when editing your status message.</string>
 	<string name="change_presence">Change Presence</string>
 	<string name="status_message">Status message</string>
 	<string name="all_accounts_on_this_device">Set for all accounts on this device</string>
@@ -710,4 +709,6 @@
     <string name="qr_code_scanner_needs_access_to_camera">The QR code scanner needs access to the camera</string>
     <string name="pref_scroll_to_bottom">Scroll to bottom</string>
 	<string name="pref_scroll_to_bottom_summary">Scroll down after sending a message</string>
+    <string name="edit_status_message_title">Edit Status Message</string>
+	<string name="edit_status_message">Edit status message</string>
 </resources>