1package de.gultsch.chat.ui;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.List;
7
8import de.gultsch.chat.R;
9import de.gultsch.chat.R.id;
10import de.gultsch.chat.entities.Contact;
11import de.gultsch.chat.entities.Conversation;
12import de.gultsch.chat.entities.Message;
13import de.gultsch.chat.utils.UIHelper;
14import android.net.Uri;
15import android.os.Bundle;
16import android.app.FragmentTransaction;
17import android.app.NotificationManager;
18import android.content.Context;
19import android.content.Intent;
20import android.graphics.Typeface;
21import android.support.v4.widget.SlidingPaneLayout;
22import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
23import android.util.Log;
24import android.view.KeyEvent;
25import android.view.LayoutInflater;
26import android.view.Menu;
27import android.view.MenuItem;
28import android.view.View;
29import android.view.ViewGroup;
30import android.view.inputmethod.InputMethodManager;
31import android.widget.AdapterView;
32import android.widget.AdapterView.OnItemClickListener;
33import android.widget.ArrayAdapter;
34import android.widget.ListView;
35import android.widget.TextView;
36import android.widget.ImageView;
37
38public class ConversationActivity extends XmppActivity {
39
40 public static final String VIEW_CONVERSATION = "viewConversation";
41 public static final String CONVERSATION = "conversationUuid";
42
43 public static final int INSERT_CONTACT = 0x9889;
44
45 protected SlidingPaneLayout spl;
46
47 private List<Conversation> conversationList = new ArrayList<Conversation>();
48 private Conversation selectedConversation = null;
49 private ListView listView;
50
51 private boolean paneShouldBeOpen = true;
52 private ArrayAdapter<Conversation> listAdapter;
53
54 private OnConversationListChangedListener onConvChanged = new OnConversationListChangedListener() {
55
56 @Override
57 public void onConversationListChanged() {
58 final Conversation currentConv = getSelectedConversation();
59 conversationList.clear();
60 conversationList.addAll(xmppConnectionService
61 .getConversations());
62 runOnUiThread(new Runnable() {
63
64 @Override
65 public void run() {
66 updateConversationList();
67 /*for(int i = 0; i < conversationList.size(); ++i) {
68 if (currentConv == conversationList.get(i)) {
69 selectedConversation = conversationList.get(i);
70 break;
71 }
72 }*/
73 if(paneShouldBeOpen) {
74 selectedConversation = conversationList.get(0);
75 if (conversationList.size() >= 1) {
76 swapConversationFragment();
77 } else {
78 startActivity(new Intent(getApplicationContext(), NewConversationActivity.class));
79 finish();
80 }
81 }
82 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation");
83 if (selectedFragment!=null) {
84 selectedFragment.updateMessages();
85 }
86 }
87 });
88 }
89 };
90 private boolean contactInserted = false;
91
92
93 public List<Conversation> getConversationList() {
94 return this.conversationList;
95 }
96
97 public Conversation getSelectedConversation() {
98 return this.selectedConversation;
99 }
100
101 public ListView getConversationListView() {
102 return this.listView;
103 }
104
105 public SlidingPaneLayout getSlidingPaneLayout() {
106 return this.spl;
107 }
108
109 public boolean shouldPaneBeOpen() {
110 return paneShouldBeOpen;
111 }
112
113 public void updateConversationList() {
114 if (conversationList.size() >= 1) {
115 Collections.sort(this.conversationList, new Comparator<Conversation>() {
116 @Override
117 public int compare(Conversation lhs, Conversation rhs) {
118 return (int) (rhs.getLatestMessage().getTimeSent() - lhs.getLatestMessage().getTimeSent());
119 }
120 });
121 }
122 this.listView.invalidateViews();
123 }
124
125 @Override
126 protected void onCreate(Bundle savedInstanceState) {
127
128 super.onCreate(savedInstanceState);
129
130 setContentView(R.layout.fragment_conversations_overview);
131
132 listView = (ListView) findViewById(R.id.list);
133
134 this.listAdapter = new ArrayAdapter<Conversation>(this,
135 R.layout.conversation_list_row, conversationList) {
136 @Override
137 public View getView(int position, View view, ViewGroup parent) {
138 if (view == null) {
139 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
140 view = (View) inflater.inflate(
141 R.layout.conversation_list_row, null);
142 }
143 Conversation conv = getItem(position);
144 TextView convName = (TextView) view.findViewById(R.id.conversation_name);
145 convName.setText(conv.getName());
146 TextView convLastMsg = (TextView) view.findViewById(R.id.conversation_lastmsg);
147 convLastMsg.setText(conv.getLatestMessage().getBody());
148
149 if(!conv.isRead()) {
150 convName.setTypeface(null,Typeface.BOLD);
151 convLastMsg.setTypeface(null,Typeface.BOLD);
152 } else {
153 convName.setTypeface(null,Typeface.NORMAL);
154 convLastMsg.setTypeface(null,Typeface.NORMAL);
155 }
156
157 ((TextView) view.findViewById(R.id.conversation_lastupdate))
158 .setText(UIHelper.readableTimeDifference(getItem(position).getLatestMessage().getTimeSent()));
159
160 Uri profilePhoto = getItem(position).getProfilePhotoUri();
161 ImageView imageView = (ImageView) view.findViewById(R.id.conversation_image);
162 if (profilePhoto!=null) {
163 imageView.setImageURI(profilePhoto);
164 } else {
165 imageView.setImageBitmap(UIHelper.getUnknownContactPicture(getItem(position).getName(),200));
166 }
167
168
169 ((ImageView) view.findViewById(R.id.conversation_image))
170 .setImageURI(getItem(position).getProfilePhotoUri());
171 return view;
172 }
173
174 };
175
176 listView.setAdapter(this.listAdapter);
177
178 listView.setOnItemClickListener(new OnItemClickListener() {
179
180 @Override
181 public void onItemClick(AdapterView<?> arg0, View clickedView,
182 int position, long arg3) {
183 paneShouldBeOpen = false;
184 if (selectedConversation != conversationList.get(position)) {
185 selectedConversation = conversationList.get(position);
186 swapConversationFragment(); //.onBackendConnected(conversationList.get(position));
187 } else {
188 spl.closePane();
189 }
190 }
191 });
192 spl = (SlidingPaneLayout) findViewById(id.slidingpanelayout);
193 spl.setParallaxDistance(150);
194 spl.setShadowResource(R.drawable.es_slidingpane_shadow);
195 spl.setSliderFadeColor(0);
196 spl.setPanelSlideListener(new PanelSlideListener() {
197
198 @Override
199 public void onPanelOpened(View arg0) {
200 paneShouldBeOpen = true;
201 getActionBar().setDisplayHomeAsUpEnabled(false);
202 getActionBar().setTitle(R.string.app_name);
203 invalidateOptionsMenu();
204
205 InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
206
207 View focus = getCurrentFocus();
208
209 if (focus != null) {
210
211 inputManager.hideSoftInputFromWindow(
212 focus.getWindowToken(),
213 InputMethodManager.HIDE_NOT_ALWAYS);
214 }
215 }
216
217 @Override
218 public void onPanelClosed(View arg0) {
219 paneShouldBeOpen = false;
220 if (conversationList.size() > 0) {
221 getActionBar().setDisplayHomeAsUpEnabled(true);
222 getActionBar().setTitle(getSelectedConversation().getName());
223 invalidateOptionsMenu();
224 if (!getSelectedConversation().isRead()) {
225 getSelectedConversation().markRead();
226 updateConversationList();
227 }
228 }
229 }
230
231 @Override
232 public void onPanelSlide(View arg0, float arg1) {
233 // TODO Auto-generated method stub
234
235 }
236 });
237 }
238
239 @Override
240 public boolean onCreateOptionsMenu(Menu menu) {
241 getMenuInflater().inflate(R.menu.conversations, menu);
242 MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security);
243
244 if (spl.isOpen()) {
245 ((MenuItem) menu.findItem(R.id.action_archive)).setVisible(false);
246 ((MenuItem) menu.findItem(R.id.action_details)).setVisible(false);
247 menuSecure.setVisible(false);
248 } else {
249 ((MenuItem) menu.findItem(R.id.action_add)).setVisible(false);
250 if (this.getSelectedConversation()!=null) {
251 if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
252 ((MenuItem) menu.findItem(R.id.action_security)).setVisible(false);
253 menuSecure.setVisible(false);
254 ((MenuItem) menu.findItem(R.id.action_archive)).setTitle("Leave conference");
255 } else {
256 if (this.getSelectedConversation().getLatestMessage().getEncryption() != Message.ENCRYPTION_NONE) {
257 menuSecure.setIcon(R.drawable.ic_action_secure);
258 }
259 }
260 }
261 }
262 return true;
263 }
264
265 @Override
266 public boolean onOptionsItemSelected(MenuItem item) {
267 switch (item.getItemId()) {
268 case android.R.id.home:
269 spl.openPane();
270 break;
271 case R.id.action_settings:
272 startActivity(new Intent(this, SettingsActivity.class));
273 break;
274 case R.id.action_accounts:
275 startActivity(new Intent(this, ManageAccountActivity.class));
276 break;
277 case R.id.action_add:
278 startActivity(new Intent(this, NewConversationActivity.class));
279 break;
280 case R.id.action_archive:
281 Conversation conv = getSelectedConversation();
282 conv.setStatus(Conversation.STATUS_ARCHIVED);
283 paneShouldBeOpen = true;
284 spl.openPane();
285 xmppConnectionService.archiveConversation(conv);
286 selectedConversation = conversationList.get(0);
287 break;
288 case R.id.action_details:
289 DialogContactDetails details = new DialogContactDetails();
290 Contact contact = this.getSelectedConversation().getContact();
291 if (contact != null) {
292 contact.setAccount(this.selectedConversation.getAccount());
293 details.setContact(contact);
294 details.show(getFragmentManager(), "details");
295 } else {
296 Log.d("xmppService","contact was null - means not in roster");
297 }
298 break;
299 default:
300 break;
301 }
302 return super.onOptionsItemSelected(item);
303 }
304
305 protected ConversationFragment swapConversationFragment() {
306 ConversationFragment selectedFragment = new ConversationFragment();
307
308 FragmentTransaction transaction = getFragmentManager()
309 .beginTransaction();
310 transaction.replace(R.id.selected_conversation, selectedFragment,"conversation");
311 transaction.commit();
312 return selectedFragment;
313 }
314
315 @Override
316 public boolean onKeyDown(int keyCode, KeyEvent event) {
317 if (keyCode == KeyEvent.KEYCODE_BACK) {
318 if (!spl.isOpen()) {
319 spl.openPane();
320 return false;
321 }
322 }
323 return super.onKeyDown(keyCode, event);
324 }
325
326 public void onStart() {
327 super.onStart();
328 NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
329 nm.cancelAll();
330 if (conversationList.size()>=1) {
331 onConvChanged.onConversationListChanged();
332 }
333 }
334
335 @Override
336 protected void onStop() {
337 Log.d("gultsch","called on stop in conversation activity");
338 if (xmppConnectionServiceBound) {
339 xmppConnectionService.removeOnConversationListChangedListener();
340 }
341 super.onStop();
342 }
343
344 @Override
345 void onBackendConnected() {
346
347
348 if (contactInserted) {
349 Log.d("xmppService","merge phone contacts with roster");
350 contactInserted = false;
351 xmppConnectionService.mergePhoneContactsWithRoster();
352 }
353
354 xmppConnectionService.setOnConversationListChangedListener(this.onConvChanged);
355
356 if (conversationList.size()==0) {
357 conversationList.clear();
358 conversationList.addAll(xmppConnectionService
359 .getConversations());
360
361 this.updateConversationList();
362 }
363
364 if ((getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) {
365 if (getIntent().getType().equals(
366 ConversationActivity.VIEW_CONVERSATION)) {
367 handledViewIntent = true;
368
369 String convToView = (String) getIntent().getExtras().get(CONVERSATION);
370
371 for(int i = 0; i < conversationList.size(); ++i) {
372 if (conversationList.get(i).getUuid().equals(convToView)) {
373 selectedConversation = conversationList.get(i);
374 }
375 }
376 paneShouldBeOpen = false;
377 swapConversationFragment();
378 }
379 } else {
380 if (xmppConnectionService.getAccounts().size() == 0) {
381 startActivity(new Intent(this, ManageAccountActivity.class));
382 finish();
383 } else if (conversationList.size() <= 0) {
384 //add no history
385 startActivity(new Intent(this, NewConversationActivity.class));
386 finish();
387 } else {
388 spl.openPane();
389 //find currently loaded fragment
390 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation");
391 if (selectedFragment!=null) {
392 Log.d("gultsch","ConversationActivity. found old fragment.");
393 selectedFragment.onBackendConnected();
394 } else {
395 Log.d("gultsch","conversationactivity. no old fragment found. creating new one");
396 selectedConversation = conversationList.get(0);
397 Log.d("gultsch","selected conversation is #"+selectedConversation);
398 swapConversationFragment();
399 }
400 }
401 }
402 }
403
404 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
405 if (requestCode==INSERT_CONTACT) {
406 Log.d("xmppService","contact inserted");
407 this.contactInserted = true;
408 }
409 }
410}