ConferenceDetailsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.annotation.TargetApi;
  4import android.app.PendingIntent;
  5import android.content.Context;
  6import android.content.IntentSender.SendIntentException;
  7import android.graphics.Bitmap;
  8import android.os.Build;
  9import android.os.Bundle;
 10import android.view.ContextMenu;
 11import android.view.LayoutInflater;
 12import android.view.Menu;
 13import android.view.MenuItem;
 14import android.view.View;
 15import android.view.View.OnClickListener;
 16import android.widget.Button;
 17import android.widget.ImageButton;
 18import android.widget.ImageView;
 19import android.widget.LinearLayout;
 20import android.widget.TextView;
 21import android.widget.Toast;
 22
 23import org.openintents.openpgp.util.OpenPgpUtils;
 24
 25import java.util.ArrayList;
 26import java.util.List;
 27
 28import eu.siacs.conversations.R;
 29import eu.siacs.conversations.crypto.PgpEngine;
 30import eu.siacs.conversations.entities.Account;
 31import eu.siacs.conversations.entities.Bookmark;
 32import eu.siacs.conversations.entities.Contact;
 33import eu.siacs.conversations.entities.Conversation;
 34import eu.siacs.conversations.entities.MucOptions;
 35import eu.siacs.conversations.entities.MucOptions.User;
 36import eu.siacs.conversations.services.XmppConnectionService;
 37import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
 38import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
 39import eu.siacs.conversations.xmpp.jid.Jid;
 40import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 41
 42public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged {
 43	public static final String ACTION_VIEW_MUC = "view_muc";
 44	private Conversation mConversation;
 45	private OnClickListener inviteListener = new OnClickListener() {
 46
 47		@Override
 48		public void onClick(View v) {
 49			inviteToConversation(mConversation);
 50		}
 51	};
 52	private TextView mYourNick;
 53	private ImageView mYourPhoto;
 54	private ImageButton mEditNickButton;
 55	private TextView mRoleAffiliaton;
 56	private TextView mFullJid;
 57	private TextView mAccountJid;
 58	private LinearLayout membersView;
 59	private LinearLayout mMoreDetails;
 60	private Button mInviteButton;
 61	private String uuid = null;
 62	private List<User> users = new ArrayList<>();
 63	private User mSelectedUser = null;
 64
 65	private boolean mAdvancedMode = false;
 66
 67	private UiCallback<Conversation> renameCallback = new UiCallback<Conversation>() {
 68		@Override
 69		public void success(Conversation object) {
 70			runOnUiThread(new Runnable() {
 71				@Override
 72				public void run() {
 73					Toast.makeText(ConferenceDetailsActivity.this,getString(R.string.your_nick_has_been_changed),Toast.LENGTH_SHORT).show();
 74					updateView();
 75				}
 76			});
 77
 78		}
 79
 80		@Override
 81		public void error(final int errorCode, Conversation object) {
 82			runOnUiThread(new Runnable() {
 83				@Override
 84				public void run() {
 85					Toast.makeText(ConferenceDetailsActivity.this,getString(errorCode),Toast.LENGTH_SHORT).show();
 86				}
 87			});
 88		}
 89
 90		@Override
 91		public void userInputRequried(PendingIntent pi, Conversation object) {
 92
 93		}
 94	};
 95
 96	@Override
 97	public void onConversationUpdate() {
 98		runOnUiThread(new Runnable() {
 99
100			@Override
101			public void run() {
102				updateView();
103			}
104		});
105	}
106
107	@Override
108	public void onMucRosterUpdate() {
109		runOnUiThread(new Runnable() {
110
111			@Override
112			public void run() {
113				updateView();
114			}
115		});
116	}
117
118	@Override
119	protected void onCreate(Bundle savedInstanceState) {
120		super.onCreate(savedInstanceState);
121		setContentView(R.layout.activity_muc_details);
122		mYourNick = (TextView) findViewById(R.id.muc_your_nick);
123		mYourPhoto = (ImageView) findViewById(R.id.your_photo);
124		mEditNickButton = (ImageButton) findViewById(R.id.edit_nick_button);
125		mFullJid = (TextView) findViewById(R.id.muc_jabberid);
126		membersView = (LinearLayout) findViewById(R.id.muc_members);
127		mAccountJid = (TextView) findViewById(R.id.details_account);
128		mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details);
129		mMoreDetails.setVisibility(View.GONE);
130		mInviteButton = (Button) findViewById(R.id.invite);
131		mInviteButton.setOnClickListener(inviteListener);
132		if (getActionBar() != null) {
133			getActionBar().setHomeButtonEnabled(true);
134			getActionBar().setDisplayHomeAsUpEnabled(true);
135		}
136		mEditNickButton.setOnClickListener(new OnClickListener() {
137
138			@Override
139			public void onClick(View v) {
140				quickEdit(mConversation.getMucOptions().getActualNick(),
141						new OnValueEdited() {
142
143							@Override
144							public void onValueEdited(String value) {
145								xmppConnectionService.renameInMuc(mConversation,value,renameCallback);
146							}
147						});
148			}
149		});
150	}
151
152	@Override
153	public boolean onOptionsItemSelected(MenuItem menuItem) {
154		switch (menuItem.getItemId()) {
155			case android.R.id.home:
156				finish();
157				break;
158			case R.id.action_edit_subject:
159				if (mConversation != null) {
160					quickEdit(mConversation.getName(), new OnValueEdited() {
161
162						@Override
163						public void onValueEdited(String value) {
164							MessagePacket packet = xmppConnectionService
165								.getMessageGenerator().conferenceSubject(
166										mConversation, value);
167							xmppConnectionService.sendMessagePacket(
168									mConversation.getAccount(), packet);
169						}
170					});
171				}
172				break;
173			case R.id.action_save_as_bookmark:
174				saveAsBookmark();
175				break;
176			case R.id.action_delete_bookmark:
177				deleteBookmark();
178				break;
179			case R.id.action_advanced_mode:
180				this.mAdvancedMode = !menuItem.isChecked();
181				menuItem.setChecked(this.mAdvancedMode);
182				invalidateOptionsMenu();
183				updateView();
184				break;
185		}
186		return super.onOptionsItemSelected(menuItem);
187	}
188
189	@Override
190	protected String getShareableUri() {
191		if (mConversation != null) {
192			return "xmpp:" + mConversation.getJid().toBareJid().toString() + "?join";
193		} else {
194			return "";
195		}
196	}
197
198	@Override
199	public boolean onPrepareOptionsMenu(Menu menu) {
200		MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark);
201		MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark);
202		MenuItem menuItemAdvancedMode = menu.findItem(R.id.action_advanced_mode);
203		menuItemAdvancedMode.setChecked(mAdvancedMode);
204		Account account = mConversation.getAccount();
205		if (account.hasBookmarkFor(mConversation.getJid().toBareJid())) {
206			menuItemSaveBookmark.setVisible(false);
207			menuItemDeleteBookmark.setVisible(true);
208		} else {
209			menuItemDeleteBookmark.setVisible(false);
210			menuItemSaveBookmark.setVisible(true);
211		}
212		return true;
213	}
214
215	@Override
216	public boolean onCreateOptionsMenu(Menu menu) {
217		getMenuInflater().inflate(R.menu.muc_details, menu);
218		return true;
219	}
220
221	@Override
222	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
223		Object tag = v.getTag();
224		if (tag instanceof User) {
225			getMenuInflater().inflate(R.menu.muc_details_context,menu);
226			final User user = (User) tag;
227			final User self = mConversation.getMucOptions().getSelf();
228			this.mSelectedUser = user;
229			String name;
230			if (user.getJid() != null) {
231				final Contact contact = user.getContact();
232				if (contact != null) {
233					name = contact.getDisplayName();
234				} else if (user.getJid() != null) {
235					name = user.getJid().toBareJid().toString();
236				} else {
237					name = user.getName();
238				}
239				menu.setHeaderTitle(name);
240				MenuItem startConversation = menu.findItem(R.id.start_conversation);
241				MenuItem giveMembership = menu.findItem(R.id.give_membership);
242				MenuItem removeMembership = menu.findItem(R.id.remove_membership);
243				MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges);
244				MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges);
245				MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room);
246				startConversation.setVisible(true);
247				if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) &&
248						self.getAffiliation().outranks(user.getAffiliation())) {
249					if (mAdvancedMode) {
250						if (user.getAffiliation() == MucOptions.Affiliation.NONE) {
251							giveMembership.setVisible(true);
252						} else {
253							removeMembership.setVisible(true);
254						}
255					}
256					if (user.getAffiliation() != MucOptions.Affiliation.ADMIN) {
257						giveAdminPrivileges.setVisible(true);
258					} else {
259						removeAdminPrivileges.setVisible(true);
260					}
261					removeFromRoom.setVisible(true);
262				}
263			}
264
265		}
266		super.onCreateContextMenu(menu,v,menuInfo);
267	}
268
269	@Override
270	public boolean onContextItemSelected(MenuItem item) {
271		switch (item.getItemId()) {
272			case R.id.start_conversation:
273				startConversation(mSelectedUser);
274				return true;
275			case R.id.give_admin_privileges:
276				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.ADMIN,this);
277				return true;
278			case R.id.give_membership:
279				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
280				return true;
281			case R.id.remove_membership:
282				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.NONE,this);
283				return true;
284			case R.id.remove_admin_privileges:
285				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
286				return true;
287			case R.id.remove_from_room:
288				xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this);
289				return true;
290			default:
291				return super.onContextItemSelected(item);
292		}
293	}
294
295	protected void startConversation(User user) {
296		if (user.getJid() != null) {
297			Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid().toBareJid(),false);
298			switchToConversation(conversation);
299		}
300	}
301
302	protected void saveAsBookmark() {
303		Account account = mConversation.getAccount();
304		Bookmark bookmark = new Bookmark(account, mConversation.getJid().toBareJid());
305		if (!mConversation.getJid().isBareJid()) {
306			bookmark.setNick(mConversation.getJid().getResourcepart());
307		}
308		bookmark.setAutojoin(true);
309		account.getBookmarks().add(bookmark);
310		xmppConnectionService.pushBookmarks(account);
311		mConversation.setBookmark(bookmark);
312	}
313
314	protected void deleteBookmark() {
315		Account account = mConversation.getAccount();
316		Bookmark bookmark = mConversation.getBookmark();
317		bookmark.unregisterConversation();
318		account.getBookmarks().remove(bookmark);
319		xmppConnectionService.pushBookmarks(account);
320	}
321
322	@Override
323	void onBackendConnected() {
324		if (getIntent().getAction().equals(ACTION_VIEW_MUC)) {
325			this.uuid = getIntent().getExtras().getString("uuid");
326		}
327		if (uuid != null) {
328			this.mConversation = xmppConnectionService
329				.findConversationByUuid(uuid);
330			if (this.mConversation != null) {
331				updateView();
332			}
333		}
334	}
335
336	private void updateView() {
337		mAccountJid.setText(getString(R.string.using_account, mConversation
338					.getAccount().getJid().toBareJid()));
339		mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48)));
340		setTitle(mConversation.getName());
341		mFullJid.setText(mConversation.getJid().toBareJid().toString());
342		mYourNick.setText(mConversation.getMucOptions().getActualNick());
343		mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
344		if (mConversation.getMucOptions().online()) {
345			mMoreDetails.setVisibility(View.VISIBLE);
346			User self = mConversation.getMucOptions().getSelf();
347			final String status = getStatus(self);
348			if (status != null) {
349				mRoleAffiliaton.setVisibility(View.VISIBLE);
350				mRoleAffiliaton.setText(status);
351			} else {
352				mRoleAffiliaton.setVisibility(View.GONE);
353			}
354		}
355		this.users.clear();
356		this.users.addAll(mConversation.getMucOptions().getUsers());
357		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
358		membersView.removeAllViews();
359		for (final User user : mConversation.getMucOptions().getUsers()) {
360			View view = inflater.inflate(R.layout.contact, membersView,
361					false);
362			this.setListItemBackgroundOnView(view);
363			view.setOnClickListener(new OnClickListener() {
364				@Override
365				public void onClick(View view) {
366					highlightInMuc(mConversation, user.getName());
367				}
368			});
369			registerForContextMenu(view);
370			view.setTag(user);
371			TextView tvDisplayName = (TextView) view.findViewById(R.id.contact_display_name);
372			TextView tvKey = (TextView) view.findViewById(R.id.key);
373			TextView tvStatus = (TextView) view.findViewById(R.id.contact_jid);
374			if (mAdvancedMode && user.getPgpKeyId() != 0) {
375				tvKey.setVisibility(View.VISIBLE);
376				tvKey.setOnClickListener(new OnClickListener() {
377
378					@Override
379					public void onClick(View v) {
380						viewPgpKey(user);
381					}
382				});
383				tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
384			}
385			Bitmap bm;
386			Contact contact = user.getContact();
387			if (contact != null) {
388				bm = avatarService().get(contact, getPixel(48));
389				tvDisplayName.setText(contact.getDisplayName());
390				tvStatus.setText(user.getName() + " \u2022 " + getStatus(user));
391			} else {
392				bm = avatarService().get(user.getName(), getPixel(48));
393				tvDisplayName.setText(user.getName());
394				tvStatus.setText(getStatus(user));
395
396			}
397			ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
398			iv.setImageBitmap(bm);
399			membersView.addView(view);
400		}
401	}
402
403	private String getStatus(User user) {
404		if (mAdvancedMode) {
405			StringBuilder builder = new StringBuilder();
406			builder.append(getString(user.getAffiliation().getResId()));
407			builder.append(" (");
408			builder.append(getString(user.getRole().getResId()));
409			builder.append(')');
410			return builder.toString();
411		} else {
412			return getString(user.getAffiliation().getResId());
413		}
414	}
415
416	@SuppressWarnings("deprecation")
417	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
418	private void setListItemBackgroundOnView(View view) {
419		int sdk = android.os.Build.VERSION.SDK_INT;
420		if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
421			view.setBackgroundDrawable(getResources().getDrawable(R.drawable.greybackground));
422		} else {
423			view.setBackground(getResources().getDrawable(R.drawable.greybackground));
424		}
425	}
426
427	private void viewPgpKey(User user) {
428		PgpEngine pgp = xmppConnectionService.getPgpEngine();
429		if (pgp != null) {
430			PendingIntent intent = pgp.getIntentForKey(
431					mConversation.getAccount(), user.getPgpKeyId());
432			if (intent != null) {
433				try {
434					startIntentSenderForResult(intent.getIntentSender(), 0,
435							null, 0, 0, 0);
436				} catch (SendIntentException ignored) {
437
438				}
439			}
440		}
441	}
442
443	@Override
444	public void onAffiliationChangedSuccessful(Jid jid) {
445
446	}
447
448	@Override
449	public void onAffiliationChangeFailed(Jid jid, int resId) {
450
451	}
452}