diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/PostsHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/PostsHelper.java index 190b198..012afb5 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/PostsHelper.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/PostsHelper.java @@ -3,6 +3,8 @@ package org.communiquons.android.comunic.client.data.helpers; import android.content.Context; import android.support.annotation.Nullable; +import org.communiquons.android.comunic.client.data.models.APIFileRequest; +import org.communiquons.android.comunic.client.data.models.APIPostFile; import org.communiquons.android.comunic.client.data.models.APIRequest; import org.communiquons.android.comunic.client.data.models.APIResponse; import org.communiquons.android.comunic.client.data.models.CreatePost; @@ -146,15 +148,26 @@ public class PostsHelper { public int create(CreatePost post){ //Prepare the request on the server - APIRequest params = new APIRequest(mContext, "posts/create"); + APIFileRequest req = new APIFileRequest(mContext, "posts/create"); //Put basic information about the post - params.addString("content", post.getContent()); + req.addString("content", post.getContent()); //Determine the kind of post switch (post.getType()){ case TEXT: - params.addString("kind", "text"); + req.addString("kind", "text"); + break; + + case IMAGE: + req.addString("kind", "image"); + + //Process image and add it to the request + APIPostFile file = new APIPostFile(); + file.setFileName("image.png"); + file.setBitmap(post.getNewImage()); + file.setFieldName("image"); + req.addFile(file); break; default: @@ -166,15 +179,15 @@ public class PostsHelper { switch (post.getVisibilityLevel()){ case PUBLIC: - params.addString("visibility", "public"); + req.addString("visibility", "public"); break; case FRIENDS: - params.addString("visibility", "friends"); + req.addString("visibility", "friends"); break; case PRIVATE: - params.addString("visibility", "private"); + req.addString("visibility", "private"); break; default: @@ -185,7 +198,7 @@ public class PostsHelper { switch (post.getPage_type()){ case USER_PAGE: - params.addString("kind-page", "user"); + req.addString("kind-page", "user"); break; default: @@ -193,13 +206,17 @@ public class PostsHelper { } //Set the ID of the target page - params.addInt("kind-id", post.getPage_id()); + req.addInt("kind-id", post.getPage_id()); //Perform the request on the server try { - //Perform the request - APIResponse response = new APIRequestHelper().exec(params); + //Perform the request (upload a file if required) + APIResponse response; + if(req.containsFiles()) + response = new APIRequestHelper().execPostFile(req); + else + response = new APIRequestHelper().exec(req); //Check for errors if(response.getResponse_code() != 200) diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/models/APIFileRequest.java b/app/src/main/java/org/communiquons/android/comunic/client/data/models/APIFileRequest.java index fda131b..c20ebd5 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/models/APIFileRequest.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/models/APIFileRequest.java @@ -48,4 +48,13 @@ public class APIFileRequest extends APIRequest { public ArrayList getFiles() { return files; } + + /** + * Check whether a request includes a file or not + * + * @return TRUE if at least one file is present in the request / FALSE elses + */ + public boolean containsFiles(){ + return files.size() > 0; + } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/models/CreatePost.java b/app/src/main/java/org/communiquons/android/comunic/client/data/models/CreatePost.java index 305ab1e..e18c95a 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/models/CreatePost.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/models/CreatePost.java @@ -1,5 +1,7 @@ package org.communiquons.android.comunic.client.data.models; +import android.graphics.Bitmap; + /** * This object extends the Post object in order to include all the required informations to * create a new post @@ -10,6 +12,20 @@ package org.communiquons.android.comunic.client.data.models; public class CreatePost extends Post { + //Private fields + private Bitmap newImage; + //Get and set new image + public void setNewImage(Bitmap newImage) { + this.newImage = newImage; + } + + public Bitmap getNewImage() { + return newImage; + } + + public boolean hasNewImage(){ + return newImage != null; + } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/PostsCreateFormFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/PostsCreateFormFragment.java index ed01b31..c1491a7 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/PostsCreateFormFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/PostsCreateFormFragment.java @@ -1,6 +1,10 @@ package org.communiquons.android.comunic.client.ui.fragments; +import android.app.AlertDialog; import android.app.Fragment; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; @@ -9,15 +13,22 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; +import android.widget.ImageButton; import android.widget.Toast; import org.communiquons.android.comunic.client.R; -import org.communiquons.android.comunic.client.data.models.CreatePost; import org.communiquons.android.comunic.client.data.enums.PageType; -import org.communiquons.android.comunic.client.data.models.Post; import org.communiquons.android.comunic.client.data.enums.PostTypes; import org.communiquons.android.comunic.client.data.enums.PostVisibilityLevels; import org.communiquons.android.comunic.client.data.helpers.PostsHelper; +import org.communiquons.android.comunic.client.data.models.CreatePost; +import org.communiquons.android.comunic.client.data.models.Post; +import org.communiquons.android.comunic.client.ui.utils.BitmapUtils; +import org.communiquons.android.comunic.client.ui.utils.UiUtils; + +import java.io.FileNotFoundException; + +import static android.app.Activity.RESULT_OK; /** * Posts creation form @@ -38,6 +49,11 @@ public class PostsCreateFormFragment extends Fragment { */ public static final String PAGE_TYPE_ARG = "PAGE_TYPE"; + /** + * Intent : request to pick a picture + */ + public static final int PICK_PHOTO = 2; + /** * Page type : user page */ @@ -53,6 +69,11 @@ public class PostsCreateFormFragment extends Fragment { */ private PostsHelper mPostHelper; + /** + * Select image button + */ + private ImageButton mPickImageButton; + /** * Submit form button */ @@ -63,6 +84,11 @@ public class PostsCreateFormFragment extends Fragment { */ private EditText mPostContent; + /** + * User picked bitmap to include with the post + */ + private Bitmap mNewPicture; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -85,6 +111,21 @@ public class PostsCreateFormFragment extends Fragment { //Get post text area mPostContent = view.findViewById(R.id.new_post_content); + //Get choose image button and makes it lives + mPickImageButton = view.findViewById(R.id.select_image_button); + mPickImageButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + choosePicture(); + } + }); + mPickImageButton.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + cancelPictureSelectionDialog(); + return true; + } + }); + //Get send button and makes it lives mSendButton = view.findViewById(R.id.submit_create_post_form); mSendButton.setOnClickListener(new View.OnClickListener() { @@ -95,6 +136,100 @@ public class PostsCreateFormFragment extends Fragment { }); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + switch (requestCode){ + + case PICK_PHOTO: + pick_picture_callback(resultCode, data); + break; + + } + } + + /** + * Offer the user to choose a picture to add to his post + */ + private void choosePicture() { + + //Make an intent + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("image/*"); + startActivityForResult(photoPickerIntent, PICK_PHOTO); + + } + + /** + * Callback called when a picture has been selected + * + * @param resultCode The result of the operation + * @param data Data to process + */ + private void pick_picture_callback(int resultCode, Intent data){ + + if(resultCode == RESULT_OK){ + + try { + + //Get bitmap + Bitmap bitmap = BitmapUtils.IntentResultToBitmap(getActivity(), data); + + //Check for errors + if(bitmap == null) + return; + + //Apply bitmap + mPickImageButton.setImageBitmap(bitmap); + mNewPicture = bitmap; + + } catch (FileNotFoundException e) { + e.printStackTrace(); + cancelPictureSelectionDialog(); + } + + } + + } + + /** + * Offer the user to cancel his choice of picture + */ + private void cancelPictureSelectionDialog(){ + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.conversation_message_remove_image_popup_title) + .setMessage(R.string.conversation_message_remove_image_popup_message) + .setNegativeButton(R.string.conversation_message_remove_image_popup_cancel, null) + + .setPositiveButton(R.string.conversation_message_remove_image_popup_confirm, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + removeChosenPicture(); + } + }) + + .show(); + } + + /** + * Remove the picture chosen by the user + */ + private void removeChosenPicture(){ + + //Free memory + if(mNewPicture != null) + mNewPicture.recycle(); + mNewPicture = null; + + //Reset image button + mPickImageButton.setImageBitmap(null); + mPickImageButton.setImageDrawable(UiUtils.getDrawable(getActivity(), + android.R.drawable.ic_menu_gallery)); + + } + /** * Set the on post created class to trigger when an event occur * @@ -109,12 +244,6 @@ public class PostsCreateFormFragment extends Fragment { */ private void submit_form(){ - //Check if the content of the post is empty / too short - if(mPostContent.getText().length() < 5){ - Toast.makeText(getActivity(), R.string.err_post_content_too_short, - Toast.LENGTH_SHORT).show(); - return; - } //Create a post object and fill it with the required information CreatePost post = new CreatePost(); @@ -129,10 +258,31 @@ public class PostsCreateFormFragment extends Fragment { //Set post content post.setContent(""+mPostContent.getText()); - //Default value, will be updated in a new version + //Default values post.setType(PostTypes.TEXT); post.setVisibilityLevel(PostVisibilityLevels.FRIENDS); + //Check if the post contains an image + if(mNewPicture != null){ + post.setType(PostTypes.IMAGE); + post.setNewImage(mNewPicture); + } + + + //Other post types will be added in new versions + + //Perform post checks + //If the post is a text + if(post.getType() == PostTypes.TEXT){ + + //Check if the content of the post is empty / too short + if(mPostContent.getText().length() < 5){ + Toast.makeText(getActivity(), R.string.err_post_content_too_short, + Toast.LENGTH_SHORT).show(); + return; + } + } + //Try to create post mSendButton.setEnabled(false); new AsyncTask(){ diff --git a/app/src/main/res/layout/post_create_form.xml b/app/src/main/res/layout/post_create_form.xml index 0c8886d..b42fec3 100644 --- a/app/src/main/res/layout/post_create_form.xml +++ b/app/src/main/res/layout/post_create_form.xml @@ -13,11 +13,34 @@ android:lines="3" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small" /> - -