display chat states in conferences

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/MucOptions.java       |  5 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java   | 30 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 33 
src/main/java/eu/siacs/conversations/utils/UIHelper.java            | 12 
src/main/res/layout/message_status.xml                              |  2 
src/main/res/values/strings.xml                                     |  2 
6 files changed, 71 insertions(+), 13 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/MucOptions.java πŸ”—

@@ -544,12 +544,15 @@ public class MucOptions {
 		}
 	}
 
-	public ArrayList<User> getUsersWithChatState(ChatState state) {
+	public ArrayList<User> getUsersWithChatState(ChatState state, int max) {
 		synchronized (users) {
 			ArrayList<User> list = new ArrayList<>();
 			for(User user : users) {
 				if (user.chatState == state) {
 					list.add(user);
+					if (list.size() >= max) {
+						break;
+					}
 				}
 			}
 			return list;

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

@@ -1284,6 +1284,36 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 						}
 					}
 				}
+			} else {
+				ChatState state = ChatState.COMPOSING;
+				List<MucOptions.User> users = conversation.getMucOptions().getUsersWithChatState(state,5);
+				if (users.size() == 0) {
+					state = ChatState.PAUSED;
+					users = conversation.getMucOptions().getUsersWithChatState(state, 5);
+
+				}
+				if (users.size() > 0) {
+					Message statusMessage;
+					if (users.size() == 1) {
+						MucOptions.User user = users.get(0);
+						int id = state == ChatState.COMPOSING ? R.string.contact_is_typing : R.string.contact_has_stopped_typing;
+						statusMessage = Message.createStatusMessage(conversation, getString(id, UIHelper.getDisplayName(user)));
+						statusMessage.setTrueCounterpart(user.getRealJid());
+						statusMessage.setCounterpart(user.getFullJid());
+					} else {
+						StringBuilder builder = new StringBuilder();
+						for(MucOptions.User user : users) {
+							if (builder.length() != 0) {
+								builder.append(", ");
+							}
+							builder.append(UIHelper.getDisplayName(user));
+						}
+						int id = state == ChatState.COMPOSING ? R.string.contacts_are_typing : R.string.contacts_have_stopped_typing;
+						statusMessage = Message.createStatusMessage(conversation, getString(id, builder.toString()));
+					}
+					this.messageList.add(statusMessage);
+				}
+
 			}
 		}
 	}

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

@@ -667,19 +667,28 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 				});
 			} else {
 				viewHolder.status_message.setVisibility(View.VISIBLE);
-				viewHolder.contact_picture.setVisibility(View.VISIBLE);
 				viewHolder.load_more_messages.setVisibility(View.GONE);
+				viewHolder.status_message.setText(message.getBody());
+				boolean showAvatar;
 				if (conversation.getMode() == Conversation.MODE_SINGLE) {
-					viewHolder.contact_picture.setImageBitmap(activity
-							.avatarService().get(conversation.getContact(),
-									activity.getPixel(32)));
+					showAvatar = true;
+					loadAvatar(message,viewHolder.contact_picture,activity.getPixel(32));
+				} else if (message.getCounterpart() != null ){
+					showAvatar = true;
+					loadAvatar(message,viewHolder.contact_picture,activity.getPixel(32));
+				} else {
+					showAvatar = false;
+				}
+				if (showAvatar) {
 					viewHolder.contact_picture.setAlpha(0.5f);
+					viewHolder.contact_picture.setVisibility(View.VISIBLE);
+				} else {
+					viewHolder.contact_picture.setVisibility(View.GONE);
 				}
-				viewHolder.status_message.setText(message.getBody());
 			}
 			return view;
 		} else {
-			loadAvatar(message, viewHolder.contact_picture);
+			loadAvatar(message, viewHolder.contact_picture,activity.getPixel(48));
 		}
 
 		viewHolder.contact_picture
@@ -968,14 +977,16 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 	class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> {
 		private final WeakReference<ImageView> imageViewReference;
 		private Message message = null;
+		private final int size;
 
-		public BitmapWorkerTask(ImageView imageView) {
+		public BitmapWorkerTask(ImageView imageView, int size) {
 			imageViewReference = new WeakReference<>(imageView);
+			this.size = size;
 		}
 
 		@Override
 		protected Bitmap doInBackground(Message... params) {
-			return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled());
+			return activity.avatarService().get(params[0], size, isCancelled());
 		}
 
 		@Override
@@ -990,9 +1001,9 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 		}
 	}
 
-	public void loadAvatar(Message message, ImageView imageView) {
+	public void loadAvatar(Message message, ImageView imageView, int size) {
 		if (cancelPotentialWork(message, imageView)) {
-			final Bitmap bm = activity.avatarService().get(message, activity.getPixel(48), true);
+			final Bitmap bm = activity.avatarService().get(message, size, true);
 			if (bm != null) {
 				cancelPotentialWork(message, imageView);
 				imageView.setImageBitmap(bm);
@@ -1000,7 +1011,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 			} else {
 				imageView.setBackgroundColor(UIHelper.getColorForName(UIHelper.getMessageDisplayName(message)));
 				imageView.setImageDrawable(null);
-				final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+				final BitmapWorkerTask task = new BitmapWorkerTask(imageView, size);
 				final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
 				imageView.setImageDrawable(asyncDrawable);
 				try {

src/main/java/eu/siacs/conversations/utils/UIHelper.java πŸ”—

@@ -22,6 +22,7 @@ import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.ListItem;
 import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.entities.Presence;
 import eu.siacs.conversations.entities.Transferable;
 import eu.siacs.conversations.ui.XmppActivity;
@@ -251,7 +252,16 @@ public class UIHelper {
 
 	private static boolean isPositionFollowedByBigGrin(CharSequence body, int pos) {
 		return body.length() <= pos + 1
-				|| ((body.charAt(pos+1) == '<') && (body.length() == pos+2 || Character.isWhitespace(body.charAt(pos+2))));
+				|| ((body.charAt(pos + 1) == '<') && (body.length() == pos + 2 || Character.isWhitespace(body.charAt(pos + 2))));
+	}
+
+	public static String getDisplayName(MucOptions.User user) {
+		Contact contact = user.getContact();
+		if (contact != null) {
+			return contact.getDisplayName();
+		} else {
+			return user.getName();
+		}
 	}
 
 	public static String getFileDescriptionString(final Context context, final Message message) {

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

@@ -34,7 +34,9 @@
         android:id="@+id/status_message"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:minHeight="32dp"
         android:layout_centerVertical="true"
+        android:gravity="center_vertical"
         android:layout_marginLeft="8dp"
         android:layout_toEndOf="@+id/message_photo"
         android:layout_toRightOf="@+id/message_photo"

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

@@ -503,6 +503,8 @@
 	<string name="disable_account">Disable Account</string>
 	<string name="contact_is_typing">%s is typing…</string>
 	<string name="contact_has_stopped_typing">%s has stopped typing</string>
+	<string name="contacts_are_typing">%s are typing…</string>
+	<string name="contacts_have_stopped_typing">%s have stopped typing</string>
 	<string name="pref_chat_states">Typing notifications</string>
 	<string name="pref_chat_states_summary">Let your contacts know when you are writing messages to them</string>
 	<string name="send_location">Send location</string>