diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7ca18b7cc..819314ff3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/twidere/build.gradle b/twidere/build.gradle index 561f6bd73..dba8d212f 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -57,6 +57,7 @@ configurations { dependencies { // wearApp project(':twidere.wear') apt 'com.bluelinelabs:logansquare-compiler:1.1.0' + apt 'com.hannesdorfmann.parcelableplease:processor:1.0.1' compile 'com.android.support:multidex:1.0.1' compile 'com.android.support:support-v13:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' @@ -88,6 +89,8 @@ dependencies { compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' compile 'com.makeramen:roundedimageview:2.1.0' compile 'com.soundcloud.android:android-crop:1.0.0@aar' + compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1' + compile 'com.github.mariotaku:PickNCrop:76563fae81' googleCompile 'com.google.android.gms:play-services-maps:7.5.0' googleCompile 'com.google.maps.android:android-maps-utils:0.3.4' fdroidCompile 'org.osmdroid:osmdroid-android:4.3' diff --git a/twidere/src/main/AndroidManifest.xml b/twidere/src/main/AndroidManifest.xml index 5104922a6..2238d9438 100644 --- a/twidere/src/main/AndroidManifest.xml +++ b/twidere/src/main/AndroidManifest.xml @@ -316,7 +316,7 @@ diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java index 16af21d2c..53ee3f51f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java @@ -736,9 +736,8 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL if (s instanceof Spannable && count == 1 && before == 0) { final ImageSpan[] imageSpans = ((Spannable) s).getSpans(start, start + count, ImageSpan.class); if (imageSpans.length == 1) { - final Intent intent = new Intent(ComposeActivity.this, ImagePickerActivity.class); - intent.setAction(ImagePickerActivity.INTENT_ACTION_GET_IMAGE); - intent.setData(Uri.parse(imageSpans[0].getSource())); + final Intent intent = ThemedImagePickerActivity.withThemed(ComposeActivity.this) + .getImage(Uri.parse(imageSpans[0].getSource())).build(); startActivityForResult(intent, REQUEST_PICK_IMAGE); ((Spannable) s).setSpan(new MarkForDeleteSpan(), start, start + count, Spanned.SPAN_INCLUSIVE_INCLUSIVE); @@ -1050,8 +1049,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL } private boolean pickImage() { - final Intent intent = new Intent(this, ImagePickerActivity.class); - intent.setAction(ImagePickerActivity.INTENT_ACTION_PICK_IMAGE); + final Intent intent = ThemedImagePickerActivity.withThemed(this).pickImage().build(); startActivityForResult(intent, REQUEST_PICK_IMAGE); return true; } @@ -1177,8 +1175,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL } private boolean takePhoto() { - final Intent intent = new Intent(this, ImagePickerActivity.class); - intent.setAction(ImagePickerActivity.INTENT_ACTION_TAKE_PHOTO); + final Intent intent = ThemedImagePickerActivity.withThemed(this).takePhoto().build(); startActivityForResult(intent, REQUEST_TAKE_PHOTO); return true; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ImagePickerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ImagePickerActivity.java deleted file mode 100644 index ae013c602..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ImagePickerActivity.java +++ /dev/null @@ -1,369 +0,0 @@ -package org.mariotaku.twidere.activity.support; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Environment; -import android.provider.MediaStore; -import android.support.annotation.NonNull; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; -import android.util.Log; -import android.webkit.MimeTypeMap; - -import com.github.ooxi.jdatauri.DataUri; -import com.soundcloud.android.crop.Crop; - -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.activity.ImageCropperActivity; -import org.mariotaku.twidere.fragment.ProgressDialogFragment; -import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment; -import org.mariotaku.twidere.model.SingleResponse; -import org.mariotaku.twidere.util.RestFuNetworkStreamDownloader; -import org.mariotaku.twidere.util.ThemeUtils; -import org.mariotaku.twidere.util.Utils; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import static android.os.Environment.getExternalStorageState; - -public class ImagePickerActivity extends ThemedFragmentActivity { - - public static final int REQUEST_PICK_IMAGE = 101; - public static final int REQUEST_TAKE_PHOTO = 102; - public static final int REQUEST_CROP = 103; - - public static final String INTENT_ACTION_TAKE_PHOTO = INTENT_PACKAGE_PREFIX + "TAKE_PHOTO"; - public static final String INTENT_ACTION_PICK_IMAGE = INTENT_PACKAGE_PREFIX + "PICK_IMAGE"; - public static final String INTENT_ACTION_GET_IMAGE = INTENT_PACKAGE_PREFIX + "GET_IMAGE"; - - public static final String EXTRA_ASPECT_X = "aspect_x"; - public static final String EXTRA_ASPECT_Y = "aspect_y"; - public static final String EXTRA_MAX_WIDTH = "max_width"; - public static final String EXTRA_MAX_HEIGHT = "max_height"; - - private Uri mTempPhotoUri; - private CopyImageTask mTask; - private Runnable mImageSelectedRunnable; - - @Override - public int getThemeColor() { - return ThemeUtils.getUserAccentColor(this); - } - - @Override - public int getThemeResourceId() { - return ThemeUtils.getNoDisplayThemeResource(this); - } - - @Override - public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { - if (resultCode != RESULT_OK) { - setResult(RESULT_CANCELED); - finish(); - return; - } - final boolean needsCrop; - final Uri src; - switch (requestCode) { - case REQUEST_PICK_IMAGE: { - needsCrop = true; - src = intent.getData(); - break; - } - case REQUEST_TAKE_PHOTO: { - needsCrop = true; - src = mTempPhotoUri; - break; - } - case REQUEST_CROP: { - needsCrop = false; - src = mTempPhotoUri; - break; - } - default: { - finish(); - return; - } - } - if (src == null) return; - mImageSelectedRunnable = new Runnable() { - - @Override - public void run() { - imageSelected(src, needsCrop, !needsCrop); - } - }; - } - - @Override - protected void onResumeFragments() { - super.onResumeFragments(); - if (mImageSelectedRunnable != null) { - runOnUiThread(mImageSelectedRunnable); - } - } - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Intent intent = getIntent(); - final String action = intent.getAction(); - if (INTENT_ACTION_TAKE_PHOTO.equals(action)) { - takePhoto(); - } else if (INTENT_ACTION_PICK_IMAGE.equals(action)) { - pickImage(); - } else if (INTENT_ACTION_GET_IMAGE.equals(action)) { - imageSelected(intent.getData(), true, false); - } else { - new ImageSourceDialogFragment().show(getSupportFragmentManager(), "image_source"); - } - } - - @Override - protected void onStop() { - mImageSelectedRunnable = null; - super.onStop(); - } - - private void imageSelected(final Uri uri, final boolean needsCrop, final boolean deleteSource) { - final CopyImageTask task = mTask; - if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) return; - mTask = new CopyImageTask(this, uri, needsCrop, deleteSource); - mTask.execute(); - } - - private void pickImage() { - final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("image/*"); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - try { - startActivityForResult(intent, REQUEST_PICK_IMAGE); - } catch (final ActivityNotFoundException ignored) { - } - } - - private void takePhoto() { - final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - final Uri uri = createTempImageUri(); - mTempPhotoUri = uri; - intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); - try { - startActivityForResult(intent, REQUEST_TAKE_PHOTO); - } catch (final ActivityNotFoundException ignored) { - takePhotoFallback(mTempPhotoUri); - } - } - - private Uri createTempImageUri() { - if (!getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) return null; - final File extCacheDir = getExternalCacheDir(); - final File file; - try { - file = File.createTempFile("temp_image_", ".tmp", extCacheDir); - } catch (final IOException e) { - return null; - } - return Uri.fromFile(file); - } - - private boolean takePhotoFallback(Uri uri) { - final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); - try { - startActivityForResult(intent, REQUEST_TAKE_PHOTO); - } catch (final ActivityNotFoundException e) { - return false; - } - return true; - } - - private static class CopyImageTask extends AsyncTask> { - private static final String TAG_COPYING_IMAGE = "copying_image"; - private final ImagePickerActivity mActivity; - private final Uri mUri; - private final boolean mNeedsCrop; - private final boolean mDeleteSource; - - public CopyImageTask(final ImagePickerActivity activity, final Uri uri, final boolean needsCrop, final boolean deleteSource) { - mActivity = activity; - mUri = uri; - mNeedsCrop = needsCrop; - mDeleteSource = deleteSource; - } - - @Override - protected SingleResponse doInBackground(final Object... params) { - final ContentResolver cr = mActivity.getContentResolver(); - InputStream is = null; - OutputStream os = null; - try { - final File cacheDir = mActivity.getCacheDir(); - final Uri uri = this.mUri; - final String mimeType; - final String scheme = uri.getScheme(); - if (SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme)) { - final NetworkStreamDownloader downloader = new RestFuNetworkStreamDownloader(mActivity); - final NetworkStreamDownloader.DownloadResult result = downloader.get(uri); - is = result.stream; - mimeType = result.mimeType; - } else if (SCHEME_DATA.equals(scheme)) { - final DataUri dataUri = DataUri.parse(uri.toString(), Charset.defaultCharset()); - is = new ByteArrayInputStream(dataUri.getData()); - mimeType = dataUri.getMime(); - } else { - is = cr.openInputStream(uri); - final BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inJustDecodeBounds = true; - BitmapFactory.decodeStream(cr.openInputStream(uri), null, opts); - mimeType = opts.outMimeType; - } - final String suffix = mimeType != null ? "." - + MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType) : null; - final File outFile = File.createTempFile("temp_image_", suffix, cacheDir); - os = new FileOutputStream(outFile); - Utils.copyStream(is, os); - if (mDeleteSource && SCHEME_FILE.equals(scheme)) { - final File sourceFile = new File(mUri.getPath()); - sourceFile.delete(); - } - return SingleResponse.getInstance(outFile); - } catch (final IOException e) { - return SingleResponse.getInstance(e); - } finally { - Utils.closeSilently(os); - Utils.closeSilently(is); - } - } - - @Override - protected void onPreExecute() { - final ProgressDialogFragment f = ProgressDialogFragment.show(mActivity, TAG_COPYING_IMAGE); - f.setCancelable(false); - } - - @Override - protected void onPostExecute(final SingleResponse result) { - final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(TAG_COPYING_IMAGE); - if (f instanceof DialogFragment) { - ((DialogFragment) f).dismiss(); - } - if (result.hasData()) { - final Uri dstUri = Uri.fromFile(result.getData()); - final Intent callingIntent = mActivity.getIntent(); - if (mNeedsCrop && ((callingIntent.hasExtra(EXTRA_ASPECT_X) && callingIntent.hasExtra(EXTRA_ASPECT_Y)) - || (callingIntent.hasExtra(EXTRA_MAX_WIDTH) && callingIntent.hasExtra(EXTRA_MAX_HEIGHT)))) { - final Uri tempImageUri = mActivity.createTempImageUri(); - final Crop crop = Crop.of(dstUri, tempImageUri); - final int aspectX = callingIntent.getIntExtra(EXTRA_ASPECT_X, -1); - final int aspectY = callingIntent.getIntExtra(EXTRA_ASPECT_Y, -1); - if (aspectX > 0 && aspectY > 0) { - crop.withAspect(aspectX, aspectY); - } - final int maxWidth = callingIntent.getIntExtra(EXTRA_MAX_WIDTH, -1); - final int maxHeight = callingIntent.getIntExtra(EXTRA_MAX_HEIGHT, -1); - if (maxWidth > 0 && maxHeight > 0) { - crop.withMaxSize(maxWidth, maxHeight); - } - final Intent cropIntent = crop.getIntent(mActivity); - cropIntent.setClass(mActivity, ImageCropperActivity.class); - mActivity.mTempPhotoUri = tempImageUri; - mActivity.startActivityForResult(cropIntent, REQUEST_CROP); - return; - } - final Intent data = new Intent(); - data.setData(dstUri); - mActivity.setResult(RESULT_OK, data); - } else if (result.hasException()) { - Log.w(LOGTAG, result.getException()); - } - mActivity.finish(); - } - } - - public static class ImageSourceDialogFragment extends BaseSupportDialogFragment implements OnClickListener { - - @Override - public void onClick(final DialogInterface dialog, final int which) { - final FragmentActivity activity = getActivity(); - if (!(activity instanceof ImagePickerActivity)) return; - final ImagePickerActivity addImageActivity = (ImagePickerActivity) activity; - final String source = getResources().getStringArray(R.array.value_image_sources)[which]; - if ("gallery".equals(source)) { - addImageActivity.pickImage(); - } else if ("camera".equals(source)) { - addImageActivity.takePhoto(); - } - } - - @NonNull - @Override - public Dialog onCreateDialog(final Bundle savedInstanceState) { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setItems(R.array.entries_image_sources, this); - return builder.create(); - } - - @Override - public void onCancel(final DialogInterface dialog) { - super.onCancel(dialog); - final FragmentActivity a = getActivity(); - if (a != null) { - a.finish(); - } - } - - @Override - public void onDismiss(final DialogInterface dialog) { - super.onDismiss(dialog); - } - } - - public static abstract class NetworkStreamDownloader { - - private final Context mContext; - - protected NetworkStreamDownloader(Context context) { - mContext = context; - } - - public final Context getContext() { - return mContext; - } - - public abstract DownloadResult get(Uri uri) throws IOException; - - public static final class DownloadResult { - - private final InputStream stream; - private final String mimeType; - - public DownloadResult(final InputStream stream, final String mimeType) { - this.stream = stream; - this.mimeType = mimeType; - } - - public static DownloadResult get(InputStream stream, String mimeType) { - return new DownloadResult(stream, mimeType); - } - - } - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedImagePickerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedImagePickerActivity.java new file mode 100644 index 000000000..d363e4a97 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedImagePickerActivity.java @@ -0,0 +1,73 @@ +package org.mariotaku.twidere.activity.support; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.annotation.NonNull; + +import org.mariotaku.pickncrop.library.ImagePickerActivity; +import org.mariotaku.twidere.activity.ImageCropperActivity; +import org.mariotaku.twidere.util.RestFuNetworkStreamDownloader; +import org.mariotaku.twidere.util.ThemeUtils; + +public class ThemedImagePickerActivity extends ImagePickerActivity { + + @Override + public void setTheme(final int resid) { + super.setTheme(ThemeUtils.getNoDisplayThemeResource(this)); + } + + public static ThemedIntentBuilder withThemed(Context context) { + return new ThemedIntentBuilder(context); + } + + public static final class ThemedIntentBuilder { + private final Context context; + private final IntentBuilder intentBuilder; + + public ThemedIntentBuilder(final Context context) { + this.context = context; + this.intentBuilder = new IntentBuilder(context); + intentBuilder.cropImageActivityClass(ImageCropperActivity.class); + intentBuilder.streamDownloaderClass(RestFuNetworkStreamDownloader.class); + } + + public ThemedIntentBuilder takePhoto() { + intentBuilder.takePhoto(); + return this; + } + + public ThemedIntentBuilder getImage(@NonNull final Uri uri) { + intentBuilder.getImage(uri); + return this; + } + + public Intent build() { + final Intent intent = intentBuilder.build(); + intent.setClass(context, ThemedImagePickerActivity.class); + return intent; + } + + public ThemedIntentBuilder pickImage() { + intentBuilder.pickImage(); + return this; + } + + public ThemedIntentBuilder addEntry(final String name, final String value, final int result) { + intentBuilder.addEntry(name, value, result); + return this; + } + + public ThemedIntentBuilder maximumSize(final int w, final int h) { + intentBuilder.maximumSize(w, h); + return this; + } + + public ThemedIntentBuilder aspectRatio(final int x, final int y) { + intentBuilder.aspectRatio(x, y); + return this; + } + } + + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java index 966d8991a..e863d4589 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java @@ -78,7 +78,7 @@ import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.RawItemArray; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.BaseAppCompatActivity; -import org.mariotaku.twidere.activity.support.ImagePickerActivity; +import org.mariotaku.twidere.activity.support.ThemedImagePickerActivity; import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; import org.mariotaku.twidere.adapter.MessageConversationAdapter; import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter; @@ -467,7 +467,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements break; } case R.id.add_image: { - final Intent intent = new Intent(getActivity(), ImagePickerActivity.class); + final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).build(); startActivityForResult(intent, REQUEST_PICK_IMAGE); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java index 5852cdbee..1351512ec 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java @@ -50,7 +50,7 @@ import com.twitter.Validator; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity; -import org.mariotaku.twidere.activity.support.ImagePickerActivity; +import org.mariotaku.twidere.activity.support.ThemedImagePickerActivity; import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; import org.mariotaku.twidere.api.twitter.model.ProfileUpdate; @@ -86,6 +86,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On private static final int REQUEST_PICK_LINK_COLOR = 3; private static final int REQUEST_PICK_BACKGROUND_COLOR = 4; + private static final int RESULT_REMOVE_BANNER = 101; + private MediaLoaderWrapper mLazyImageLoader; private AsyncTaskManager mAsyncTaskManager; private AsyncTask mTask; @@ -93,8 +95,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On private ImageView mProfileBannerView; private MaterialEditText mEditName, mEditDescription, mEditLocation, mEditUrl; private View mProgressContainer, mEditProfileContent; - private View mProfileImageCamera, mProfileImageGallery; - private View mProfileBannerGallery, mProfileBannerRemove; + private View mEditProfileImage; + private View mEditProfileBanner; private View mSetLinkColor, mSetBackgroundColor; private ForegroundColorView mLinkColor, mBackgroundColor; private long mAccountId; @@ -127,41 +129,18 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On case R.id.profile_banner: { break; } - case R.id.profile_image_camera: { - final Intent intent = new Intent(getActivity(), ImagePickerActivity.class); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_X, 1); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_Y, 1); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_WIDTH, 512); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_HEIGHT, 512); - intent.setAction(ImagePickerActivity.INTENT_ACTION_TAKE_PHOTO); + case R.id.edit_profile_image: { + final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(1, 1) + .maximumSize(512, 512).build(); startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_IMAGE); break; } - case R.id.profile_image_gallery: { - final Intent intent = new Intent(getActivity(), ImagePickerActivity.class); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_X, 3); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_Y, 1); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_WIDTH, 1500); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_HEIGHT, 500); - intent.setAction(ImagePickerActivity.INTENT_ACTION_PICK_IMAGE); - startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_IMAGE); - break; - } - case R.id.profile_banner_gallery: { - final Intent intent = new Intent(getActivity(), ImagePickerActivity.class); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_X, 1); - intent.putExtra(ImagePickerActivity.EXTRA_ASPECT_Y, 1); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_WIDTH, 512); - intent.putExtra(ImagePickerActivity.EXTRA_MAX_HEIGHT, 512); - intent.setAction(ImagePickerActivity.INTENT_ACTION_PICK_IMAGE); + case R.id.edit_profile_banner: { + final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(3, 1) + .maximumSize(1500, 500).addEntry(getString(R.string.remove), "remove_banner", RESULT_REMOVE_BANNER).build(); startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BANNER_IMAGE); break; } - case R.id.profile_banner_remove: { - mTask = new RemoveProfileBannerTaskInternal(user.account_id); - AsyncTaskUtils.executeTask(mTask); - break; - } case R.id.set_link_color: { final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); intent.putExtra(EXTRA_COLOR, user.link_color); @@ -249,10 +228,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On mProfileImageView.setOnClickListener(this); mProfileBannerView.setOnClickListener(this); - mProfileImageCamera.setOnClickListener(this); - mProfileImageGallery.setOnClickListener(this); - mProfileBannerGallery.setOnClickListener(this); - mProfileBannerRemove.setOnClickListener(this); + mEditProfileBanner.setOnClickListener(this); + mEditProfileImage.setOnClickListener(this); mSetLinkColor.setOnClickListener(this); mSetBackgroundColor.setOnClickListener(this); @@ -299,10 +276,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On mEditDescription = (MaterialEditText) view.findViewById(R.id.description); mEditLocation = (MaterialEditText) view.findViewById(R.id.location); mEditUrl = (MaterialEditText) view.findViewById(R.id.url); - mProfileImageCamera = view.findViewById(R.id.profile_image_camera); - mProfileImageGallery = view.findViewById(R.id.profile_image_gallery); - mProfileBannerGallery = view.findViewById(R.id.profile_banner_gallery); - mProfileBannerRemove = view.findViewById(R.id.profile_banner_remove); + mEditProfileImage = view.findViewById(R.id.edit_profile_image); + mEditProfileBanner = view.findViewById(R.id.edit_profile_banner); mLinkColor = (ForegroundColorView) view.findViewById(R.id.link_color); mBackgroundColor = (ForegroundColorView) view.findViewById(R.id.background_color); mSetLinkColor = view.findViewById(R.id.set_link_color); @@ -315,7 +290,11 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On switch (requestCode) { case REQUEST_UPLOAD_PROFILE_BANNER_IMAGE: { if (mTask != null && mTask.getStatus() == Status.RUNNING) return; - mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAsyncTaskManager, mAccountId, data.getData(), true); + if (resultCode == RESULT_REMOVE_BANNER) { + mTask = new RemoveProfileBannerTaskInternal(mAccountId); + } else { + mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAsyncTaskManager, mAccountId, data.getData(), true); + } AsyncTaskUtils.executeTask(mTask); break; } @@ -343,6 +322,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } + boolean isProfileChanged() { final ParcelableUser user = mUser; if (user == null) return true; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ClipboardUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/ClipboardUtils.java index 5e7ba2c64..119923745 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ClipboardUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ClipboardUtils.java @@ -19,9 +19,14 @@ package org.mariotaku.twidere.util; +import android.annotation.TargetApi; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.os.Build; +import android.support.annotation.Nullable; +import android.text.Spanned; +import android.text.style.ImageSpan; public final class ClipboardUtils { @@ -31,4 +36,30 @@ public final class ClipboardUtils { clipboardManager.setPrimaryClip(ClipData.newPlainText(text, text)); return true; } + + @Nullable + public static String getImageUrl(final Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return null; + return ClipboardUtilsAPI16.getImageUrl(context); + } + + private static class ClipboardUtilsAPI16 { + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + public static String getImageUrl(final Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return null; + final ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + final ClipData primaryClip = cm.getPrimaryClip(); + if (primaryClip.getItemCount() > 0) { + final ClipData.Item item = primaryClip.getItemAt(0); + final CharSequence styledText = item.coerceToStyledText(context); + if (styledText instanceof Spanned) { + final Spanned spanned = (Spanned) styledText; + final ImageSpan[] imageSpans = spanned.getSpans(0, spanned.length(), ImageSpan.class); + if (imageSpans.length == 1) return imageSpans[0].getSource(); + } + } + return null; + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/RestFuNetworkStreamDownloader.java b/twidere/src/main/java/org/mariotaku/twidere/util/RestFuNetworkStreamDownloader.java index 4eb515e1b..921ed226d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/RestFuNetworkStreamDownloader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/RestFuNetworkStreamDownloader.java @@ -28,14 +28,14 @@ import org.mariotaku.restfu.http.RestHttpClient; import org.mariotaku.restfu.http.RestHttpRequest; import org.mariotaku.restfu.http.RestHttpResponse; import org.mariotaku.restfu.http.mime.TypedData; -import org.mariotaku.twidere.activity.support.ImagePickerActivity; +import org.mariotaku.twidere.activity.support.ThemedImagePickerActivity; import java.io.IOException; /** * Created by mariotaku on 15/6/17. */ -public class RestFuNetworkStreamDownloader extends ImagePickerActivity.NetworkStreamDownloader { +public class RestFuNetworkStreamDownloader extends ThemedImagePickerActivity.NetworkStreamDownloader { public RestFuNetworkStreamDownloader(Context context) { super(context); diff --git a/twidere/src/main/res/layout/fragment_user_profile_editor.xml b/twidere/src/main/res/layout/fragment_user_profile_editor.xml index 4051b0b59..13a57ee71 100644 --- a/twidere/src/main/res/layout/fragment_user_profile_editor.xml +++ b/twidere/src/main/res/layout/fragment_user_profile_editor.xml @@ -17,10 +17,11 @@ ~ along with this program. If not, see . --> - @@ -64,71 +68,27 @@ android:layout_height="@dimen/element_size_mlarge" android:layout_gravity="center" android:foreground="?selectableItemBackground" - android:scaleType="centerCrop" /> + android:scaleType="centerCrop"/> - - - - - - - - - - - - - + android:layout_marginLeft="@dimen/element_spacing_normal" + android:layout_marginStart="@dimen/element_spacing_normal" + android:text="@string/profile_image" + android:textAllCaps="true" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:textColorPrimary" + android:textStyle="bold"/> @@ -138,65 +98,19 @@ android:layout_height="@dimen/element_size_mlarge" android:layout_gravity="center" android:foreground="?selectableItemBackground" - android:scaleType="centerCrop" /> + android:scaleType="centerCrop"/> - - - - - - - - - - - - - + android:layout_marginLeft="@dimen/element_spacing_normal" + android:layout_marginStart="@dimen/element_spacing_normal" + android:paddingTop="@dimen/element_spacing_normal" + android:text="@string/profile_banner" + android:textAllCaps="true" + android:textAppearance="?android:textAppearanceSmall" + android:textColor="?android:textColorPrimary" + android:textStyle="bold"/> @@ -227,7 +141,7 @@ app:met_baseColor="?android:textColorPrimary" app:met_floatingLabel="normal" app:met_floatingLabelText="@string/name" - app:met_maxCharacters="20" /> + app:met_maxCharacters="20"/> + app:met_maxCharacters="160"/> + app:met_maxCharacters="30"/> + app:met_maxCharacters="100"/> @@ -294,7 +208,7 @@ android:id="@+id/link_color" android:layout_width="@dimen/element_size_normal" android:layout_height="@dimen/element_size_normal" - android:layout_weight="0" /> + android:layout_weight="0"/> + android:textStyle="bold"/> @@ -323,7 +237,7 @@ android:id="@+id/background_color" android:layout_width="@dimen/element_size_normal" android:layout_height="@dimen/element_size_normal" - android:layout_weight="0" /> + android:layout_weight="0"/> + android:textStyle="bold"/> @@ -353,7 +267,7 @@ android:visibility="visible" tools:visibility="gone"> - + \ No newline at end of file diff --git a/twidere/src/main/res/values/arrays.xml b/twidere/src/main/res/values/arrays.xml index ece920e8f..0c9a4b198 100644 --- a/twidere/src/main/res/values/arrays.xml +++ b/twidere/src/main/res/values/arrays.xml @@ -104,12 +104,14 @@ @string/scale - @string/from_camera - @string/from_gallery + @string/source_camera + @string/source_gallery + @string/source_clipboard camera gallery + clipboard round diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index fe1df69eb..31ed81ae7 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -646,7 +646,11 @@ Blocking Load more Photo + Camera Gallery + Camera + Gallery + Clipboard Remove Load media Text color