package com.kenny.openimgur.activities;
import android.Manifest;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.transition.Transition;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.kenny.openimgur.R;
import com.kenny.openimgur.classes.ImgurBaseObject;
import com.kenny.openimgur.classes.ImgurPhoto;
import com.kenny.openimgur.util.FileUtil;
import com.kenny.openimgur.util.ImageUtil;
import com.kenny.openimgur.util.LogUtil;
import com.kenny.openimgur.util.PermissionUtils;
import com.kenny.openimgur.util.RequestCodes;
import com.kenny.openimgur.util.ViewUtils;
import com.kennyc.bottomsheet.BottomSheet;
import com.kennyc.bottomsheet.BottomSheetListener;
import com.kennyc.view.MultiStateView;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import java.io.File;
import java.lang.ref.WeakReference;
import butterknife.BindView;
import butterknife.OnClick;
/**
* Created by Kenny-PC on 3/8/2015.
*/
public class MemeActivity extends BaseActivity {
private static final String KEY_OBJECT = "imgur_object";
private static final String KEY_FILE_PATH = "file_path";
@BindView(R.id.image)
ImageView mImage;
@BindView(R.id.topText)
TextView mTopText;
@BindView(R.id.bottomText)
TextView mBottomText;
@BindView(R.id.content)
View mView;
@BindView(R.id.multiView)
MultiStateView mMultiStateView;
private ImgurBaseObject mObject;
public static Intent createIntent(Context context, ImgurBaseObject object) {
return new Intent(context, MemeActivity.class).putExtra(KEY_OBJECT, object);
}
public static Intent createIntent(Context context, @NonNull File file) {
return new Intent(context, MemeActivity.class).putExtra(KEY_FILE_PATH, file.getAbsolutePath());
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meme_create);
Intent intent = getIntent();
boolean hasTransition;
if (intent == null) {
LogUtil.w(TAG, "No object was found in the intent");
finish();
return;
}
if (intent.hasExtra(KEY_OBJECT)) {
mObject = intent.getParcelableExtra(KEY_OBJECT);
hasTransition = isApiLevel(Build.VERSION_CODES.LOLLIPOP) && savedInstanceState == null;
} else {
String path = intent.getStringExtra(KEY_FILE_PATH);
mObject = new ImgurBaseObject("-1", null, "file:///" + path);
// Locally imported images will not have an activity transition
hasTransition = false;
}
getSupportActionBar().setTitle(mObject.getTitle());
loadImage(hasTransition);
mView.setDrawingCacheEnabled(true);
if (hasTransition) {
getWindow().getEnterTransition().addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
// NOOP
}
@Override
public void onTransitionEnd(Transition transition) {
mTopText.setVisibility(View.VISIBLE);
mBottomText.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(mTopText, "alpha", 0.0f, 1.0f).setDuration(200).start();
ObjectAnimator.ofFloat(mBottomText, "alpha", 0.0f, 1.0f).setDuration(200).start();
getWindow().getEnterTransition().removeListener(this);
}
@Override
public void onTransitionCancel(Transition transition) {
// NOOP
}
@Override
public void onTransitionPause(Transition transition) {
// NOOP
}
@Override
public void onTransitionResume(Transition transition) {
// NOOP
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.meme, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
int level = PermissionUtils.getPermissionLevel(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
switch (level) {
case PermissionUtils.PERMISSION_AVAILABLE:
mMultiStateView.setViewState(MultiStateView.VIEW_STATE_LOADING);
// Clear any memory cache before we save to avoid an OOM
ImageUtil.getImageLoader(this).clearMemoryCache();
new SaveMemeTask().execute(this);
break;
case PermissionUtils.PERMISSION_NEVER_ASKED:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RequestCodes.REQUEST_PERMISSION_WRITE);
break;
case PermissionUtils.PERMISSION_DENIED:
new AlertDialog.Builder(this, app.getImgurTheme().getAlertDialogTheme())
.setTitle(R.string.permission_title)
.setMessage(R.string.permission_rational_meme)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MemeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RequestCodes.REQUEST_PERMISSION_WRITE);
}
}).show();
break;
}
return true;
case R.id.fontSize:
new AlertDialog.Builder(this, theme.getAlertDialogTheme())
.setTitle(R.string.meme_font_size)
.setItems(R.array.meme_font_sizes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
float textSize;
switch (which) {
case 0:
// Small
textSize = getResources().getDimensionPixelSize(R.dimen.meme_text_small);
break;
case 1:
// Medium
textSize = getResources().getDimensionPixelSize(R.dimen.meme_text_medium);
break;
case 2:
// Large
textSize = getResources().getDimensionPixelSize(R.dimen.meme_text_large);
break;
case 3:
// X Large
textSize = getResources().getDimensionPixelSize(R.dimen.meme_text_xlarge);
break;
default:
LogUtil.v(TAG, "Unable to determine text size selected, defaulting to medium");
textSize = getResources().getDimensionPixelSize(R.dimen.meme_text_medium);
break;
}
mTopText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
mBottomText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
}).show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void loadImage(boolean hasTransition) {
if (hasTransition) {
mTopText.setVisibility(View.GONE);
mBottomText.setVisibility(View.GONE);
ActivityCompat.postponeEnterTransition(this);
}
ImageUtil.getImageLoader(this).displayImage(mObject.getLink(), mImage, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
mMultiStateView.setViewState(MultiStateView.VIEW_STATE_CONTENT);
ActivityCompat.startPostponedEnterTransition(MemeActivity.this);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
super.onLoadingFailed(imageUri, view, failReason);
finish();
// Toast error message
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
super.onLoadingCancelled(imageUri, view);
finish();
}
@Override
public void onLoadingStarted(String imageUri, View view) {
super.onLoadingStarted(imageUri, view);
mMultiStateView.setViewState(MultiStateView.VIEW_STATE_LOADING);
}
});
}
void onMemeCreated(@Nullable final File file) {
mMultiStateView.setViewState(MultiStateView.VIEW_STATE_CONTENT);
dismissDialogFragment("saving");
if (FileUtil.isFileValid(file)) {
final Uri fileUri = Uri.fromFile(file);
FileUtil.scanFile(fileUri, getApplicationContext());
new BottomSheet.Builder(this)
.setSheet(R.menu.meme_saved)
.setStyle(theme.getBottomSheetTheme())
.setTitle(R.string.meme_success)
.setListener(new BottomSheetListener() {
@Override
public void onSheetShown(BottomSheet bottomSheet) {
// NOOP
}
@Override
public void onSheetItemSelected(BottomSheet bottomSheet, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.share:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType(ImgurPhoto.IMAGE_TYPE_JPEG);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
startActivity(shareIntent);
break;
case R.id.upload:
startActivity(UploadActivity.createIntent(getApplicationContext(), file));
break;
}
}
@Override
public void onSheetDismissed(BottomSheet bottomSheet, @DismissEvent int dismissEvent) {
finish();
}
})
.show();
} else {
Snackbar.make(mMultiStateView, R.string.meme_failed, Snackbar.LENGTH_LONG).show();
}
}
@OnClick({R.id.topText, R.id.bottomText})
public void onClick(final View view) {
new AlertDialog.Builder(this, theme.getAlertDialogTheme())
.setTitle(R.string.meme_input_title)
.setView(R.layout.meme_caption)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AlertDialog ad = (AlertDialog) dialog;
EditText editText = (EditText) ad.findViewById(R.id.memeCaption);
String text = editText.getText().toString();
if (view == mBottomText) {
mBottomText.setText(text);
} else if (view == mTopText) {
mTopText.setText(text);
}
}
}).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
ViewUtils.fixTransitionLeak(this);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case RequestCodes.REQUEST_PERMISSION_WRITE:
boolean hasPermission = PermissionUtils.verifyPermissions(grantResults);
if (hasPermission) {
mMultiStateView.setViewState(MultiStateView.VIEW_STATE_LOADING);
// Clear any memory cache before we save to avoid an OOM
ImageUtil.getImageLoader(this).clearMemoryCache();
new SaveMemeTask().execute(this);
} else {
Snackbar.make(mMultiStateView, R.string.permission_denied, Snackbar.LENGTH_LONG).show();
}
break;
}
}
@Override
protected int getStyleRes() {
return theme.isDarkTheme ? R.style.Theme_Opengur_Dark : R.style.Theme_Opengur_Light_DarkActionBar;
}
static class SaveMemeTask extends AsyncTask<MemeActivity, Void, File> {
private static final String TAG = "SaveMemeTask";
WeakReference<MemeActivity> mActivity;
@Override
protected File doInBackground(MemeActivity... params) {
if (params == null || params.length <= 0) {
throw new IllegalArgumentException("No Activity passed to save bitmap");
}
mActivity = new WeakReference<>(params[0]);
Bitmap drawingCache = mActivity.get().mView.getDrawingCache();
try {
if (drawingCache != null) {
File file = ImageUtil.saveBitmap(drawingCache);
if (FileUtil.isFileValid(file)) {
LogUtil.v(TAG, "Meme saved successfully");
return file;
}
}
} catch (Exception ex) {
LogUtil.e(TAG, "Error saving Meme bitmap", ex);
} finally {
if (drawingCache != null) drawingCache.recycle();
}
LogUtil.v(TAG, "Unable to save Meme");
return null;
}
@Override
protected void onPostExecute(File result) {
MemeActivity activity = mActivity.get();
if (activity != null) {
activity.onMemeCreated(result);
mActivity.clear();
mActivity = null;
}
}
}
}