Various DM fixes (check description)

Use new download flow.
Fix blank space at top when scrolling.
Fix animated media.
This commit is contained in:
Ammar Githam 2020-11-04 23:58:06 +09:00
parent 850e119236
commit bdcb32395b
12 changed files with 151 additions and 82 deletions

View File

@ -73,6 +73,7 @@ dependencies {
implementation 'org.jsoup:jsoup:1.13.1'
implementation 'com.facebook.fresco:fresco:2.3.0'
implementation 'com.facebook.fresco:animated-gif:2.3.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'

View File

@ -40,10 +40,10 @@ import androidx.navigation.ui.NavigationUI;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
@ -97,11 +97,12 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
R.id.notificationsViewer,
R.id.themePreferencesFragment,
R.id.favoritesFragment,
R.id.backupPreferencesFragment
// , R.id.postViewV2Fragment
R.id.backupPreferencesFragment,
R.id.directMessagesThreadFragment
);
private static final Map<Integer, Integer> NAV_TO_MENU_ID_MAP = new HashMap<>();
private static final List<Integer> REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = Collections.singletonList(R.id.commentsViewerFragment);
private static final List<Integer> REMOVE_COLLAPSING_TOOLBAR_SCROLL_DESTINATIONS = ImmutableList.of(R.id.commentsViewerFragment,
R.id.directMessagesThreadFragment);
private static final String FIRST_FRAGMENT_GRAPH_INDEX_KEY = "firstFragmentGraphIndex";
private ActivityMainBinding binding;

View File

@ -1,33 +1,64 @@
package awais.instagrabber.adapters.viewholder.directmessages;
import android.net.Uri;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.util.Pair;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import awais.instagrabber.R;
import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.utils.NumberUtils;
import awais.instagrabber.utils.Utils;
public class DirectMessageAnimatedMediaViewHolder extends DirectMessageItemViewHolder {
private final LayoutDmAnimatedMediaBinding binding;
private final int maxHeight;
private final int maxWidth;
public DirectMessageAnimatedMediaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding,
@NonNull final LayoutDmAnimatedMediaBinding binding,
final View.OnClickListener onClickListener) {
super(baseBinding, onClickListener);
this.binding = binding;
maxHeight = itemView.getResources().getDimensionPixelSize(R.dimen.dm_media_img_max_height);
maxWidth = (int) (Utils.displayMetrics.widthPixels - Utils.convertDpToPx(64) - getItemMargin());
setItemView(binding.getRoot());
removeElevation();
}
@Override
public void bindItem(final DirectItemModel directItemModel) {
final DirectItemModel.DirectItemAnimatedMediaModel animatedMediaModel = directItemModel.getAnimatedMediaModel();
final String url = animatedMediaModel.getGifUrl();
final Pair<Integer, Integer> widthHeight = NumberUtils.calculateWidthHeight(
animatedMediaModel.getHeight(),
animatedMediaModel.getWidth(),
maxHeight,
maxWidth
);
binding.ivAnimatedMessage.setVisibility(View.VISIBLE);
final ViewGroup.LayoutParams layoutParams = binding.ivAnimatedMessage.getLayoutParams();
final int width = widthHeight.first != null ? widthHeight.first : 0;
final int height = widthHeight.second != null ? widthHeight.second : 0;
layoutParams.width = width;
layoutParams.height = height;
binding.ivAnimatedMessage.requestLayout();
final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
.setResizeOptions(ResizeOptions.forDimensions(width, height))
.build();
binding.ivAnimatedMessage.setController(Fresco.newDraweeControllerBuilder()
.setUri(directItemModel.getAnimatedMediaModel().getGifUrl())
.setImageRequest(request)
.setAutoPlayAnimations(true)
.build());
binding.ivAnimatedMessage.setVisibility(View.VISIBLE);
}
}

View File

@ -71,6 +71,10 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
this.binding.messageCard.addView(view);
}
public int getItemMargin() {
return itemMargin;
}
public abstract void bindItem(final DirectItemModel directItemModel);
@Nullable
@ -88,4 +92,8 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde
}
return null;
}
protected void removeElevation() {
binding.messageCard.setCardElevation(0);
}
}

View File

@ -26,7 +26,7 @@ public class DirectMessageMediaViewHolder extends DirectMessageItemViewHolder {
super(baseBinding, onClickListener);
this.binding = binding;
maxHeight = itemView.getResources().getDimensionPixelSize(R.dimen.dm_media_img_max_height);
maxWidth = (int) (Utils.displayMetrics.widthPixels * 0.8);
maxWidth = (int) (Utils.displayMetrics.widthPixels - Utils.convertDpToPx(64) - getItemMargin());
setItemView(binding.getRoot());
}

View File

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
@ -26,6 +27,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
@ -78,6 +81,7 @@ import awais.instagrabber.utils.Utils;
public class DirectMessageThreadFragment extends Fragment {
private static final String TAG = "DirectMessagesThreadFmt";
private static final int PICK_IMAGE = 100;
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
private AppCompatActivity fragmentActivity;
private String threadId;
@ -169,8 +173,9 @@ public class DirectMessageThreadFragment extends Fragment {
binding.swipeRefreshLayout.setRefreshing(false);
}
};
private LinearLayout root;
private ConstraintLayout root;
private boolean shouldRefresh = true;
private DirectItemModel.DirectItemMediaModel downloadMediaItem;
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
@ -251,18 +256,7 @@ public class DirectMessageThreadFragment extends Fragment {
break;
case RAVEN_MEDIA:
case MEDIA:
final ProfileModel user = getUser(directItemModel.getUserId());
final DirectItemModel.DirectItemMediaModel selectedItem =
itemType == DirectItemType.MEDIA ? directItemModel.getMediaModel() : directItemModel.getRavenMediaModel().getMedia();
final String url = selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO
? selectedItem.getVideoUrl()
: selectedItem.getThumbUrl();
if (url == null) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
} else {
DownloadUtils.dmDownload(context, user.getUsername(), DownloadMethod.DOWNLOAD_DIRECT, selectedItem);
Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show();
}
downloadItem(context);
break;
case STORY_SHARE:
if (directItemModel.getReelShare() != null) {
@ -295,11 +289,13 @@ public class DirectMessageThreadFragment extends Fragment {
} else if (which == 1) {
sendText(null, directItemModel.getItemId(), directItemModel.isLiked());
} else if (which == 2) {
if (directItemModel == null)
if (directItemModel == null) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
else if (String.valueOf(directItemModel.getUserId()).equals(myId))
} else if (String.valueOf(directItemModel.getUserId()).equals(myId)) {
new ThreadAction().execute("delete", directItemModel.getItemId());
else searchUsername(getUser(directItemModel.getUserId()).getUsername());
} else {
searchUsername(getUser(directItemModel.getUserId()).getUsername());
}
}
};
final View.OnClickListener onClickListener = v -> {
@ -365,6 +361,26 @@ public class DirectMessageThreadFragment extends Fragment {
}
}
private void downloadItem(final Context context) {
final ProfileModel user = getUser(directItemModel.getUserId());
final DirectItemModel.DirectItemMediaModel selectedItem = directItemModel.getItemType() == DirectItemType.MEDIA
? directItemModel.getMediaModel()
: directItemModel.getRavenMediaModel().getMedia();
final String url = selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO
? selectedItem.getVideoUrl()
: selectedItem.getThumbUrl();
if (url == null) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
} else {
if (ContextCompat.checkSelfPermission(context, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
DownloadUtils.dmDownload(context, user.getUsername(), selectedItem.getId(), url);
} else {
requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
}
Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onResume() {
super.onResume();
@ -422,6 +438,17 @@ public class DirectMessageThreadFragment extends Fragment {
if (listViewModel != null) listViewModel.getList().postValue(Collections.emptyList());
}
@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
final boolean granted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
final Context context = getContext();
if (context == null) return;
if (requestCode == STORAGE_PERM_REQUEST_CODE && granted) {
downloadItem(context);
}
}
private void sendText(final String text, final String itemId, final boolean delete) {
DirectThreadBroadcaster.TextBroadcastOptions textOptions = null;
DirectThreadBroadcaster.ReactionBroadcastOptions reactionOptions = null;

View File

@ -42,7 +42,6 @@ import awais.instagrabber.asyncs.PostFetcher;
import awais.instagrabber.models.BasePostModel;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.PostChild;
import awais.instagrabber.models.direct_messages.DirectItemModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.workers.DownloadWorker;
@ -169,40 +168,28 @@ public final class DownloadUtils {
public static void dmDownload(@NonNull final Context context,
@Nullable final String username,
final DownloadMethod method,
final DirectItemModel.DirectItemMediaModel itemsToDownload) {
if (Utils.settingsHelper == null) Utils.settingsHelper = new SettingsHelper(context);
if (itemsToDownload == null) return;
if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED)
dmDownloadImpl(context, username, method, itemsToDownload);
else if (context instanceof Activity)
final String modelId,
final String url) {
if (url == null) return;
if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
dmDownloadImpl(context, username, modelId, url);
} else if (context instanceof Activity) {
ActivityCompat.requestPermissions((Activity) context, PERMS, 8020);
}
}
private static void dmDownloadImpl(@NonNull final Context context,
@Nullable final String username,
final DownloadMethod method,
final DirectItemModel.DirectItemMediaModel selectedItem) {
File dir = new File(Environment.getExternalStorageDirectory(), "Download");
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH);
if (!TextUtils.isEmpty(customPath)) dir = new File(customPath);
}
if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username))
dir = new File(dir, username);
final String modelId,
final String url) {
final File dir = getDownloadDir(context, username);
if (dir.exists() || dir.mkdirs()) {
new DownloadAsync(context,
selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(),
getDownloadSaveFileDm(dir, selectedItem),
null)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
download(context,
url,
getDownloadSaveFile(dir, modelId, url).getAbsolutePath());
return;
}
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
}
@NonNull
@ -229,14 +216,6 @@ public final class DownloadUtils {
return new File(finalDir, fileName);
}
@NonNull
private static File getDownloadSaveFileDm(final File finalDir,
@NonNull final DirectItemModel.DirectItemMediaModel model) {
final boolean isVideo = model.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO;
final String displayUrl = isVideo ? model.getVideoUrl() : model.getThumbUrl();
return new File(finalDir, model.getId() + getFileExtensionFromUrl(displayUrl));
}
/**
* Copied from {@link MimeTypeMap#getFileExtensionFromUrl(String)})
* <p>

View File

@ -57,13 +57,25 @@ public final class NumberUtils {
@NonNull
public static Pair<Integer, Integer> calculateWidthHeight(final int height, final int width, final int maxHeight, final int maxWidth) {
int tempWidth = width;
int tempHeight = height > maxHeight ? maxHeight : height;
if (tempWidth > maxWidth) {
tempHeight = NumberUtils.getResultingHeight(maxWidth, height, width);
tempWidth = maxWidth;
if (width > maxWidth) {
int tempHeight = getResultingHeight(maxWidth, height, width);
int tempWidth = maxWidth;
if (tempHeight > maxHeight) {
tempWidth = getResultingWidth(maxHeight, tempHeight, tempWidth);
tempHeight = maxHeight;
}
return new Pair<>(tempWidth, tempHeight);
}
return new Pair<>(tempWidth, tempHeight);
if ((height < maxHeight && width < maxWidth) || (height > maxHeight)) {
int tempWidth = getResultingWidth(maxHeight, height, width);
int tempHeight = maxHeight;
if (tempWidth > maxWidth) {
tempHeight = getResultingHeight(maxWidth, tempHeight, tempWidth);
tempWidth = maxWidth;
}
return new Pair<>(tempWidth, tempHeight);
}
return new Pair<>(width, height);
}
public static float roundFloat2Decimals(final float value) {

View File

@ -1,17 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?actionBarSize"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
android:layout_weight="1"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toTopOf="@id/comment_container"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/messageList"
@ -21,8 +25,13 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:id="@+id/comment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swipeRefreshLayout">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
@ -47,9 +56,7 @@
android:maxLength="2200"
android:maxLines="10"
android:paddingStart="8dp"
android:paddingLeft="8dp"
android:paddingEnd="4dp"
android:paddingRight="4dp"
android:scrollHorizontally="false" />
<androidx.appcompat.widget.AppCompatImageView
@ -61,11 +68,9 @@
android:clickable="true"
android:focusable="true"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:paddingBottom="4dp"
app:srcCompat="@drawable/ic_send_24" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.facebook.drawee.view.SimpleDraweeView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ivAnimatedMessage"
android:layout_width="match_parent"
android:layout_height="@dimen/dm_media_img_max_height" />
android:layout_height="@dimen/dm_media_img_max_height"
app:actualImageScaleType="fitXY" />

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
@ -11,7 +12,8 @@
android:layout_height="@dimen/profile_pic_size_regular"
android:layout_gravity="top|start"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp" />
android:layout_marginEnd="4dp"
tools:background="@mipmap/ic_launcher" />
<LinearLayout
android:id="@+id/content_container"
@ -27,8 +29,8 @@
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="?android:textColorPrimary" />
android:textColor="?android:textColorPrimary"
tools:text="@string/app_name" />
<androidx.cardview.widget.CardView
android:id="@+id/messageCard"
@ -37,7 +39,8 @@
android:foreground="?android:selectableItemBackground"
app:cardCornerRadius="@dimen/dm_message_card_radius"
app:cardElevation="2dp"
app:cardUseCompatPadding="true" />
app:cardUseCompatPadding="true"
tools:background="@mipmap/ic_launcher" />
<androidx.cardview.widget.CardView
android:id="@+id/liked_container"

View File

@ -6,10 +6,10 @@
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/ivMediaPreview"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:actualImageScaleType="fitCenter"/>
android:layout_gravity="center"
app:actualImageScaleType="fitXY" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/typeIcon"