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.User;
35import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
36import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
37import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
38
39public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate {
40 public static final String ACTION_VIEW_MUC = "view_muc";
41 private Conversation mConversation;
42 private OnClickListener inviteListener = new OnClickListener() {
43
44 @Override
45 public void onClick(View v) {
46 inviteToConversation(mConversation);
47 }
48 };
49 private TextView mYourNick;
50 private ImageView mYourPhoto;
51 private ImageButton mEditNickButton;
52 private TextView mRoleAffiliaton;
53 private TextView mFullJid;
54 private TextView mAccountJid;
55 private LinearLayout membersView;
56 private LinearLayout mMoreDetails;
57 private Button mInviteButton;
58 private String uuid = null;
59 private List<User> users = new ArrayList<>();
60 private User mSelectedUser = null;
61
62 private UiCallback<Conversation> renameCallback = new UiCallback<Conversation>() {
63 @Override
64 public void success(Conversation object) {
65 runOnUiThread(new Runnable() {
66 @Override
67 public void run() {
68 Toast.makeText(ConferenceDetailsActivity.this,getString(R.string.your_nick_has_been_changed),Toast.LENGTH_SHORT).show();
69 populateView();
70 }
71 });
72
73 }
74
75 @Override
76 public void error(final int errorCode, Conversation object) {
77 runOnUiThread(new Runnable() {
78 @Override
79 public void run() {
80 Toast.makeText(ConferenceDetailsActivity.this,getString(errorCode),Toast.LENGTH_SHORT).show();
81 }
82 });
83 }
84
85 @Override
86 public void userInputRequried(PendingIntent pi, Conversation object) {
87
88 }
89 };
90
91 @Override
92 public void onConversationUpdate() {
93 runOnUiThread(new Runnable() {
94
95 @Override
96 public void run() {
97 populateView();
98 }
99 });
100 }
101
102 @Override
103 public void onMucRosterUpdate() {
104 runOnUiThread(new Runnable() {
105
106 @Override
107 public void run() {
108 populateView();
109 }
110 });
111 }
112
113 @Override
114 protected void onCreate(Bundle savedInstanceState) {
115 super.onCreate(savedInstanceState);
116 setContentView(R.layout.activity_muc_details);
117 mYourNick = (TextView) findViewById(R.id.muc_your_nick);
118 mYourPhoto = (ImageView) findViewById(R.id.your_photo);
119 mEditNickButton = (ImageButton) findViewById(R.id.edit_nick_button);
120 mFullJid = (TextView) findViewById(R.id.muc_jabberid);
121 membersView = (LinearLayout) findViewById(R.id.muc_members);
122 mAccountJid = (TextView) findViewById(R.id.details_account);
123 mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details);
124 mMoreDetails.setVisibility(View.GONE);
125 mInviteButton = (Button) findViewById(R.id.invite);
126 mInviteButton.setOnClickListener(inviteListener);
127 if (getActionBar() != null) {
128 getActionBar().setHomeButtonEnabled(true);
129 getActionBar().setDisplayHomeAsUpEnabled(true);
130 }
131 mEditNickButton.setOnClickListener(new OnClickListener() {
132
133 @Override
134 public void onClick(View v) {
135 quickEdit(mConversation.getMucOptions().getActualNick(),
136 new OnValueEdited() {
137
138 @Override
139 public void onValueEdited(String value) {
140 xmppConnectionService.renameInMuc(mConversation,value,renameCallback);
141 }
142 });
143 }
144 });
145 }
146
147 @Override
148 public boolean onOptionsItemSelected(MenuItem menuItem) {
149 switch (menuItem.getItemId()) {
150 case android.R.id.home:
151 finish();
152 break;
153 case R.id.action_edit_subject:
154 if (mConversation != null) {
155 quickEdit(mConversation.getName(), new OnValueEdited() {
156
157 @Override
158 public void onValueEdited(String value) {
159 MessagePacket packet = xmppConnectionService
160 .getMessageGenerator().conferenceSubject(
161 mConversation, value);
162 xmppConnectionService.sendMessagePacket(
163 mConversation.getAccount(), packet);
164 }
165 });
166 }
167 break;
168 case R.id.action_save_as_bookmark:
169 saveAsBookmark();
170 break;
171 case R.id.action_delete_bookmark:
172 deleteBookmark();
173 break;
174 }
175 return super.onOptionsItemSelected(menuItem);
176 }
177
178 public String getReadableRole(int role) {
179 switch (role) {
180 case User.ROLE_MODERATOR:
181 return getString(R.string.moderator);
182 case User.ROLE_PARTICIPANT:
183 return getString(R.string.participant);
184 case User.ROLE_VISITOR:
185 return getString(R.string.visitor);
186 default:
187 return "";
188 }
189 }
190
191 @Override
192 protected String getShareableUri() {
193 if (mConversation != null) {
194 return "xmpp:" + mConversation.getContactJid().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 Account account = mConversation.getAccount();
205 if (account.hasBookmarkFor(mConversation.getContactJid().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 this.mSelectedUser = user;
228 String name;
229 final Contact contact = user.getContact();
230 if (contact != null) {
231 name = contact.getDisplayName();
232 } else if (user.getJid() != null) {
233 name = user.getJid().toBareJid().toString();
234 } else {
235 name = user.getName();
236 }
237 menu.setHeaderTitle(name);
238 MenuItem startConversation = menu.findItem(R.id.start_conversation);
239 if (user.getJid() == null) {
240 startConversation.setVisible(false);
241 }
242 }
243 super.onCreateContextMenu(menu,v,menuInfo);
244 }
245
246 @Override
247 public boolean onContextItemSelected(MenuItem item) {
248 switch (item.getItemId()) {
249 case R.id.start_conversation:
250 startConversation(mSelectedUser);
251 return true;
252 default:
253 return super.onContextItemSelected(item);
254 }
255 }
256
257 protected void startConversation(User user) {
258 if (user.getJid() != null) {
259 Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid().toBareJid(),false);
260 switchToConversation(conversation);
261 }
262 }
263
264 protected void saveAsBookmark() {
265 Account account = mConversation.getAccount();
266 Bookmark bookmark = new Bookmark(account, mConversation.getContactJid().toBareJid());
267 if (!mConversation.getContactJid().isBareJid()) {
268 bookmark.setNick(mConversation.getContactJid().getResourcepart());
269 }
270 bookmark.setAutojoin(true);
271 account.getBookmarks().add(bookmark);
272 xmppConnectionService.pushBookmarks(account);
273 mConversation.setBookmark(bookmark);
274 }
275
276 protected void deleteBookmark() {
277 Account account = mConversation.getAccount();
278 Bookmark bookmark = mConversation.getBookmark();
279 bookmark.unregisterConversation();
280 account.getBookmarks().remove(bookmark);
281 xmppConnectionService.pushBookmarks(account);
282 }
283
284 @Override
285 void onBackendConnected() {
286 if (getIntent().getAction().equals(ACTION_VIEW_MUC)) {
287 this.uuid = getIntent().getExtras().getString("uuid");
288 }
289 if (uuid != null) {
290 this.mConversation = xmppConnectionService
291 .findConversationByUuid(uuid);
292 if (this.mConversation != null) {
293 populateView();
294 }
295 }
296 }
297
298 private void populateView() {
299 mAccountJid.setText(getString(R.string.using_account, mConversation
300 .getAccount().getJid().toBareJid()));
301 mYourPhoto.setImageBitmap(avatarService().get(
302 mConversation.getAccount(), getPixel(48)));
303 setTitle(mConversation.getName());
304 mFullJid.setText(mConversation.getContactJid().toBareJid().toString());
305 mYourNick.setText(mConversation.getMucOptions().getActualNick());
306 mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
307 if (mConversation.getMucOptions().online()) {
308 mMoreDetails.setVisibility(View.VISIBLE);
309 User self = mConversation.getMucOptions().getSelf();
310 switch (self.getAffiliation()) {
311 case User.AFFILIATION_ADMIN:
312 mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " ("
313 + getString(R.string.admin) + ")");
314 break;
315 case User.AFFILIATION_OWNER:
316 mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " ("
317 + getString(R.string.owner) + ")");
318 break;
319 default:
320 mRoleAffiliaton.setText(getReadableRole(self.getRole()));
321 break;
322 }
323 }
324 this.users.clear();
325 this.users.addAll(mConversation.getMucOptions().getUsers());
326 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
327 membersView.removeAllViews();
328 for (final User user : mConversation.getMucOptions().getUsers()) {
329 View view = inflater.inflate(R.layout.contact, membersView,
330 false);
331 this.setListItemBackgroundOnView(view);
332 view.setOnClickListener(new OnClickListener() {
333 @Override
334 public void onClick(View view) {
335 highlightInMuc(mConversation, user.getName());
336 }
337 });
338 registerForContextMenu(view);
339 view.setTag(user);
340 TextView name = (TextView) view
341 .findViewById(R.id.contact_display_name);
342 TextView key = (TextView) view.findViewById(R.id.key);
343 TextView role = (TextView) view.findViewById(R.id.contact_jid);
344 if (user.getPgpKeyId() != 0) {
345 key.setVisibility(View.VISIBLE);
346 key.setOnClickListener(new OnClickListener() {
347
348 @Override
349 public void onClick(View v) {
350 viewPgpKey(user);
351 }
352 });
353 key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
354 }
355 Bitmap bm;
356 Contact contact = user.getContact();
357 if (contact != null) {
358 bm = avatarService().get(contact, getPixel(48));
359 name.setText(contact.getDisplayName());
360 role.setText(user.getName() + " \u2022 "
361 + getReadableRole(user.getRole()));
362 } else {
363 bm = avatarService().get(user.getName(), getPixel(48));
364 name.setText(user.getName());
365 role.setText(getReadableRole(user.getRole()));
366 }
367 ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
368 iv.setImageBitmap(bm);
369 membersView.addView(view);
370 }
371 }
372
373 @SuppressWarnings("deprecation")
374 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
375 private void setListItemBackgroundOnView(View view) {
376 int sdk = android.os.Build.VERSION.SDK_INT;
377 if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
378 view.setBackgroundDrawable(getResources().getDrawable(R.drawable.greybackground));
379 } else {
380 view.setBackground(getResources().getDrawable(R.drawable.greybackground));
381 }
382 }
383
384 private void viewPgpKey(User user) {
385 PgpEngine pgp = xmppConnectionService.getPgpEngine();
386 if (pgp != null) {
387 PendingIntent intent = pgp.getIntentForKey(
388 mConversation.getAccount(), user.getPgpKeyId());
389 if (intent != null) {
390 try {
391 startIntentSenderForResult(intent.getIntentSender(), 0,
392 null, 0, 0, 0);
393 } catch (SendIntentException ignored) {
394
395 }
396 }
397 }
398 }
399}