context menu for muc participants + refactor trueCounterpart to use Jid class

iNPUTmice created

Change summary

src/main/java/eu/siacs/conversations/entities/Message.java               | 25 
src/main/java/eu/siacs/conversations/entities/MucOptions.java            | 10 
src/main/java/eu/siacs/conversations/entities/Roster.java                |  5 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  2 
src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java   | 93 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        |  3 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java   |  2 
src/main/res/menu/muc_details_context.xml                                |  5 
8 files changed, 106 insertions(+), 39 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -49,7 +49,7 @@ public class Message extends AbstractEntity {
 	public boolean markable = false;
 	protected String conversationUuid;
 	protected Jid counterpart;
-	protected String trueCounterpart;
+	protected Jid trueCounterpart;
 	protected String body;
 	protected String encryptedBody;
 	protected long timeSent;
@@ -81,7 +81,7 @@ public class Message extends AbstractEntity {
 	}
 
 	public Message(final String uuid, final String conversationUUid, final Jid counterpart,
-				   final String trueCounterpart, final String body, final long timeSent,
+				   final Jid trueCounterpart, final String body, final long timeSent,
 				   final int encryption, final int status, final int type, final String remoteMsgId, final String relativeFilePath) {
 		this.uuid = uuid;
 		this.conversationUuid = conversationUUid;
@@ -108,10 +108,21 @@ public class Message extends AbstractEntity {
 		} catch (InvalidJidException e) {
 			jid = null;
 		}
+		Jid trueCounterpart;
+		try {
+			String value = cursor.getString(cursor.getColumnIndex(TRUE_COUNTERPART));
+			if (value!=null) {
+				trueCounterpart = Jid.fromString(value);
+			} else {
+				trueCounterpart = null;
+			}
+		} catch (InvalidJidException e) {
+			trueCounterpart = null;
+		}
 		return new Message(cursor.getString(cursor.getColumnIndex(UUID)),
 				cursor.getString(cursor.getColumnIndex(CONVERSATION)),
 				jid,
-				cursor.getString(cursor.getColumnIndex(TRUE_COUNTERPART)),
+				trueCounterpart,
 				cursor.getString(cursor.getColumnIndex(BODY)),
 				cursor.getLong(cursor.getColumnIndex(TIME_SENT)),
 				cursor.getInt(cursor.getColumnIndex(ENCRYPTION)),
@@ -138,7 +149,11 @@ public class Message extends AbstractEntity {
 		} else {
 			values.put(COUNTERPART, counterpart.toString());
 		}
-		values.put(TRUE_COUNTERPART, trueCounterpart);
+		if (trueCounterpart == null ) {
+			values.putNull(TRUE_COUNTERPART);
+		} else {
+			values.put(TRUE_COUNTERPART, trueCounterpart.toString());
+		}
 		values.put(BODY, body);
 		values.put(TIME_SENT, timeSent);
 		values.put(ENCRYPTION, encryption);
@@ -258,7 +273,7 @@ public class Message extends AbstractEntity {
 		this.type = type;
 	}
 
-	public void setTrueCounterpart(String trueCounterpart) {
+	public void setTrueCounterpart(Jid trueCounterpart) {
 		this.trueCounterpart = trueCounterpart;
 	}
 

src/main/java/eu/siacs/conversations/entities/MucOptions.java 🔗

@@ -43,7 +43,7 @@ public class MucOptions {
 		private int role;
 		private int affiliation;
 		private String name;
-		private String jid;
+		private Jid jid;
 		private long pgpKeyId = 0;
 
 		public String getName() {
@@ -54,11 +54,11 @@ public class MucOptions {
 			this.name = user;
 		}
 
-		public void setJid(String jid) {
+		public void setJid(Jid jid) {
 			this.jid = jid;
 		}
 
-		public String getJid() {
+		public Jid getJid() {
 			return this.jid;
 		}
 
@@ -165,7 +165,7 @@ public class MucOptions {
 						user.setName(name);
 						user.setAffiliation(item.getAttribute("affiliation"));
 						user.setRole(item.getAttribute("role"));
-						user.setJid(item.getAttribute("jid"));
+						user.setJid(item.getAttributeAsJid("jid"));
 						user.setName(name);
 						if (name.equals(this.joinnick)) {
 							this.isOnline = true;
@@ -346,7 +346,7 @@ public class MucOptions {
         }
     }
 
-	public String getTrueCounterpart(String counterpart) {
+	public Jid getTrueCounterpart(String counterpart) {
 		for (User user : this.getUsers()) {
 			if (user.getName().equals(counterpart)) {
 				return user.getJid();

src/main/java/eu/siacs/conversations/entities/Roster.java 🔗

@@ -15,12 +15,11 @@ public class Roster {
 		this.account = account;
 	}
 
-	public Contact getContactFromRoster(String jid) {
+	public Contact getContactFromRoster(Jid jid) {
 		if (jid == null) {
 			return null;
 		}
-		String cleanJid = jid.split("/", 2)[0];
-		Contact contact = contacts.get(cleanJid);
+		Contact contact = contacts.get(jid.toBareJid().toString());
 		if (contact != null && contact.showInRoster()) {
 			return contact;
 		} else {

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

@@ -1971,7 +1971,7 @@ public class XmppConnectionService extends Service {
 		return this.mJingleConnectionManager;
 	}
 
-	public List<Contact> findContacts(String jid) {
+	public List<Contact> findContacts(Jid jid) {
 		ArrayList<Contact> contacts = new ArrayList<>();
 		for (Account account : getAccounts()) {
 			if (!account.isOptionSet(Account.OPTION_DISABLED)) {

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

@@ -7,6 +7,7 @@ import android.content.IntentSender.SendIntentException;
 import android.graphics.Bitmap;
 import android.os.Build;
 import android.os.Bundle;
+import android.view.ContextMenu;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -35,12 +36,12 @@ import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 
 public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnRenameListener {
 	public static final String ACTION_VIEW_MUC = "view_muc";
-	private Conversation conversation;
+	private Conversation mConversation;
 	private OnClickListener inviteListener = new OnClickListener() {
 
 		@Override
 		public void onClick(View v) {
-			inviteToConversation(conversation);
+			inviteToConversation(mConversation);
 		}
 	};
 	private TextView mYourNick;
@@ -54,6 +55,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 	private Button mInviteButton;
 	private String uuid = null;
 	private List<User> users = new ArrayList<>();
+	private User mSelectedUser = null;
 
 	@Override
 	public void onRename(final boolean success) {
@@ -107,12 +109,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 
 			@Override
 			public void onClick(View v) {
-				quickEdit(conversation.getMucOptions().getActualNick(),
+				quickEdit(mConversation.getMucOptions().getActualNick(),
 						new OnValueEdited() {
 
 							@Override
 							public void onValueEdited(String value) {
-								xmppConnectionService.renameInMuc(conversation,
+								xmppConnectionService.renameInMuc(mConversation,
 										value);
 							}
 						});
@@ -127,16 +129,16 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 				finish();
 				break;
 			case R.id.action_edit_subject:
-				if (conversation != null) {
-					quickEdit(conversation.getName(), new OnValueEdited() {
+				if (mConversation != null) {
+					quickEdit(mConversation.getName(), new OnValueEdited() {
 
 						@Override
 						public void onValueEdited(String value) {
 							MessagePacket packet = xmppConnectionService
 									.getMessageGenerator().conferenceSubject(
-											conversation, value);
+											mConversation, value);
 							xmppConnectionService.sendMessagePacket(
-									conversation.getAccount(), packet);
+									mConversation.getAccount(), packet);
 						}
 					});
 				}
@@ -160,8 +162,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 
 	@Override
 	protected String getShareableUri() {
-		if (conversation != null) {
-			return "xmpp:" + conversation.getContactJid().toBareJid().toString() + "?join";
+		if (mConversation != null) {
+			return "xmpp:" + mConversation.getContactJid().toBareJid().toString() + "?join";
 		} else {
 			return "";
 		}
@@ -173,32 +175,75 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 		return true;
 	}
 
+	@Override
+	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+		Object tag = v.getTag();
+		if (tag instanceof User) {
+			getMenuInflater().inflate(R.menu.muc_details_context,menu);
+			final User user = (User) tag;
+			this.mSelectedUser = user;
+			String name;
+			final Contact contact = user.getContact();
+			if (contact != null) {
+				name = contact.getDisplayName();
+			} else if (user.getJid() != null) {
+				name = user.getJid().toBareJid().toString();
+			} else {
+				name = user.getName();
+			}
+			menu.setHeaderTitle(name);
+			MenuItem startConversation = menu.findItem(R.id.start_conversation);
+			if (user.getJid() == null) {
+				startConversation.setVisible(false);
+			}
+		}
+		super.onCreateContextMenu(menu,v,menuInfo);
+	}
+
+	@Override
+	public boolean onContextItemSelected(MenuItem item) {
+		switch (item.getItemId()) {
+			case R.id.start_conversation:
+				startConversation(mSelectedUser);
+				return true;
+			default:
+				return super.onContextItemSelected(item);
+		}
+	}
+
+	protected void startConversation(User user) {
+		if (user.getJid() != null) {
+			Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid(),false);
+			switchToConversation(conversation);
+		}
+	}
+
 	@Override
 	void onBackendConnected() {
 		if (getIntent().getAction().equals(ACTION_VIEW_MUC)) {
 			this.uuid = getIntent().getExtras().getString("uuid");
 		}
 		if (uuid != null) {
-			this.conversation = xmppConnectionService
+			this.mConversation = xmppConnectionService
 					.findConversationByUuid(uuid);
-			if (this.conversation != null) {
+			if (this.mConversation != null) {
 				populateView();
 			}
 		}
 	}
 
 	private void populateView() {
-		mAccountJid.setText(getString(R.string.using_account, conversation
+		mAccountJid.setText(getString(R.string.using_account, mConversation
 				.getAccount().getJid().toBareJid()));
 		mYourPhoto.setImageBitmap(avatarService().get(
-				conversation.getAccount(), getPixel(48)));
-		setTitle(conversation.getName());
-		mFullJid.setText(conversation.getContactJid().toBareJid().toString());
-		mYourNick.setText(conversation.getMucOptions().getActualNick());
+				mConversation.getAccount(), getPixel(48)));
+		setTitle(mConversation.getName());
+		mFullJid.setText(mConversation.getContactJid().toBareJid().toString());
+		mYourNick.setText(mConversation.getMucOptions().getActualNick());
 		mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
-		if (conversation.getMucOptions().online()) {
+		if (mConversation.getMucOptions().online()) {
 			mMoreDetails.setVisibility(View.VISIBLE);
-			User self = conversation.getMucOptions().getSelf();
+			User self = mConversation.getMucOptions().getSelf();
 			switch (self.getAffiliation()) {
 				case User.AFFILIATION_ADMIN:
 					mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " ("
@@ -214,19 +259,21 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 			}
 		}
 		this.users.clear();
-		this.users.addAll(conversation.getMucOptions().getUsers());
+		this.users.addAll(mConversation.getMucOptions().getUsers());
 		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		membersView.removeAllViews();
-		for (final User user : conversation.getMucOptions().getUsers()) {
+		for (final User user : mConversation.getMucOptions().getUsers()) {
 			View view = inflater.inflate(R.layout.contact, membersView,
 					false);
 			this.setListItemBackgroundOnView(view);
 			view.setOnClickListener(new OnClickListener() {
 				@Override
 				public void onClick(View view) {
-					highlightInMuc(conversation, user.getName());
+					highlightInMuc(mConversation, user.getName());
 				}
 			});
+			registerForContextMenu(view);
+			view.setTag(user);
 			TextView name = (TextView) view
 					.findViewById(R.id.contact_display_name);
 			TextView key = (TextView) view.findViewById(R.id.key);
@@ -274,7 +321,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 		PgpEngine pgp = xmppConnectionService.getPgpEngine();
 		if (pgp != null) {
 			PendingIntent intent = pgp.getIntentForKey(
-					conversation.getAccount(), user.getPgpKeyId());
+					mConversation.getAccount(), user.getPgpKeyId());
 			if (intent != null) {
 				try {
 					startIntentSenderForResult(intent.getIntentSender(), 0,

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

@@ -622,7 +622,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
 	}
 
 	private boolean handleJid(Invite invite) {
-		List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid().toString());
+		List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid());
 		if (contacts.size() == 0) {
 			showCreateContactDialog(invite.getJid().toString(),invite.getFingerprint());
 			return false;

src/main/res/menu/muc_details_context.xml 🔗

@@ -1,4 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
-
+    <item
+        android:id="@+id/start_conversation"
+        android:title="@string/start_conversation"
+        />
 </menu>