Skip to content
Snippets Groups Projects
Commit 3fa4fd18 authored by John Carlson's avatar John Carlson
Browse files

Basic attach activity (no style)

parent e1ab26ac
No related branches found
No related tags found
No related merge requests found
Pipeline #
Loading
Loading
@@ -129,6 +129,7 @@ dependencies {
compile ('com.vdurmont:emoji-java:3.1.3') {
exclude group: 'org.json', module: 'json'
}
compile 'com.github.jkwiecien:EasyImage:1.2.3'
 
normalCompile('com.crashlytics.sdk.android:crashlytics:2.6.2@aar') {
transitive = true;
Loading
Loading
Loading
Loading
@@ -73,6 +73,8 @@
<activity android:name=".activity.PickBranchOrTagActivity"
android:theme="@style/Activity.Translucent"/>
<activity android:name=".activity.WebviewLoginActivity" />
<activity android:name=".activity.AttachActivity"
android:theme="@style/Activity.Translucent"/>
<activity
android:name=".activity.RoutingActivity"
android:launchMode="singleTask"
Loading
Loading
package com.commit451.gitlab.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.commit451.easycallback.EasyCallback;
import com.commit451.gitlab.App;
import com.commit451.gitlab.R;
import com.commit451.gitlab.model.api.FileUploadResponse;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.util.FileUtil;
import org.parceler.Parcels;
import java.io.File;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.MultipartBody;
import pl.aprilapps.easyphotopicker.DefaultCallback;
import pl.aprilapps.easyphotopicker.EasyImage;
import timber.log.Timber;
/**
* Attaches files
*/
public class AttachActivity extends BaseActivity {
public static final String KEY_FILE_UPLOAD_RESPONSE = "response";
private static final String KEY_PROJECT = "project";
public static Intent newIntent(Context context, Project project) {
Intent intent = new Intent(context, AttachActivity.class);
intent.putExtra(KEY_PROJECT, Parcels.wrap(project));
return intent;
}
private Project mProject;
@OnClick(R.id.button_choose_photo)
void onChoosePhotoClicked() {
EasyImage.openGallery(this, 0);
}
@OnClick(R.id.button_take_photo)
void onTakePhotoClicked() {
EasyImage.openCamera(this, 0);
}
@OnClick(R.id.button_choose_file)
void onChooseFileClicked() {
EasyImage.openChooserWithDocuments(this, "Choose file", 0);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_attach);
ButterKnife.bind(this);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(KEY_PROJECT));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
EasyImage.handleActivityResult(requestCode, resultCode, data, this, new DefaultCallback() {
@Override
public void onImagePickerError(Exception e, EasyImage.ImageSource source, int type) {
//Some error handling
}
@Override
public void onImagePicked(File imageFile, EasyImage.ImageSource source, int type) {
//Handle the image
onPhotoReturned(imageFile);
}
@Override
public void onCanceled(EasyImage.ImageSource source, int type) {
//Cancel handling, you might wanna remove taken photo if it was canceled
if (source == EasyImage.ImageSource.CAMERA) {
File photoFile = EasyImage.lastlyTakenButCanceledPhoto(AttachActivity.this);
if (photoFile != null) {
photoFile.delete();
}
}
}
});
}
private void onPhotoReturned(File photo) {
MultipartBody.Part part = FileUtil.toPart(photo);
App.instance().getGitLab().uploadFile(mProject.getId(), part).enqueue(new EasyCallback<FileUploadResponse>() {
@Override
public void success(@NonNull FileUploadResponse response) {
Intent data = new Intent();
data.putExtra(KEY_FILE_UPLOAD_RESPONSE, Parcels.wrap(response));
setResult(RESULT_OK, data);
finish();
}
@Override
public void failure(Throwable t) {
Timber.e(t);
finish();
}
});
}
}
Loading
Loading
@@ -27,7 +27,6 @@ import com.commit451.gitlab.model.api.Issue;
import com.commit451.gitlab.model.api.Note;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.navigation.Navigator;
import com.commit451.gitlab.util.FileUtil;
import com.commit451.gitlab.util.IntentUtil;
import com.commit451.gitlab.util.PaginationUtil;
import com.commit451.gitlab.view.SendMessageView;
Loading
Loading
@@ -41,7 +40,6 @@ import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.MultipartBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
Loading
Loading
@@ -58,7 +56,7 @@ public class IssueActivity extends BaseActivity {
private static final String EXTRA_PROJECT_NAME = "project_name";
private static final String EXTRA_ISSUE_IID = "extra_issue_iid";
 
private static final int REQUEST_IMAGE = 1;
private static final int REQUEST_ATTACH = 1;
 
public static Intent newIntent(Context context, Project project, Issue issue) {
Intent intent = new Intent(context, IssueActivity.class);
Loading
Loading
@@ -256,8 +254,7 @@ public class IssueActivity extends BaseActivity {
private Callback<FileUploadResponse> mUploadImageCallback = new EasyCallback<FileUploadResponse>() {
@Override
public void success(@NonNull FileUploadResponse response) {
mProgress.setVisibility(View.GONE);
mSendMessageView.appendText(response.getMarkdown());
}
 
@Override
Loading
Loading
@@ -323,7 +320,7 @@ public class IssueActivity extends BaseActivity {
 
@Override
public void onAttachmentClicked() {
Navigator.navigateToChoosePhoto(IssueActivity.this, REQUEST_IMAGE);
Navigator.navigateToAttach(IssueActivity.this, mProject, REQUEST_ATTACH);
}
});
 
Loading
Loading
@@ -362,12 +359,14 @@ public class IssueActivity extends BaseActivity {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_IMAGE:
//Not checking result code because apps are dumb and don't use it
Uri selectedImage = data.getData();
if (selectedImage != null) {
MultipartBody.Part part = FileUtil.toPart(IssueActivity.this, selectedImage);
App.instance().getGitLab().uploadFile(mProject.getId(), part).enqueue(mUploadImageCallback);
case REQUEST_ATTACH:
if (resultCode == RESULT_OK) {
FileUploadResponse response = Parcels.unwrap(data.getParcelableExtra(AttachActivity.KEY_FILE_UPLOAD_RESPONSE));
mProgress.setVisibility(View.GONE);
mSendMessageView.appendText(response.getMarkdown());
} else {
Snackbar.make(mRoot, R.string.failed_to_upload_file, Snackbar.LENGTH_LONG)
.show();
}
break;
}
Loading
Loading
Loading
Loading
@@ -20,12 +20,11 @@ import com.commit451.gitlab.event.MergeRequestChangedEvent;
import com.commit451.gitlab.model.api.MergeRequest;
import com.commit451.gitlab.model.api.Note;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.navigation.Navigator;
import com.commit451.gitlab.util.PaginationUtil;
import com.commit451.gitlab.view.SendMessageView;
import com.commit451.teleprinter.Teleprinter;
import org.greenrobot.eventbus.Subscribe;
 
import org.greenrobot.eventbus.Subscribe;
import org.parceler.Parcels;
 
import java.util.List;
Loading
Loading
@@ -192,7 +191,7 @@ public class MergeRequestDiscussionFragment extends ButterKnifeFragment {
 
@Override
public void onAttachmentClicked() {
Navigator.navigateToAttach(getActivity());
//TODO
}
});
 
Loading
Loading
Loading
Loading
@@ -13,13 +13,13 @@ import org.parceler.Parcel;
public class FileUploadResponse {
 
@JsonField(name = "alt")
protected String mAlt;
String mAlt;
@JsonField(name = "url")
protected String mUrl;
String mUrl;
@JsonField(name = "is_image")
protected boolean mIsImage;
boolean mIsImage;
@JsonField(name = "markdown")
protected String mMarkdown;
String mMarkdown;
 
protected FileUploadResponse() {
//for json
Loading
Loading
Loading
Loading
@@ -18,6 +18,7 @@ import com.commit451.gitlab.activity.AddLabelActivity;
import com.commit451.gitlab.activity.AddMilestoneActivity;
import com.commit451.gitlab.activity.AddNewLabelActivity;
import com.commit451.gitlab.activity.AddUserActivity;
import com.commit451.gitlab.activity.AttachActivity;
import com.commit451.gitlab.activity.BuildActivity;
import com.commit451.gitlab.activity.DiffActivity;
import com.commit451.gitlab.activity.FileActivity;
Loading
Loading
@@ -230,14 +231,9 @@ public class Navigator {
activity.startActivity(intent);
}
 
public static void navigateToAttach(Activity activity) {
//TODO
}
public static void navigateToChoosePhoto(Activity activity, int requestCode) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
activity.startActivityForResult(photoPickerIntent, requestCode);
public static void navigateToAttach(Activity activity, Project project, int requestCode) {
Intent intent = AttachActivity.newIntent(activity, project);
activity.startActivityForResult(intent, requestCode);
}
 
private static void startMorphActivity(Activity activity, View fab, Intent intent) {
Loading
Loading
Loading
Loading
@@ -9,6 +9,7 @@ import android.provider.MediaStore;
import android.provider.OpenableColumns;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
 
import okhttp3.MediaType;
Loading
Loading
@@ -33,6 +34,11 @@ public class FileUtil {
return null;
}
 
public static MultipartBody.Part toPart(File file) {
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
return MultipartBody.Part.createFormData("file", file.getName(), requestBody);
}
public static MultipartBody.Part toPart(Bitmap bitmap, String name) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
Loading
Loading
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
style="@style/Card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:padding="16dp"
android:clickable="true"
android:layout_gravity="bottom"
android:background="@color/window_background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/button_take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
app:srcCompat="@drawable/ic_camera_24dp"
android:background="?attr/selectableItemBackgroundBorderless"/>
<ImageView
android:id="@+id/button_choose_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
app:srcCompat="@drawable/ic_gallery_24dp"
android:background="?attr/selectableItemBackgroundBorderless"/>
<ImageView
android:id="@+id/button_choose_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
app:srcCompat="@drawable/ic_file_24dp"
android:background="?attr/selectableItemBackgroundBorderless"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
\ No newline at end of file
Loading
Loading
@@ -160,6 +160,7 @@
<string name="failed_to_create_issue">Failed to create or modify issue</string>
<string name="discard">Discard</string>
<string name="are_you_sure_you_want_to_discard">Are you sure you want to discard?</string>
<string name="failed_to_upload_file">Failed to upload file</string>
 
<!-- Project -->
<string name="no_readme_found">No README found for project</string>
Loading
Loading
  • username-removed-167252 @aleksandar-stefanovic ·

    Just out of curiosity - why did you use a separate Activity for achieving this? Why didn't you use an Fragment (typical use case, since it's not occupying the whole screen) - or nothing at all (the code could have been implemented in the already existing Activity, and then it could have maybe extended some functionality into some other class)? Using a whole activity to display what is essentially a dialog or a menu seems redundant. I'm not saying that what's done is wrong, I'm just wondering why.

  • Hey @aleksandar-stefanovic I tend to use Activities over Fragments wherever possible due to the fact that I find fragments pretty limiting. With an activity, you can usually achieve more custom animations and transitions. I also made it it's own activity so that both the Merge Request and Issue activities could use it easily and it would "just work" without having to potentially duplicate code in both activities. It probably could be achieved also with a BottomSheetDialogFragment or something similar, but when using an Activity, we could easily refactor it to look like a dialog, a full screen activity, or whatever else without having to do much work.

  • username-removed-167252 @aleksandar-stefanovic ·

    Okay, I understand... can I submit a merge request that adds a library to the project? I've added a circular reveal animation to the "attachment" CardView that pops up, but I had to add this lib for compat reasons (API 14 vs API 21 in stock). Or, I could keep it >=API 21 alternatively... This circular reveal animation can be also used elsewhere in the project, it's simple to implement... video: https://www.youtube.com/watch?v=SCdNjPxnlOM

    Edited by username-removed-167252
  • Nice! That looks really good! Yeah, I would love to see a Merge Request for this!

  • username-removed-167252 @aleksandar-stefanovic ·

    Thanks! Coming right up!

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment