Merge remote-tracking branch 'origin/master'

This commit is contained in:
Conny Duck 2018-09-03 21:29:26 +02:00
commit a57b354247
5 changed files with 124 additions and 101 deletions

View file

@ -1,4 +1,4 @@
[![Translate - with Stringlate](https://img.shields.io/badge/translate%20with-stringlate-green.svg)](https://lonamiwebs.github.io/stringlate/translate?git=https%3A%2F%2Fgithub.com%2Ftuskyapp%2FTusky) [![Build Status](https://app.bitrise.io/app/55b2f0c77c4bba74/status.svg?token=elUl9fieM5K34iLRL0rpoA&branch=master)](https://app.bitrise.io/app/55b2f0c77c4bba74) [![CircleCI](https://circleci.com/gh/tuskyapp/Tusky.svg?style=svg)](https://circleci.com/gh/tuskyapp/Tusky)
[![Translate - with Stringlate](https://img.shields.io/badge/translate%20with-stringlate-green.svg)](https://lonamiwebs.github.io/stringlate/translate?git=https%3A%2F%2Fgithub.com%2Ftuskyapp%2FTusky) [![Build Status](https://app.bitrise.io/app/a3e773c3c57a894c/status.svg?token=qLu_Ti4Gp2LWcYT4eo2INQ&branch=master)](https://app.bitrise.io/app/a3e773c3c57a894c#/builds) [![CircleCI](https://circleci.com/gh/tuskyapp/Tusky.svg?style=svg)](https://circleci.com/gh/tuskyapp/Tusky)
# Tusky
![](/fastlane/metadata/android/en-US/images/icon.png)

View file

@ -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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}
}