View Javadoc
1   /*
2    * Copyright (C) 2003-2014 eXo Platform SAS.
3    *
4    * This is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as
6    * published by the Free Software Foundation; either version 3 of
7    * the License, or (at your option) any later version.
8    *
9    * This software is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this software; if not, write to the Free
16   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   */
19  package org.exoplatform.ui.social;
20  
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.IOException;
24  
25  import com.squareup.picasso.Picasso;
26  
27  import org.exoplatform.R;
28  import org.exoplatform.controller.social.ComposeMessageController;
29  import org.exoplatform.model.SocialSpaceInfo;
30  import org.exoplatform.utils.ExoConstants;
31  import org.exoplatform.utils.ExoDocumentUtils;
32  import org.exoplatform.utils.Log;
33  import org.exoplatform.utils.PhotoUtils;
34  import org.exoplatform.utils.SettingUtils;
35  import org.exoplatform.widget.AddPhotoDialog;
36  import org.exoplatform.widget.PostWaitingDialog;
37  import org.exoplatform.widget.RectangleImageView;
38  import org.exoplatform.widget.RemoveAttachedPhotoDialog;
39  import android.annotation.SuppressLint;
40  import android.app.Activity;
41  import android.content.Context;
42  import android.content.Intent;
43  import android.content.pm.PackageManager;
44  import android.content.res.Resources;
45  import android.graphics.Bitmap;
46  import android.graphics.BitmapFactory;
47  import android.net.Uri;
48  import android.os.Bundle;
49  import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback;
50  import android.view.Menu;
51  import android.view.MenuItem;
52  import android.view.MotionEvent;
53  import android.view.View;
54  import android.view.View.OnClickListener;
55  import android.view.View.OnLongClickListener;
56  import android.view.inputmethod.InputMethodManager;
57  import android.widget.Button;
58  import android.widget.EditText;
59  import android.widget.ImageView;
60  import android.widget.LinearLayout;
61  import android.widget.LinearLayout.LayoutParams;
62  import android.widget.ScrollView;
63  import android.widget.TextView;
64  import android.widget.Toast;
65  
66  public class ComposeMessageActivity extends Activity implements View.OnClickListener, OnRequestPermissionsResultCallback {
67  
68    private PostWaitingDialog            _progressDialog;
69  
70    private int                          composeType             = -1;
71  
72    private EditText                     composeEditText;
73  
74    private ScrollView                   textFieldScrollView;
75  
76    private LinearLayout                 fileAttachWrap;
77  
78    private TextView                     postDestinationView;
79  
80    private ImageView                    postDestinationIcon;
81  
82    private Button                       sendButton;
83  
84    private Button                       cancelButton;
85  
86    private String                       composeMessage;
87  
88    private String                       comment;
89  
90    private String                       statusUpdate;
91  
92    private String                       cancelText;
93  
94    private String                       sendText;
95  
96    private ComposeMessageController     messageController;
97  
98    public static ComposeMessageActivity composeMessageActivity;
99  
100   private String                       sdcard_temp_dir         = null;
101 
102   private int                          currentPosition         = -1;
103 
104   private static final String          TAG                     = "eXo____ComposeMessageActivity____";
105 
106   private static final int             SELECT_POST_DESTINATION = 10;
107   
108   private final String KEY_COMPOSE_TYPE                        = "COMPOSE_TYPE";
109   
110   private final String KEY_CURRENT_POSITION                    = "CURRENT_POSITION";
111   
112   private final String KEY_TEMP_IMAGE                          = "TEMP_IMAGE";
113 
114   @Override
115   public void onCreate(Bundle savedInstanceState) {
116     super.onCreate(savedInstanceState);
117     setContentView(R.layout.compose_message_layout);
118     changeLanguage();
119     initLayout();
120     composeMessageActivity = this;
121     if (savedInstanceState != null) {
122       composeType = savedInstanceState.getInt(KEY_COMPOSE_TYPE);
123       currentPosition = savedInstanceState.getInt(KEY_CURRENT_POSITION);
124       String tmpImage = savedInstanceState.getString(KEY_TEMP_IMAGE, null);
125       if (tmpImage != null) {
126         addImageToMessage(new File(tmpImage));
127       }
128     } else {
129       composeType = getIntent().getIntExtra(ExoConstants.COMPOSE_TYPE, composeType);
130       if (composeType == ExoConstants.COMPOSE_COMMENT_TYPE) {
131         currentPosition = getIntent().getIntExtra(ExoConstants.ACTIVITY_CURRENT_POSITION, currentPosition);
132       }
133     }
134     setActivityTitle(composeType);
135     messageController = new ComposeMessageController(this, composeType, _progressDialog);
136     if (composeType == ExoConstants.COMPOSE_COMMENT_TYPE) {
137       ((LinearLayout) postDestinationView.getParent()).setVisibility(View.GONE);
138     }
139   }
140   
141   @Override
142   protected void onSaveInstanceState(Bundle outState) {
143     outState.putInt(KEY_COMPOSE_TYPE, composeType);
144     outState.putInt(KEY_CURRENT_POSITION, currentPosition);
145     outState.putString(KEY_TEMP_IMAGE, sdcard_temp_dir);
146     super.onSaveInstanceState(outState);
147   }
148   
149   @Override
150   protected void onDestroy() {
151     composeMessageActivity = null;
152     super.onDestroy();
153   }
154 
155   private void initLayout() {
156     postDestinationView = (TextView) findViewById(R.id.post_destination_text_view);
157     postDestinationIcon = (ImageView) findViewById(R.id.post_destination_image);
158     composeEditText = (EditText) findViewById(R.id.compose_text_view);
159     textFieldScrollView = (ScrollView) findViewById(R.id.compose_textfield_scroll);
160     textFieldScrollView.setOnTouchListener(new View.OnTouchListener() {
161       @Override
162       public boolean onTouch(View v, MotionEvent event) {
163         if (event.getAction() == MotionEvent.ACTION_DOWN) {
164           InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
165           mgr.showSoftInput(composeEditText, InputMethodManager.RESULT_UNCHANGED_SHOWN);
166         }
167         return false;
168       }
169     });
170 
171     fileAttachWrap = (LinearLayout) findViewById(R.id.compose_attach_file_wrap);
172     sendButton = (Button) findViewById(R.id.compose_send_button);
173     sendButton.setText(sendText);
174     sendButton.setOnClickListener(this);
175     cancelButton = (Button) findViewById(R.id.compose_cancel_button);
176     cancelButton.setText(cancelText);
177     cancelButton.setOnClickListener(this);
178   }
179   
180   private void setActivityTitle(int compType) {
181     if (compType == ExoConstants.COMPOSE_POST_TYPE) {
182       setTitle(statusUpdate);
183     } else {
184       setTitle(comment);
185     }
186   }
187 
188   @Override
189   public boolean onCreateOptionsMenu(Menu menu) {
190     getMenuInflater().inflate(R.menu.composer, menu);
191     return true;
192   }
193 
194   @Override
195   public boolean onPrepareOptionsMenu(Menu menu) {
196     MenuItem attach = menu.findItem(R.id.menu_compose_attach);
197     if (attach != null) {
198       if (composeType == ExoConstants.COMPOSE_POST_TYPE) {
199         // show the attach photo menu item
200         attach.setVisible(true);
201       } else if (composeType == ExoConstants.COMPOSE_COMMENT_TYPE) {
202         // hide the attach photo menu item
203         attach.setVisible(false);
204       }
205     }
206     return true;
207   }
208 
209   @Override
210   public boolean onOptionsItemSelected(MenuItem item) {
211     switch (item.getItemId()) {
212     case R.id.menu_compose_attach:
213       new AddPhotoDialog(this, messageController).show();
214       break;
215     }
216     return true;
217   }
218   
219 
220   @SuppressLint("Override")
221   @Override
222   public void onRequestPermissionsResult(int reqCode, String[] permissions, int[] results) {
223     if (results.length > 0
224         && results[0] == PackageManager.PERMISSION_GRANTED) {  
225         // permission granted
226       switch (reqCode) {
227       case ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA:
228         messageController.initCamera();
229         break;
230       case ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY:
231         PhotoUtils.pickPhotoForActivity(this);
232         break;
233       default:
234         break;
235       }
236     } else {
237         // permission denied
238       if (ExoDocumentUtils.shouldDisplayExplanation(this, ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY) ||
239           ExoDocumentUtils.shouldDisplayExplanation(this, ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA) ) {
240         PhotoUtils.alertNeedStoragePermission(this);
241       } else {
242         Toast.makeText(this, R.string.PermissionStorageDeniedToast, Toast.LENGTH_LONG).show();
243       }
244     }
245     return;
246   }
247 
248   public void onActivityResult(int requestCode, int resultCode, Intent intent) {
249     super.onActivityResult(requestCode, resultCode, intent);
250     if (resultCode == RESULT_OK) {
251       switch (requestCode) {
252       // Add image after capturing photo from camera
253       case ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA:
254         String sdcard_dir = messageController.getSdCardTempDir();
255         File file = new File(sdcard_dir);
256         addImageToMessage(file);
257         break;
258 
259       // Get the pick image action result from native photo album and send
260       // it to SelectedImageActivity class
261       case ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY:
262         Intent intent2 = new Intent(this, SelectedImageActivity.class);
263         Uri uri = intent.getData();
264         intent.putExtra(ExoConstants.SELECTED_IMAGE_MODE, 2);
265         intent2.setData(uri);
266         if (intent.getExtras() != null) {
267           intent2.putExtras(intent.getExtras());
268         }
269 
270         startActivity(intent2);
271         break;
272 
273       // Get the destination of the post from the SpaceSelectorActivity
274       case SELECT_POST_DESTINATION:
275         SocialSpaceInfo space = intent.getParcelableExtra(SpaceSelectorActivity.SELECTED_SPACE);
276 
277         if (space != null) {
278           messageController.setPostDestination(space);
279           postDestinationView.setText(space.displayName);
280           Picasso.with(this).load(space.avatarUrl).placeholder(R.drawable.icon_space_default).into(postDestinationIcon);
281         } else {
282           messageController.setPostDestination(null);
283           postDestinationView.setText(R.string.Public);
284           Picasso.with(this).load(R.drawable.icon_post_public).into(postDestinationIcon);
285         }
286         break;
287       }
288     } else {
289       // TODO handle failure of startActivityForResult
290     }
291     /*
292      * Set default language to our application setting language
293      */
294     SettingUtils.setDefaultLanguage(this);
295   }
296 
297   public static void addImageToMessage(File file) {
298     try {
299       final String filePath = file.getAbsolutePath();
300       composeMessageActivity.sdcard_temp_dir = filePath;
301       BitmapFactory.Options options = new BitmapFactory.Options();
302       options.inSampleSize = 4;
303       options.inPurgeable = true;
304       options.inInputShareable = true;
305       FileInputStream fis = new FileInputStream(file);
306       Bitmap bitmap = BitmapFactory.decodeStream(fis, null, options);
307       fis.close();
308       bitmap = PhotoUtils.resizeImageBitmap(composeMessageActivity, bitmap);
309       bitmap = ExoDocumentUtils.rotateBitmapToNormal(filePath, bitmap);
310 
311       RectangleImageView image = new RectangleImageView(composeMessageActivity);
312       image.setPadding(1, 1, 1, 1);
313       image.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
314       image.setImageBitmap(bitmap);
315       image.setOnClickListener(new OnClickListener() {
316 
317         public void onClick(View v) {
318           Intent intent = new Intent(composeMessageActivity, SelectedImageActivity.class);
319           intent.putExtra(ExoConstants.SELECTED_IMAGE_MODE, 1);
320           intent.putExtra(ExoConstants.SELECTED_IMAGE_EXTRA, filePath);
321           composeMessageActivity.startActivity(intent);
322         }
323       });
324       image.setOnLongClickListener(new OnLongClickListener() {
325 
326         @Override
327         public boolean onLongClick(View v) {
328           new RemoveAttachedPhotoDialog(composeMessageActivity).show();
329           return true;
330         }
331       });
332       LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
333       composeMessageActivity.fileAttachWrap.removeAllViews();
334       composeMessageActivity.fileAttachWrap.addView(image, params);
335     } catch (IOException e) {
336       if (Log.LOGD)
337         Log.e(TAG, "Error when adding image to message", e);
338     }
339   }
340 
341   public static void removeImageFromMessage() {
342     if (composeMessageActivity != null) {
343       composeMessageActivity.fileAttachWrap.removeAllViews();
344       composeMessageActivity.sdcard_temp_dir = null;
345     }
346   }
347 
348   @Override
349   public void finish() {
350     if (_progressDialog != null) {
351       _progressDialog.dismiss();
352     }
353     super.finish();
354   }
355 
356   @Override
357   public void onBackPressed() {
358     finish();
359   }
360 
361   @Override
362   public void onClick(View view) {
363 
364     if (view.equals(sendButton)) {
365       composeMessage = composeEditText.getText().toString();
366       messageController.onSendMessage(composeMessage, sdcard_temp_dir, currentPosition);
367     }
368     if (view.equals(cancelButton)) {
369       finish();
370     }
371   }
372 
373   public void openSpaceSelectionActivity(View v) {
374     // Open the Space Selector Activity and expect a result
375     Intent selectSpace = new Intent(this, SpaceSelectorActivity.class);
376     startActivityForResult(selectSpace, SELECT_POST_DESTINATION);
377   }
378 
379   private void changeLanguage() {
380     Resources resource = getResources();
381     comment = resource.getString(R.string.Comment);
382     statusUpdate = resource.getString(R.string.StatusUpdate);
383     sendText = resource.getString(R.string.Send);
384     cancelText = resource.getString(R.string.Cancel);
385   }
386 }