ConversationActivity.java

  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}