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