ConferenceDetailsActivity.java

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