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