add 'log out' button to foreground notifcation

this temporarily disconnects all accounts until the user opens the app again.

essentially this akin to an 'Exit' button

Users previously had the option to 'disable' accounts but this provides a
faster way to "free up resources" until the next time the app is opened.
This commit is contained in:
Daniel Gultsch 2023-10-18 14:02:10 +02:00
parent 418d6b09a0
commit f042efd550
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
14 changed files with 131 additions and 88 deletions

View file

@ -359,6 +359,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
private void enableAccount(Account account) { private void enableAccount(Account account) {
account.setOption(Account.OPTION_DISABLED, false); account.setOption(Account.OPTION_DISABLED, false);
account.setOption(Account.OPTION_SOFT_DISABLED, false);
final XmppConnection connection = account.getXmppConnection(); final XmppConnection connection = account.getXmppConnection();
if (connection != null) { if (connection != null) {
connection.resetEverything(); connection.resetEverything();

View file

@ -70,6 +70,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
public static final int OPTION_UNVERIFIED = 8; public static final int OPTION_UNVERIFIED = 8;
public static final int OPTION_FIXED_USERNAME = 9; public static final int OPTION_FIXED_USERNAME = 9;
public static final int OPTION_QUICKSTART_AVAILABLE = 10; public static final int OPTION_QUICKSTART_AVAILABLE = 10;
public static final int OPTION_SOFT_DISABLED = 11;
private static final String KEY_PGP_SIGNATURE = "pgp_signature"; private static final String KEY_PGP_SIGNATURE = "pgp_signature";
private static final String KEY_PGP_ID = "pgp_id"; private static final String KEY_PGP_ID = "pgp_id";
@ -248,6 +249,10 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
return !isOptionSet(Account.OPTION_DISABLED); return !isOptionSet(Account.OPTION_DISABLED);
} }
public boolean isConnectionEnabled() {
return !isOptionSet(Account.OPTION_DISABLED) && !isOptionSet(Account.OPTION_SOFT_DISABLED);
}
public boolean isOptionSet(final int option) { public boolean isOptionSet(final int option) {
return ((options & (1 << option)) != 0); return ((options & (1 << option)) != 0);
} }
@ -322,6 +327,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
public State getStatus() { public State getStatus() {
if (isOptionSet(OPTION_DISABLED)) { if (isOptionSet(OPTION_DISABLED)) {
return State.DISABLED; return State.DISABLED;
} else if (isOptionSet(OPTION_SOFT_DISABLED)) {
return State.LOGGED_OUT;
} else { } else {
return this.status; return this.status;
} }
@ -765,6 +772,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
public enum State { public enum State {
DISABLED(false, false), DISABLED(false, false),
LOGGED_OUT(false,false),
OFFLINE(false), OFFLINE(false),
CONNECTING(false), CONNECTING(false),
ONLINE(false), ONLINE(false),
@ -824,6 +832,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
switch (this) { switch (this) {
case DISABLED: case DISABLED:
return R.string.account_status_disabled; return R.string.account_status_disabled;
case LOGGED_OUT:
return R.string.account_state_logged_out;
case ONLINE: case ONLINE:
return R.string.account_status_online; return R.string.account_status_online;
case CONNECTING: case CONNECTING:

View file

@ -22,6 +22,7 @@ import android.os.Build;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.Vibrator; import android.os.Vibrator;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -40,6 +41,7 @@ import androidx.core.graphics.drawable.IconCompat;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import java.io.File; import java.io.File;
@ -1661,12 +1663,25 @@ public class NotificationService {
} }
private PendingIntent createCallAction(String sessionId, final String action, int requestCode) { private PendingIntent createCallAction(String sessionId, final String action, int requestCode) {
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); return pendingServiceIntent(mXmppConnectionService, action, requestCode, ImmutableMap.of(RtpSessionActivity.EXTRA_SESSION_ID, sessionId));
}
private PendingIntent createSnoozeIntent(final Conversation conversation) {
return pendingServiceIntent(mXmppConnectionService, XmppConnectionService.ACTION_SNOOZE, generateRequestCode(conversation,22),ImmutableMap.of("uuid",conversation.getUuid()));
}
private static PendingIntent pendingServiceIntent(final Context context, final String action, final int requestCode) {
return pendingServiceIntent(context, action, requestCode, ImmutableMap.of());
}
private static PendingIntent pendingServiceIntent(final Context context, final String action, final int requestCode, final Map<String,String> extras) {
final Intent intent = new Intent(context, XmppConnectionService.class);
intent.setAction(action); intent.setAction(action);
intent.setPackage(mXmppConnectionService.getPackageName()); for(final Map.Entry<String,String> entry : extras.entrySet()) {
intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId); intent.putExtra(entry.getKey(), entry.getValue());
}
return PendingIntent.getService( return PendingIntent.getService(
mXmppConnectionService, context,
requestCode, requestCode,
intent, intent,
s() s()
@ -1674,44 +1689,6 @@ public class NotificationService {
: PendingIntent.FLAG_UPDATE_CURRENT); : PendingIntent.FLAG_UPDATE_CURRENT);
} }
private PendingIntent createSnoozeIntent(Conversation conversation) {
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
intent.setAction(XmppConnectionService.ACTION_SNOOZE);
intent.putExtra("uuid", conversation.getUuid());
intent.setPackage(mXmppConnectionService.getPackageName());
return PendingIntent.getService(
mXmppConnectionService,
generateRequestCode(conversation, 22),
intent,
s()
? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
: PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent createTryAgainIntent() {
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
intent.setAction(XmppConnectionService.ACTION_TRY_AGAIN);
return PendingIntent.getService(
mXmppConnectionService,
45,
intent,
s()
? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
: PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent createDismissErrorIntent() {
final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
intent.setAction(XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS);
return PendingIntent.getService(
mXmppConnectionService,
69,
intent,
s()
? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
: PendingIntent.FLAG_UPDATE_CURRENT);
}
private boolean wasHighlightedOrPrivate(final Message message) { private boolean wasHighlightedOrPrivate(final Message message) {
if (message.getConversation() instanceof Conversation) { if (message.getConversation() instanceof Conversation) {
Conversation conversation = (Conversation) message.getConversation(); Conversation conversation = (Conversation) message.getConversation();
@ -1756,17 +1733,15 @@ public class NotificationService {
final Notification.Builder mBuilder = new Notification.Builder(mXmppConnectionService); final Notification.Builder mBuilder = new Notification.Builder(mXmppConnectionService);
mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.app_name)); mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.app_name));
final List<Account> accounts = mXmppConnectionService.getAccounts(); final List<Account> accounts = mXmppConnectionService.getAccounts();
int enabled = 0; final int enabled;
int connected = 0; final int connected;
if (accounts != null) { if (accounts == null) {
for (Account account : accounts) { enabled = 0;
if (account.isOnlineAndConnected()) { connected = 0;
connected++; } else {
enabled++; enabled = Iterables.size(Iterables.filter(accounts, Account::isEnabled));
} else if (account.isEnabled()) { connected =
enabled++; Iterables.size(Iterables.filter(accounts, Account::isOnlineAndConnected));
}
}
} }
mBuilder.setContentText( mBuilder.setContentText(
mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled)); mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled));
@ -1784,11 +1759,36 @@ public class NotificationService {
if (Compatibility.runsTwentySix()) { if (Compatibility.runsTwentySix()) {
mBuilder.setChannelId("foreground"); mBuilder.setChannelId("foreground");
mBuilder.addAction(
R.drawable.ic_logout_white_24dp,
mXmppConnectionService.getString(R.string.log_out),
pendingServiceIntent(
mXmppConnectionService,
XmppConnectionService.ACTION_TEMPORARILY_DISABLE,
87));
mBuilder.addAction(
R.drawable.ic_notifications_off_white_24dp,
mXmppConnectionService.getString(R.string.hide_notification),
pendingNotificationSettingsIntent(mXmppConnectionService));
} }
return mBuilder.build(); return mBuilder.build();
} }
@RequiresApi(api = Build.VERSION_CODES.O)
private static PendingIntent pendingNotificationSettingsIntent(final Context context) {
final Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, "foreground");
return PendingIntent.getActivity(
context,
89,
intent,
s()
? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
: PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent createOpenConversationsIntent() { private PendingIntent createOpenConversationsIntent() {
try { try {
return PendingIntent.getActivity( return PendingIntent.getActivity(
@ -1839,7 +1839,7 @@ public class NotificationService {
mBuilder.addAction( mBuilder.addAction(
R.drawable.ic_autorenew_white_24dp, R.drawable.ic_autorenew_white_24dp,
mXmppConnectionService.getString(R.string.try_again), mXmppConnectionService.getString(R.string.try_again),
createTryAgainIntent()); pendingServiceIntent(mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45));
if (torNotAvailable) { if (torNotAvailable) {
if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) { if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
mBuilder.addAction( mBuilder.addAction(
@ -1867,7 +1867,7 @@ public class NotificationService {
: PendingIntent.FLAG_UPDATE_CURRENT)); : PendingIntent.FLAG_UPDATE_CURRENT));
} }
} }
mBuilder.setDeleteIntent(createDismissErrorIntent()); mBuilder.setDeleteIntent(pendingServiceIntent(mXmppConnectionService,XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS, 69));
mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
mBuilder.setLocalOnly(true); mBuilder.setLocalOnly(true);

View file

@ -184,6 +184,8 @@ public class XmppConnectionService extends Service {
public static final String ACTION_CLEAR_MISSED_CALL_NOTIFICATION = "clear_missed_call_notification"; public static final String ACTION_CLEAR_MISSED_CALL_NOTIFICATION = "clear_missed_call_notification";
public static final String ACTION_DISMISS_ERROR_NOTIFICATIONS = "dismiss_error"; public static final String ACTION_DISMISS_ERROR_NOTIFICATIONS = "dismiss_error";
public static final String ACTION_TRY_AGAIN = "try_again"; public static final String ACTION_TRY_AGAIN = "try_again";
public static final String ACTION_TEMPORARILY_DISABLE = "temporarily_disable";
public static final String ACTION_IDLE_PING = "idle_ping"; public static final String ACTION_IDLE_PING = "idle_ping";
public static final String ACTION_FCM_TOKEN_REFRESH = "fcm_token_refresh"; public static final String ACTION_FCM_TOKEN_REFRESH = "fcm_token_refresh";
public static final String ACTION_FCM_MESSAGE_RECEIVED = "fcm_message_received"; public static final String ACTION_FCM_MESSAGE_RECEIVED = "fcm_message_received";
@ -452,9 +454,9 @@ public class XmppConnectionService extends Service {
joinMuc(conversation); joinMuc(conversation);
} }
scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode());
} else if (account.getStatus() == Account.State.OFFLINE || account.getStatus() == Account.State.DISABLED) { } else if (account.getStatus() == Account.State.OFFLINE || account.getStatus() == Account.State.DISABLED || account.getStatus() == Account.State.LOGGED_OUT) {
resetSendingToWaiting(account); resetSendingToWaiting(account);
if (account.isEnabled() && isInLowPingTimeoutMode(account)) { if (account.isConnectionEnabled() && isInLowPingTimeoutMode(account)) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": went into offline state during low ping mode. reconnecting now"); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": went into offline state during low ping mode. reconnecting now");
reconnectAccount(account, true, false); reconnectAccount(account, true, false);
} else { } else {
@ -846,6 +848,9 @@ public class XmppConnectionService extends Service {
Log.d(Config.LOGTAG, "received uri permission for " + uri); Log.d(Config.LOGTAG, "received uri permission for " + uri);
} }
return START_STICKY; return START_STICKY;
case ACTION_TEMPORARILY_DISABLE:
toggleSoftDisabled(true);
return START_NOT_STICKY;
} }
} }
synchronized (this) { synchronized (this) {
@ -961,6 +966,16 @@ public class XmppConnectionService extends Service {
return pingNow; return pingNow;
} }
private void toggleSoftDisabled(final boolean softDisabled) {
for(final Account account : this.accounts) {
if (account.isEnabled()) {
if (account.setOption(Account.OPTION_SOFT_DISABLED, softDisabled)) {
updateAccount(account);
}
}
}
}
public boolean processUnifiedPushMessage(final Account account, final Jid transport, final Element push) { public boolean processUnifiedPushMessage(final Account account, final Jid transport, final Element push) {
return unifiedPushBroker.processPushMessage(account, transport, push); return unifiedPushBroker.processPushMessage(account, transport, push);
} }
@ -1449,7 +1464,7 @@ public class XmppConnectionService extends Service {
private void logoutAndSave(boolean stop) { private void logoutAndSave(boolean stop) {
int activeAccounts = 0; int activeAccounts = 0;
for (final Account account : accounts) { for (final Account account : accounts) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isConnectionEnabled()) {
databaseBackend.writeRoster(account.getRoster()); databaseBackend.writeRoster(account.getRoster());
activeAccounts++; activeAccounts++;
} }
@ -2808,6 +2823,7 @@ public class XmppConnectionService extends Service {
} }
private void switchToForeground() { private void switchToForeground() {
toggleSoftDisabled(false);
final boolean broadcastLastActivity = broadcastLastActivity(); final boolean broadcastLastActivity = broadcastLastActivity();
for (Conversation conversation : getConversations()) { for (Conversation conversation : getConversations()) {
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
@ -3188,8 +3204,8 @@ public class XmppConnectionService extends Service {
if (this.accounts == null) { if (this.accounts == null) {
return false; return false;
} }
for (Account account : this.accounts) { for (final Account account : this.accounts) {
if (account.isEnabled()) { if (account.isConnectionEnabled()) {
return true; return true;
} }
} }
@ -3587,12 +3603,13 @@ public class XmppConnectionService extends Service {
}); });
} }
private void disconnect(Account account, boolean force) { private void disconnect(final Account account, boolean force) {
if ((account.getStatus() == Account.State.ONLINE)
|| (account.getStatus() == Account.State.DISABLED)) {
final XmppConnection connection = account.getXmppConnection(); final XmppConnection connection = account.getXmppConnection();
if (connection == null) {
return;
}
if (!force) { if (!force) {
List<Conversation> conversations = getConversations(); final List<Conversation> conversations = getConversations();
for (Conversation conversation : conversations) { for (Conversation conversation : conversations) {
if (conversation.getAccount() == account) { if (conversation.getAccount() == account) {
if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getMode() == Conversation.MODE_MULTI) {
@ -3604,7 +3621,6 @@ public class XmppConnectionService extends Service {
} }
connection.disconnect(force); connection.disconnect(force);
} }
}
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
@ -4093,7 +4109,7 @@ public class XmppConnectionService extends Service {
account.setXmppConnection(connection); account.setXmppConnection(connection);
} }
boolean hasInternet = hasInternetConnection(); boolean hasInternet = hasInternetConnection();
if (account.isEnabled() && hasInternet) { if (account.isConnectionEnabled() && hasInternet) {
if (!force) { if (!force) {
disconnect(account, false); disconnect(account, false);
} }
@ -4581,7 +4597,7 @@ public class XmppConnectionService extends Service {
public void refreshAllPresences() { public void refreshAllPresences() {
boolean includeIdleTimestamp = checkListeners() && broadcastLastActivity(); boolean includeIdleTimestamp = checkListeners() && broadcastLastActivity();
for (Account account : getAccounts()) { for (Account account : getAccounts()) {
if (account.isEnabled()) { if (account.isConnectionEnabled()) {
sendPresence(account, includeIdleTimestamp); sendPresence(account, includeIdleTimestamp);
} }
} }

View file

@ -270,7 +270,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
return; return;
} }
for (final Account account : xmppConnectionService.getAccounts()) { for (final Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
for (final Contact contact : account.getRoster().getContacts()) { for (final Contact contact : account.getRoster().getContacts()) {
if (contact.showInContactList() && if (contact.showInContactList() &&
!filterContacts.contains(contact.getJid().asBareJid().toString()) !filterContacts.contains(contact.getJid().asBareJid().toString())
@ -362,7 +362,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
filterContacts(); filterContacts();
this.mActivatedAccounts.clear(); this.mActivatedAccounts.clear();
for (Account account : xmppConnectionService.getAccounts()) { for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
if (Config.DOMAIN_LOCK != null) { if (Config.DOMAIN_LOCK != null) {
this.mActivatedAccounts.add(account.getJid().getEscapedLocal()); this.mActivatedAccounts.add(account.getJid().getEscapedLocal());
} else { } else {
@ -382,6 +382,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
ScanActivity.onRequestPermissionResult(this, requestCode, grantResults); ScanActivity.onRequestPermissionResult(this, requestCode, grantResults);
} }

View file

@ -416,6 +416,7 @@ public class ConversationFragment extends XmppFragment
public void onClick(View v) { public void onClick(View v) {
final Account account = conversation == null ? null : conversation.getAccount(); final Account account = conversation == null ? null : conversation.getAccount();
if (account != null) { if (account != null) {
account.setOption(Account.OPTION_SOFT_DISABLED, false);
account.setOption(Account.OPTION_DISABLED, false); account.setOption(Account.OPTION_DISABLED, false);
activity.xmppConnectionService.updateAccount(account); activity.xmppConnectionService.updateAccount(account);
} }
@ -2660,6 +2661,8 @@ public class ConversationFragment extends XmppFragment
R.string.this_account_is_disabled, R.string.this_account_is_disabled,
R.string.enable, R.string.enable,
this.mEnableAccountListener); this.mEnableAccountListener);
} else if (account.getStatus() == Account.State.LOGGED_OUT) {
showSnackbar(R.string.this_account_is_logged_out,R.string.log_in,this.mEnableAccountListener);
} else if (conversation.isBlocked()) { } else if (conversation.isBlocked()) {
showSnackbar(R.string.contact_blocked, R.string.unblock, this.mUnblockClickListener); showSnackbar(R.string.contact_blocked, R.string.unblock, this.mUnblockClickListener);
} else if (contact != null } else if (contact != null

View file

@ -149,7 +149,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
if (mInitMode && mAccount != null) { if (mInitMode && mAccount != null) {
mAccount.setOption(Account.OPTION_DISABLED, false); mAccount.setOption(Account.OPTION_DISABLED, false);
} }
if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED && !accountInfoEdited) { if (mAccount != null && Arrays.asList(Account.State.DISABLED, Account.State.LOGGED_OUT).contains(mAccount.getStatus()) && !accountInfoEdited) {
mAccount.setOption(Account.OPTION_SOFT_DISABLED, false);
mAccount.setOption(Account.OPTION_DISABLED, false); mAccount.setOption(Account.OPTION_DISABLED, false);
if (!xmppConnectionService.updateAccount(mAccount)) { if (!xmppConnectionService.updateAccount(mAccount)) {
Toast.makeText(EditAccountActivity.this, R.string.unable_to_update_account, Toast.LENGTH_SHORT).show(); Toast.makeText(EditAccountActivity.this, R.string.unable_to_update_account, Toast.LENGTH_SHORT).show();

View file

@ -61,7 +61,7 @@ public class ShortcutActivity extends AbstractSearchableListItemActivity {
return; return;
} }
for (final Account account : xmppConnectionService.getAccounts()) { for (final Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
for (final Contact contact : account.getRoster().getContacts()) { for (final Contact contact : account.getRoster().getContacts()) {
if (contact.showInContactList() if (contact.showInContactList()
&& contact.match(this, needle)) { && contact.match(this, needle)) {

View file

@ -971,8 +971,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
protected void filterContacts(String needle) { protected void filterContacts(String needle) {
this.contacts.clear(); this.contacts.clear();
final List<Account> accounts = xmppConnectionService.getAccounts(); final List<Account> accounts = xmppConnectionService.getAccounts();
for (Account account : accounts) { for (final Account account : accounts) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
for (Contact contact : account.getRoster().getContacts()) { for (Contact contact : account.getRoster().getContacts()) {
Presence.Status s = contact.getShownStatus(); Presence.Status s = contact.getShownStatus();
if (contact.showInContactList() && contact.match(this, needle) if (contact.showInContactList() && contact.match(this, needle)
@ -991,7 +991,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
protected void filterConferences(String needle) { protected void filterConferences(String needle) {
this.conferences.clear(); this.conferences.clear();
for (final Account account : xmppConnectionService.getAccounts()) { for (final Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
for (final Bookmark bookmark : account.getBookmarks()) { for (final Bookmark bookmark : account.getBookmarks()) {
if (bookmark.match(this, needle)) { if (bookmark.match(this, needle)) {
this.conferences.add(bookmark); this.conferences.add(bookmark);

View file

@ -59,6 +59,7 @@ public class AccountAdapter extends ArrayAdapter<Account> {
viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline)); viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline));
break; break;
case DISABLED: case DISABLED:
case LOGGED_OUT:
case CONNECTING: case CONNECTING:
viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary)); viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary));
break; break;

View file

@ -60,7 +60,7 @@ public class AccountUtils {
public static List<String> getEnabledAccounts(final XmppConnectionService service) { public static List<String> getEnabledAccounts(final XmppConnectionService service) {
final ArrayList<String> accounts = new ArrayList<>(); final ArrayList<String> accounts = new ArrayList<>();
for (final Account account : service.getAccounts()) { for (final Account account : service.getAccounts()) {
if (account.getStatus() != Account.State.DISABLED) { if (account.isEnabled()) {
if (Config.DOMAIN_LOCK != null) { if (Config.DOMAIN_LOCK != null) {
accounts.add(account.getJid().getEscapedLocal()); accounts.add(account.getJid().getEscapedLocal());
} else { } else {

View file

@ -233,10 +233,11 @@ public class XmppConnection implements Runnable {
return; return;
} }
if (account.getStatus() != nextStatus) { if (account.getStatus() != nextStatus) {
if ((nextStatus == Account.State.OFFLINE) if (nextStatus == Account.State.OFFLINE
&& (account.getStatus() != Account.State.CONNECTING) && account.getStatus() != Account.State.CONNECTING
&& (account.getStatus() != Account.State.ONLINE) && account.getStatus() != Account.State.ONLINE
&& (account.getStatus() != Account.State.DISABLED)) { && account.getStatus() != Account.State.DISABLED
&& account.getStatus() != Account.State.LOGGED_OUT) {
return; return;
} }
if (nextStatus == Account.State.ONLINE) { if (nextStatus == Account.State.ONLINE) {

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,7l-1.41,1.41L18.17,11H8v2h10.17l-2.58,2.58L17,17l5,-5zM4,5h8V3H4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h8v-2H4V5z"/>
</vector>

View file

@ -153,6 +153,7 @@
<string name="error_security_exception">The app you used to share this file did not provide enough permissions.</string> <string name="error_security_exception">The app you used to share this file did not provide enough permissions.</string>
<string name="account_status_unknown">Unknown</string> <string name="account_status_unknown">Unknown</string>
<string name="account_status_disabled">Temporarily disabled</string> <string name="account_status_disabled">Temporarily disabled</string>
<string name="account_state_logged_out">Logged out</string>
<string name="account_status_online">Online</string> <string name="account_status_online">Online</string>
<string name="account_status_connecting">Connecting\u2026</string> <string name="account_status_connecting">Connecting\u2026</string>
<string name="account_status_offline">Offline</string> <string name="account_status_offline">Offline</string>
@ -538,6 +539,7 @@
<string name="send_corrected_message">Send corrected message</string> <string name="send_corrected_message">Send corrected message</string>
<string name="no_keys_just_confirm">You have already validated this persons fingerprint securely to confirm trust. By selecting “Done” you are just confirming that %s is part of this group chat.</string> <string name="no_keys_just_confirm">You have already validated this persons fingerprint securely to confirm trust. By selecting “Done” you are just confirming that %s is part of this group chat.</string>
<string name="this_account_is_disabled">You have disabled this account</string> <string name="this_account_is_disabled">You have disabled this account</string>
<string name="this_account_is_logged_out">You have logged out of this account</string>
<string name="security_error_invalid_file_access">Security error: Invalid file access!</string> <string name="security_error_invalid_file_access">Security error: Invalid file access!</string>
<string name="no_application_to_share_uri">No app found to share URI</string> <string name="no_application_to_share_uri">No app found to share URI</string>
<string name="share_uri_with">Share URI with…</string> <string name="share_uri_with">Share URI with…</string>
@ -1013,5 +1015,7 @@
<string name="decline">Decline</string> <string name="decline">Decline</string>
<string name="delete_from_server">Remove account from server</string> <string name="delete_from_server">Remove account from server</string>
<string name="could_not_delete_account_from_server">Could not delete account from server</string> <string name="could_not_delete_account_from_server">Could not delete account from server</string>
<string name="hide_notification">Hide notification</string>
<string name="log_out">Log out</string>
<string name="log_in">Log in</string>
</resources> </resources>