From 95b1a7c61aea6a5866def00fc3e68a33be10e116 Mon Sep 17 00:00:00 2001
From: Konrad Pozniak <connyduck@users.noreply.github.com>
Date: Mon, 3 Sep 2018 16:24:39 +0200
Subject: [PATCH 1/3] Update bitrise badge (#833)

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6d4754d7..1e89f936 100644
--- a/README.md
+++ b/README.md
@@ -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)

From 0b3bee0d15e53de52dedce4e6627f5f7267a7673 Mon Sep 17 00:00:00 2001
From: Konrad Pozniak <connyduck@users.noreply.github.com>
Date: Mon, 3 Sep 2018 20:16:12 +0200
Subject: [PATCH 2/3] fix account switching when offline/error (#830)

---
 .../com/keylesspalace/tusky/MainActivity.java | 21 +++++++++++--------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
index 3a062fcf..dcbce519 100644
--- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
@@ -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);
 
     }

From aac63441d70e1c7782daebb18fb6d832533c8b96 Mon Sep 17 00:00:00 2001
From: Konrad Pozniak <connyduck@users.noreply.github.com>
Date: Mon, 3 Sep 2018 20:26:35 +0200
Subject: [PATCH 3/3] fix image preview rotation in ComposeActivity (#831)

---
 .../keylesspalace/tusky/ComposeActivity.java  | 32 +++++--
 .../tusky/util/DownsizeImageTask.java         | 87 +------------------
 .../keylesspalace/tusky/util/MediaUtils.java  | 83 +++++++++++++++++-
 3 files changed, 111 insertions(+), 91 deletions(-)

diff --git a/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java b/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
index 4662fbbd..f36cff2a 100644
--- a/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
@@ -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);
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/DownsizeImageTask.java b/app/src/main/java/com/keylesspalace/tusky/util/DownsizeImageTask.java
index be0c989d..3b9f04d0 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/DownsizeImageTask.java
+++ b/app/src/main/java/com/keylesspalace/tusky/util/DownsizeImageTask.java
@@ -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;
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/MediaUtils.java b/app/src/main/java/com/keylesspalace/tusky/util/MediaUtils.java
index 2e93fc92..0ad3adb1 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/MediaUtils.java
+++ b/app/src/main/java/com/keylesspalace/tusky/util/MediaUtils.java
@@ -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;
+    }
 }