Merge remote-tracking branch 'origin/master'
This commit is contained in:
		
				commit
				
					
						a57b354247
					
				
			
		
					 5 changed files with 124 additions and 101 deletions
				
			
		|  | @ -1,4 +1,4 @@ | |||
| [](https://lonamiwebs.github.io/stringlate/translate?git=https%3A%2F%2Fgithub.com%2Ftuskyapp%2FTusky) [](https://app.bitrise.io/app/55b2f0c77c4bba74) [](https://circleci.com/gh/tuskyapp/Tusky) | ||||
| [](https://lonamiwebs.github.io/stringlate/translate?git=https%3A%2F%2Fgithub.com%2Ftuskyapp%2FTusky) [](https://app.bitrise.io/app/a3e773c3c57a894c#/builds) [](https://circleci.com/gh/tuskyapp/Tusky) | ||||
| # Tusky | ||||
| 
 | ||||
|  | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ package com.keylesspalace.tusky; | |||
| import android.Manifest; | ||||
| import android.annotation.SuppressLint; | ||||
| import android.app.ProgressDialog; | ||||
| import android.arch.lifecycle.Lifecycle; | ||||
| import android.content.ContentResolver; | ||||
| import android.content.Context; | ||||
| import android.content.DialogInterface; | ||||
|  | @ -135,12 +136,20 @@ import java.util.Locale; | |||
| import javax.inject.Inject; | ||||
| 
 | ||||
| import at.connyduck.sparkbutton.helpers.Utils; | ||||
| import io.reactivex.Single; | ||||
| import io.reactivex.SingleObserver; | ||||
| import io.reactivex.android.schedulers.AndroidSchedulers; | ||||
| import io.reactivex.disposables.Disposable; | ||||
| import io.reactivex.schedulers.Schedulers; | ||||
| import okhttp3.MediaType; | ||||
| import okhttp3.MultipartBody; | ||||
| import retrofit2.Call; | ||||
| import retrofit2.Callback; | ||||
| import retrofit2.Response; | ||||
| 
 | ||||
| import static com.uber.autodispose.AutoDispose.autoDisposable; | ||||
| import static com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider.from; | ||||
| 
 | ||||
| public final class ComposeActivity | ||||
|         extends BaseActivity | ||||
|         implements ComposeOptionsListener, | ||||
|  | @ -1121,11 +1130,24 @@ public final class ComposeActivity | |||
|         DisplayMetrics displayMetrics = new DisplayMetrics(); | ||||
|         getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); | ||||
| 
 | ||||
|         Picasso.with(this) | ||||
|                 .load(item.uri) | ||||
|                 .resize(displayMetrics.widthPixels, displayMetrics.heightPixels) | ||||
|                 .onlyScaleDown() | ||||
|                 .into(imageView); | ||||
|         Single.fromCallable(() -> | ||||
|                 MediaUtils.getSampledBitmap(getContentResolver(), item.uri, displayMetrics.widthPixels, displayMetrics.heightPixels)) | ||||
|                 .subscribeOn(Schedulers.computation()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .as(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY))) | ||||
|                 .subscribe(new SingleObserver<Bitmap>() { | ||||
|                     @Override | ||||
|                     public void onSubscribe(Disposable d) {} | ||||
| 
 | ||||
|                     @Override | ||||
|                     public void onSuccess(Bitmap bitmap) { | ||||
|                         imageView.setImageBitmap(bitmap); | ||||
|                     } | ||||
| 
 | ||||
|                     @Override | ||||
|                     public void onError(Throwable e) { } | ||||
|                 }); | ||||
| 
 | ||||
| 
 | ||||
|         int margin = Utils.dpToPx(this, 4); | ||||
|         dialogLayout.addView(imageView); | ||||
|  |  | |||
|  | @ -420,7 +420,7 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut | |||
| 
 | ||||
|         Intent intent = new Intent(this, MainActivity.class); | ||||
|         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||||
|         startActivityWithSlideInAnimation(intent); | ||||
|         startActivity(intent); | ||||
|         finishWithoutSlideOutAnimation(); | ||||
| 
 | ||||
|         overridePendingTransition(R.anim.explode, R.anim.explode); | ||||
|  | @ -510,21 +510,15 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut | |||
| 
 | ||||
|         List<AccountEntity> allAccounts = accountManager.getAllAccountsOrderedByActive(); | ||||
| 
 | ||||
|         // reuse the already existing "add account" item | ||||
|         List<IProfile> profiles = new ArrayList<>(allAccounts.size()+1); | ||||
|         for (IProfile profile: headerResult.getProfiles()) { | ||||
|             if (profile.getIdentifier() == DRAWER_ITEM_ADD_ACCOUNT) { | ||||
|                 profiles.add(profile); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (AccountEntity acc : allAccounts) { | ||||
|             CharSequence emojifiedName = CustomEmojiHelper.emojifyString(acc.getDisplayName(), acc.getEmojis(), headerResult.getView()); | ||||
|             emojifiedName = EmojiCompat.get().process(emojifiedName); | ||||
| 
 | ||||
|             profiles.add(0, | ||||
|             profiles.add( | ||||
|                     new ProfileDrawerItem() | ||||
|                             .withSetSelected(acc.isActive()) | ||||
|                             .withName(emojifiedName) | ||||
|                             .withIcon(acc.getProfilePictureUrl()) | ||||
|                             .withNameShown(true) | ||||
|  | @ -532,6 +526,15 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut | |||
|                             .withEmail(acc.getFullName())); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         // reuse the already existing "add account" item | ||||
|         for (IProfile profile: headerResult.getProfiles()) { | ||||
|             if (profile.getIdentifier() == DRAWER_ITEM_ADD_ACCOUNT) { | ||||
|                 profiles.add(profile); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         headerResult.clear(); | ||||
|         headerResult.setProfiles(profiles); | ||||
| 
 | ||||
|     } | ||||
|  |  | |||
|  | @ -18,16 +18,11 @@ package com.keylesspalace.tusky.util; | |||
| import android.content.ContentResolver; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.graphics.Matrix; | ||||
| import android.net.Uri; | ||||
| import android.os.AsyncTask; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.media.ExifInterface; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | @ -37,7 +32,6 @@ import java.util.List; | |||
|  * aspect ratio and orientation. | ||||
|  */ | ||||
| public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> { | ||||
|     private static final String TAG = "DownsizeImageTask"; | ||||
|     private int sizeLimit; | ||||
|     private ContentResolver contentResolver; | ||||
|     private Listener listener; | ||||
|  | @ -54,83 +48,6 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> { | |||
|         this.listener = listener; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     private static Bitmap reorientBitmap(Bitmap bitmap, int orientation) { | ||||
|         Matrix matrix = new Matrix(); | ||||
|         switch (orientation) { | ||||
|             default: | ||||
|             case ExifInterface.ORIENTATION_NORMAL: { | ||||
|                 return bitmap; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: { | ||||
|                 matrix.setScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_180: { | ||||
|                 matrix.setRotate(180); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_FLIP_VERTICAL: { | ||||
|                 matrix.setRotate(180); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_TRANSPOSE: { | ||||
|                 matrix.setRotate(90); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_90: { | ||||
|                 matrix.setRotate(90); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_TRANSVERSE: { | ||||
|                 matrix.setRotate(-90); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_270: { | ||||
|                 matrix.setRotate(-90); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         try { | ||||
|             Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), | ||||
|                     bitmap.getHeight(), matrix, true); | ||||
|             if (!bitmap.sameAs(result)) { | ||||
|                 bitmap.recycle(); | ||||
|             } | ||||
|             return result; | ||||
|         } catch (OutOfMemoryError e) { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static int getOrientation(Uri uri, ContentResolver contentResolver) { | ||||
|         InputStream inputStream; | ||||
|         try { | ||||
|             inputStream = contentResolver.openInputStream(uri); | ||||
|         } catch (FileNotFoundException e) { | ||||
|             Log.d(TAG, Log.getStackTraceString(e)); | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         if (inputStream == null) { | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         ExifInterface exifInterface; | ||||
|         try { | ||||
|             exifInterface = new ExifInterface(inputStream); | ||||
|         } catch (IOException e) { | ||||
|             Log.d(TAG, Log.getStackTraceString(e)); | ||||
|             IOUtils.closeQuietly(inputStream); | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, | ||||
|                 ExifInterface.ORIENTATION_NORMAL); | ||||
|         IOUtils.closeQuietly(inputStream); | ||||
|         return orientation; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected Boolean doInBackground(Uri... uris) { | ||||
|         resultList = new ArrayList<>(); | ||||
|  | @ -147,7 +64,7 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> { | |||
|             BitmapFactory.decodeStream(inputStream, null, options); | ||||
|             IOUtils.closeQuietly(inputStream); | ||||
|             // Get EXIF data, for orientation info. | ||||
|             int orientation = getOrientation(uri, contentResolver); | ||||
|             int orientation = MediaUtils.getImageOrientation(uri, contentResolver); | ||||
|             // Then use that information to determine how much to compress. | ||||
|             ByteArrayOutputStream stream = new ByteArrayOutputStream(); | ||||
|             /* Unfortunately, there isn't a determined worst case compression ratio for image | ||||
|  | @ -176,7 +93,7 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> { | |||
|                 if (scaledBitmap == null) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 Bitmap reorientedBitmap = reorientBitmap(scaledBitmap, orientation); | ||||
|                 Bitmap reorientedBitmap = MediaUtils.reorientBitmap(scaledBitmap, orientation); | ||||
|                 if (reorientedBitmap == null) { | ||||
|                     scaledBitmap.recycle(); | ||||
|                     return false; | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import android.content.Context; | |||
| import android.database.Cursor; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.graphics.Matrix; | ||||
| import android.media.MediaMetadataRetriever; | ||||
| import android.media.ThumbnailUtils; | ||||
| import android.net.Uri; | ||||
|  | @ -27,6 +28,7 @@ import android.provider.OpenableColumns; | |||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.annotation.Px; | ||||
| import android.support.media.ExifInterface; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import java.io.ByteArrayOutputStream; | ||||
|  | @ -111,7 +113,9 @@ public class MediaUtils { | |||
|         options.inJustDecodeBounds = false; | ||||
|         try { | ||||
|             stream = contentResolver.openInputStream(uri); | ||||
|             return BitmapFactory.decodeStream(stream, null, options); | ||||
|             Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options); | ||||
|             int orientation = getImageOrientation(uri, contentResolver); | ||||
|             return reorientBitmap(bitmap, orientation); | ||||
|         } catch (FileNotFoundException e) { | ||||
|             Log.w(TAG, e); | ||||
|             return null; | ||||
|  | @ -176,4 +180,81 @@ public class MediaUtils { | |||
| 
 | ||||
|         return inSampleSize; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     public static Bitmap reorientBitmap(Bitmap bitmap, int orientation) { | ||||
|         Matrix matrix = new Matrix(); | ||||
|         switch (orientation) { | ||||
|             default: | ||||
|             case ExifInterface.ORIENTATION_NORMAL: { | ||||
|                 return bitmap; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: { | ||||
|                 matrix.setScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_180: { | ||||
|                 matrix.setRotate(180); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_FLIP_VERTICAL: { | ||||
|                 matrix.setRotate(180); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_TRANSPOSE: { | ||||
|                 matrix.setRotate(90); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_90: { | ||||
|                 matrix.setRotate(90); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_TRANSVERSE: { | ||||
|                 matrix.setRotate(-90); | ||||
|                 matrix.postScale(-1, 1); | ||||
|                 break; | ||||
|             } | ||||
|             case ExifInterface.ORIENTATION_ROTATE_270: { | ||||
|                 matrix.setRotate(-90); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         try { | ||||
|             Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), | ||||
|                     bitmap.getHeight(), matrix, true); | ||||
|             if (!bitmap.sameAs(result)) { | ||||
|                 bitmap.recycle(); | ||||
|             } | ||||
|             return result; | ||||
|         } catch (OutOfMemoryError e) { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static int getImageOrientation(Uri uri, ContentResolver contentResolver) { | ||||
|         InputStream inputStream; | ||||
|         try { | ||||
|             inputStream = contentResolver.openInputStream(uri); | ||||
|         } catch (FileNotFoundException e) { | ||||
|             Log.w(TAG, e); | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         if (inputStream == null) { | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         ExifInterface exifInterface; | ||||
|         try { | ||||
|             exifInterface = new ExifInterface(inputStream); | ||||
|         } catch (IOException e) { | ||||
|             Log.w(TAG, e); | ||||
|             IOUtils.closeQuietly(inputStream); | ||||
|             return ExifInterface.ORIENTATION_UNDEFINED; | ||||
|         } | ||||
|         int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, | ||||
|                 ExifInterface.ORIENTATION_NORMAL); | ||||
|         IOUtils.closeQuietly(inputStream); | ||||
|         return orientation; | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue