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