closing the corresponding conversations after blocking a contact. fixes #2347

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/parser/IqParser.java                |  9 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 32 
src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java          | 27 
src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java           |  7 
src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java      |  4 
src/main/java/eu/siacs/conversations/ui/ConversationActivity.java        | 72 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        |  2 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java   |  2 
src/main/res/values/strings.xml                                          |  2 
9 files changed, 111 insertions(+), 46 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/parser/IqParser.java 🔗

@@ -321,11 +321,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
 				}
 				account.getBlocklist().addAll(jids);
 				if (packet.getType() == IqPacket.TYPE.SET) {
+					boolean removed = false;
 					for(Jid jid : jids) {
-						Conversation conversation = mXmppConnectionService.find(account,jid);
-						if (conversation != null) {
-							mXmppConnectionService.markRead(conversation);
-						}
+						removed |= mXmppConnectionService.removeBlockedConversations(account,jid);
+					}
+					if (removed) {
+						mXmppConnectionService.updateConversationUi();
 					}
 				}
 			}

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -3643,7 +3643,7 @@ public class XmppConnectionService extends Service {
 		mDatabaseExecutor.execute(runnable);
 	}
 
-	public void sendBlockRequest(final Blockable blockable, boolean reportSpam) {
+	public boolean sendBlockRequest(final Blockable blockable, boolean reportSpam) {
 		if (blockable != null && blockable.getBlockedJid() != null) {
 			final Jid jid = blockable.getBlockedJid();
 			this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid, reportSpam), new OnIqPacketReceived() {
@@ -3656,9 +3656,39 @@ public class XmppConnectionService extends Service {
 					}
 				}
 			});
+			if (removeBlockedConversations(blockable.getAccount(),jid)) {
+				updateConversationUi();
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
 		}
 	}
 
+	public boolean removeBlockedConversations(final Account account, final Jid blockedJid) {
+		boolean removed = false;
+		synchronized (this.conversations) {
+			boolean domainJid = blockedJid.isDomainJid();
+			for(Conversation conversation : this.conversations) {
+				boolean jidMatches = (domainJid && blockedJid.getDomainpart().equals(conversation.getJid().getDomainpart()))
+						|| blockedJid.equals(conversation.getJid().toBareJid());
+				if (conversation.getAccount() == account
+						&& conversation.getMode() == Conversation.MODE_SINGLE
+						&& jidMatches) {
+					this.conversations.remove(conversation);
+					markRead(conversation);
+					conversation.setStatus(Conversation.STATUS_ARCHIVED);
+					Log.d(Config.LOGTAG,account.getJid().toBareJid()+": archiving conversation "+conversation.getJid().toBareJid()+" because jid was blocked");
+					updateConversation(conversation);
+					removed = true;
+				}
+			}
+		}
+		return removed;
+	}
+
 	public void sendUnblockRequest(final Blockable blockable) {
 		if (blockable != null && blockable.getJid() != null) {
 			final Jid jid = blockable.getBlockedJid();

src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java 🔗

@@ -11,19 +11,18 @@ import android.view.View;
 import android.widget.CheckBox;
 import android.widget.LinearLayout;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Blockable;
-import eu.siacs.conversations.services.XmppConnectionService;
 
 public final class BlockContactDialog {
-	public static void show(final Context context,
-			final XmppConnectionService xmppConnectionService,
+	public static void show(final XmppActivity xmppActivity,
 			final Blockable blockable) {
-		final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+		final AlertDialog.Builder builder = new AlertDialog.Builder(xmppActivity);
 		final boolean isBlocked = blockable.isBlocked();
 		builder.setNegativeButton(R.string.cancel, null);
-		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		LayoutInflater inflater = (LayoutInflater) xmppActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		LinearLayout view = (LinearLayout) inflater.inflate(R.layout.dialog_block_contact,null);
 		TextView message = (TextView) view.findViewById(R.id.text);
 		final CheckBox report = (CheckBox) view.findViewById(R.id.report_spam);
@@ -36,11 +35,11 @@ public final class BlockContactDialog {
 		if (blockable.getJid().isDomainJid() || blockable.getAccount().isBlocked(blockable.getJid().toDomainJid())) {
 			builder.setTitle(isBlocked ? R.string.action_unblock_domain : R.string.action_block_domain);
 			value = blockable.getJid().toDomainJid().toString();
-			spannable = new SpannableString(context.getString(isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text, value));
+			spannable = new SpannableString(xmppActivity.getString(isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text, value));
 		} else {
 			builder.setTitle(isBlocked ? R.string.action_unblock_contact : R.string.action_block_contact);
 			value = blockable.getJid().toBareJid().toString();
-			spannable = new SpannableString(context.getString(isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text, value));
+			spannable = new SpannableString(xmppActivity.getString(isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text, value));
 		}
 		int start = spannable.toString().indexOf(value);
 		if (start >= 0) {
@@ -52,9 +51,19 @@ public final class BlockContactDialog {
 			@Override
 			public void onClick(final DialogInterface dialog, final int which) {
 				if (isBlocked) {
-					xmppConnectionService.sendUnblockRequest(blockable);
+					xmppActivity.xmppConnectionService.sendUnblockRequest(blockable);
 				} else {
-					xmppConnectionService.sendBlockRequest(blockable, report.isChecked());
+					boolean toastShown = false;
+					if (xmppActivity.xmppConnectionService.sendBlockRequest(blockable, report.isChecked())) {
+						Toast.makeText(xmppActivity,R.string.corresponding_conversations_closed,Toast.LENGTH_SHORT).show();
+						toastShown = true;
+					}
+					if (xmppActivity instanceof ContactDetailsActivity) {
+						if (!toastShown) {
+							Toast.makeText(xmppActivity,R.string.contact_blocked_past_tense,Toast.LENGTH_SHORT).show();
+						}
+						xmppActivity.finish();
+					}
 				}
 			}
 		});

src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java 🔗

@@ -6,6 +6,7 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.AdapterView;
+import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -32,7 +33,7 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem
 					final View view,
 					final int position,
 					final long id) {
-				BlockContactDialog.show(parent.getContext(), xmppConnectionService,(Contact) getListItems().get(position));
+				BlockContactDialog.show(BlocklistActivity.this, (Contact) getListItems().get(position));
 				return true;
 			}
 		});
@@ -93,7 +94,9 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem
 			@Override
 			public boolean onEnterJidDialogPositive(Jid accountJid, Jid contactJid) throws EnterJidDialog.JidError {
 				Contact contact = account.getRoster().getContact(contactJid);
-                xmppConnectionService.sendBlockRequest(contact, false);
+                if (xmppConnectionService.sendBlockRequest(contact, false)) {
+					Toast.makeText(BlocklistActivity.this,R.string.corresponding_conversations_closed,Toast.LENGTH_SHORT).show();
+				}
 				return true;
 			}
 		});

src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java 🔗

@@ -296,10 +296,10 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
 				}
 				break;
 			case R.id.action_block:
-				BlockContactDialog.show(this, xmppConnectionService, contact);
+				BlockContactDialog.show(this, contact);
 				break;
 			case R.id.action_unblock:
-				BlockContactDialog.show(this, xmppConnectionService, contact);
+				BlockContactDialog.show(this, contact);
 				break;
 		}
 		return super.onOptionsItemSelected(menuItem);

src/main/java/eu/siacs/conversations/ui/ConversationActivity.java 🔗

@@ -712,10 +712,10 @@ public class ConversationActivity extends XmppActivity
 					unmuteConversation(getSelectedConversation());
 					break;
 				case R.id.action_block:
-					BlockContactDialog.show(this, xmppConnectionService, getSelectedConversation());
+					BlockContactDialog.show(this, getSelectedConversation());
 					break;
 				case R.id.action_unblock:
-					BlockContactDialog.show(this, xmppConnectionService, getSelectedConversation());
+					BlockContactDialog.show(this, getSelectedConversation());
 					break;
 				default:
 					break;
@@ -1175,6 +1175,18 @@ public class ConversationActivity extends XmppActivity
 		mPostponedActivityResult = null;
 	}
 
+	private void redirectToStartConversationActivity() {
+		Account pendingAccount = xmppConnectionService.getPendingAccount();
+		if (pendingAccount == null) {
+			Intent startConversationActivity = new Intent(this, StartConversationActivity.class);
+			startConversationActivity.putExtra("init", true);
+			startActivity(startConversationActivity);
+		} else {
+			switchToAccount(pendingAccount, true);
+		}
+		finish();
+	}
+
 	@Override
 	void onBackendConnected() {
 		this.xmppConnectionService.getNotificationService().setIsInForeground(true);
@@ -1205,15 +1217,7 @@ public class ConversationActivity extends XmppActivity
 			}
 		} else if (conversationList.size() <= 0) {
 			if (mRedirected.compareAndSet(false, true)) {
-				Account pendingAccount = xmppConnectionService.getPendingAccount();
-				if (pendingAccount == null) {
-					Intent startConversationActivity = new Intent(this, StartConversationActivity.class);
-					intent.putExtra("init", true);
-					startActivity(startConversationActivity);
-				} else {
-					switchToAccount(pendingAccount, true);
-				}
-				finish();
+				redirectToStartConversationActivity();
 			}
 		} else if (selectConversationByUuid(mOpenConversation)) {
 			if (mPanelOpen) {
@@ -1234,10 +1238,7 @@ public class ConversationActivity extends XmppActivity
 			handleViewConversationIntent(intent);
 			intent.setAction(Intent.ACTION_MAIN);
 		} else if (getSelectedConversation() == null) {
-			showConversationsOverview();
-			clearPending();
-			setSelectedConversation(conversationList.get(0));
-			this.mConversationFragment.reInit(getSelectedConversation());
+			reInitLatestConversation();
 		} else {
 			this.mConversationFragment.messageListAdapter.updatePreferences();
 			this.mConversationFragment.messagesView.invalidateViews();
@@ -1248,12 +1249,7 @@ public class ConversationActivity extends XmppActivity
 			this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
 		}
 
-		final boolean stopping;
-		if (Build.VERSION.SDK_INT >= 17) {
-			stopping = isFinishing() || isDestroyed();
-		} else {
-			stopping = isFinishing();
-		}
+		final boolean stopping = isStopping();
 
 		if (!forbidProcessingPendings) {
 			for (Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
@@ -1284,6 +1280,21 @@ public class ConversationActivity extends XmppActivity
 		}
 	}
 
+	private boolean isStopping() {
+		if (Build.VERSION.SDK_INT >= 17) {
+			return isFinishing() || isDestroyed();
+		} else {
+			return isFinishing();
+		}
+	}
+
+	private void reInitLatestConversation() {
+		showConversationsOverview();
+		clearPending();
+		setSelectedConversation(conversationList.get(0));
+		this.mConversationFragment.reInit(getSelectedConversation());
+	}
+
 	private void handleViewConversationIntent(final Intent intent) {
 		final String uuid = intent.getStringExtra(CONVERSATION);
 		final String downloadUuid = intent.getStringExtra(EXTRA_DOWNLOAD_UUID);
@@ -1643,8 +1654,10 @@ public class ConversationActivity extends XmppActivity
 	}
 
 	public void updateConversationList() {
-		xmppConnectionService
-			.populateWithOrderedConversations(conversationList);
+		xmppConnectionService.populateWithOrderedConversations(conversationList);
+		if (!conversationList.contains(mSelectedConversation)) {
+			mSelectedConversation = null;
+		}
 		if (swipedConversation != null) {
 			if (swipedConversation.isRead()) {
 				conversationList.remove(swipedConversation);
@@ -1748,10 +1761,17 @@ public class ConversationActivity extends XmppActivity
 			if (!this.mConversationFragment.isAdded()) {
 				Log.d(Config.LOGTAG,"fragment NOT added to activity. detached="+Boolean.toString(mConversationFragment.isDetached()));
 			}
-			ConversationActivity.this.mConversationFragment.updateMessages();
-			updateActionBarTitle();
-			invalidateOptionsMenu();
+			if (getSelectedConversation() == null) {
+				reInitLatestConversation();
+			} else {
+				ConversationActivity.this.mConversationFragment.updateMessages();
+				updateActionBarTitle();
+				invalidateOptionsMenu();
+			}
 		} else {
+			if (!isStopping() && mRedirected.compareAndSet(false, true)) {
+				redirectToStartConversationActivity();
+			}
 			Log.d(Config.LOGTAG,"not updating conversations fragment because conversations list size was 0");
 		}
 	}

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -947,7 +947,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 				}
 			});
 			if (conversation.isDomainBlocked()) {
-				BlockContactDialog.show(activity, activity.xmppConnectionService, conversation);
+				BlockContactDialog.show(activity, conversation);
 			} else {
 				activity.unblockConversation(conversation);
 			}

src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java 🔗

@@ -374,7 +374,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
 
     protected void toggleContactBlock() {
         final int position = contact_context_id;
-        BlockContactDialog.show(this, xmppConnectionService, (Contact) contacts.get(position));
+        BlockContactDialog.show(this, (Contact) contacts.get(position));
     }
 
     protected void deleteContact() {

src/main/res/values/strings.xml 🔗

@@ -734,4 +734,6 @@
 	<string name="encrypting_message">Encrypting message</string>
 	<string name="not_fetching_history_retention_period">Not fetching messages due to local retention period.</string>
 	<string name="transcoding_video_progress">Compressing video (%s%% completed)</string>
+	<string name="corresponding_conversations_closed">Corresponding conversations closed.</string>
+	<string name="contact_blocked_past_tense">Contact blocked.</string>
 </resources>