From 38bd1c9cbda1262a5d9c56aff874595090dd99d0 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Tue, 30 Mar 2021 22:08:24 +0900 Subject: [PATCH] Refactor giphy and voice options to their own viewholder, fix download when permission requested. --- .../adapters/DirectItemsAdapter.java | 3 +- .../DirectItemAnimatedMediaViewHolder.java | 16 +++++ .../directmessages/DirectItemViewHolder.java | 11 +--- .../DirectItemVoiceMediaViewHolder.java | 9 +++ .../customviews/DirectItemContextMenu.java | 20 ++++++- .../DirectMessageSettingsFragment.java | 2 +- .../DirectMessageThreadFragment.java | 59 +++++++++++-------- 7 files changed, 83 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index e1469ac5..2b1f410e 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; +import java.util.function.Function; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemActionLogViewHolder; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemAnimatedMediaViewHolder; @@ -404,7 +405,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter callback); } public interface DirectItemInternalLongClickListener { diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemAnimatedMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemAnimatedMediaViewHolder.java index c08bb1d9..7bc5d173 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemAnimatedMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemAnimatedMediaViewHolder.java @@ -8,8 +8,13 @@ import androidx.core.util.Pair; import androidx.recyclerview.widget.ItemTouchHelper; import com.facebook.drawee.backends.pipeline.Fresco; +import com.google.common.collect.ImmutableList; +import java.util.List; + +import awais.instagrabber.R; import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; +import awais.instagrabber.customviews.DirectItemContextMenu; import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.repositories.responses.AnimatedMediaFixedHeight; @@ -19,6 +24,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectItemAnimatedMedia; import awais.instagrabber.repositories.responses.directmessages.DirectThread; import awais.instagrabber.utils.NumberUtils; +import awais.instagrabber.utils.Utils; public class DirectItemAnimatedMediaViewHolder extends DirectItemViewHolder { @@ -65,4 +71,14 @@ public class DirectItemAnimatedMediaViewHolder extends DirectItemViewHolder { public int getSwipeDirection() { return ItemTouchHelper.ACTION_STATE_IDLE; } + + @Override + protected List getLongClickOptions() { + return ImmutableList.of( + new DirectItemContextMenu.MenuItem(R.id.detail, R.string.dms_inbox_giphy, item -> { + Utils.openURL(itemView.getContext(), "https://giphy.com/gifs/" + item.getAnimatedMedia().getId()); + return null; + }) + ); + } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java index 15814b3c..96476b10 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java @@ -543,22 +543,13 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple if (thread.getInputMode() != 1 && messageDirection == MessageDirection.OUTGOING) { builder.add(new DirectItemContextMenu.MenuItem(R.id.unsend, R.string.dms_inbox_unsend)); } - final DirectItemType itemType = item.getItemType(); - switch (itemType) { - case ANIMATED_MEDIA: - builder.add(new DirectItemContextMenu.MenuItem(R.id.detail, R.string.dms_inbox_giphy)); - break; - case VOICE_MEDIA: - builder.add(new DirectItemContextMenu.MenuItem(R.id.detail, R.string.action_download)); - break; - } final boolean showReactions = thread.getInputMode() != 1 && allowReaction(); final ImmutableList menuItems = builder.build(); if (!showReactions && menuItems.isEmpty()) return; final DirectItemContextMenu menu = new DirectItemContextMenu(itemView.getContext(), showReactions, menuItems); menu.setOnDismissListener(() -> setSelected(false)); menu.setOnReactionClickListener(emoji -> callback.onReaction(item, emoji)); - menu.setOnOptionSelectListener(itemId -> callback.onOptionSelect(item, itemId)); + menu.setOnOptionSelectListener((itemId, cb) -> callback.onOptionSelect(item, itemId, cb)); menu.show(itemView, location); } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java index 13399b06..255cceae 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java @@ -12,12 +12,14 @@ import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.common.collect.ImmutableList; import com.google.common.primitives.Floats; import java.util.List; import awais.instagrabber.R; import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; +import awais.instagrabber.customviews.DirectItemContextMenu; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; import awais.instagrabber.repositories.responses.Audio; @@ -174,6 +176,13 @@ public class DirectItemVoiceMediaViewHolder extends DirectItemViewHolder { return false; } + @Override + protected List getLongClickOptions() { + return ImmutableList.of( + new DirectItemContextMenu.MenuItem(R.id.download, R.string.action_download) + ); + } + private static class AudioItemState { private boolean prepared; diff --git a/app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java b/app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java index f615b7fc..65a18141 100644 --- a/app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java +++ b/app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java @@ -29,12 +29,14 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.util.Pair; import java.util.List; +import java.util.function.Function; import awais.instagrabber.R; import awais.instagrabber.animations.RoundedRectRevealOutlineProvider; import awais.instagrabber.customviews.emoji.Emoji; import awais.instagrabber.customviews.emoji.ReactionsManager; import awais.instagrabber.databinding.LayoutDirectItemOptionsBinding; +import awais.instagrabber.repositories.responses.directmessages.DirectItem; import static android.view.View.MeasureSpec.makeMeasureSpec; @@ -345,7 +347,7 @@ public class DirectItemContextMenu extends PopupWindow { textView.setText(context.getString(menuItem.getTitleRes())); textView.setOnClickListener(v -> { if (onOptionSelectListener != null) { - onOptionSelectListener.onSelect(menuItem.getItemId()); + onOptionSelectListener.onSelect(menuItem.getItemId(), menuItem.getCallback()); } dismiss(); }); @@ -397,9 +399,19 @@ public class DirectItemContextMenu extends PopupWindow { @StringRes private final int titleRes; + /** + * Callback function + */ + private final Function callback; + public MenuItem(@IdRes final int itemId, @StringRes final int titleRes) { + this(itemId, titleRes, null); + } + + public MenuItem(@IdRes final int itemId, @StringRes final int titleRes, @Nullable final Function callback) { this.itemId = itemId; this.titleRes = titleRes; + this.callback = callback; } public int getItemId() { @@ -409,10 +421,14 @@ public class DirectItemContextMenu extends PopupWindow { public int getTitleRes() { return titleRes; } + + public Function getCallback() { + return callback; + } } public interface OnOptionSelectListener { - void onSelect(int itemId); + void onSelect(int itemId, @Nullable Function callback); } public interface OnReactionClickListener { diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java index fe36cdbf..f98e4094 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java @@ -85,7 +85,7 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi args.getPending(), appStateViewModel.getCurrentUser() ); - viewModel = new ViewModelProvider(fragmentActivity, viewModelFactory).get(DirectSettingsViewModel.class); + viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectSettingsViewModel.class); } @NonNull diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 1c7f3dde..a6b1cb4c 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -58,6 +58,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.function.Function; import awais.instagrabber.ProfileNavGraphDirections; import awais.instagrabber.R; @@ -258,7 +259,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact } @Override - public void onOptionSelect(final DirectItem item, final int itemId) { + public void onOptionSelect(final DirectItem item, final int itemId, final Function cb) { if (itemId == R.id.unsend) { handleSentMessage(viewModel.unsend(item)); return; @@ -275,21 +276,17 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this); navController.navigate(actionGlobalUserSearch); } - if (itemId == R.id.detail) { - final Context context = getContext(); - if (context == null) return; - final DirectItemType itemType = item.getItemType(); - switch (itemType) { - case ANIMATED_MEDIA: - Utils.openURL(context, "https://giphy.com/gifs/" + item.getAnimatedMedia().getId()); - break; - case VOICE_MEDIA: - downloadItem(item.getVoiceMedia() == null ? null : item.getVoiceMedia().getMedia(), context); - break; - } + if (itemId == R.id.download) { + downloadItem(item); + return; + } + // otherwise call callback if present + if (cb != null) { + cb.apply(item); } } }; + private final DirectItemLongClickListener directItemLongClickListener = position -> { // viewModel.setSelectedPosition(position); }; @@ -319,6 +316,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact }; private final MutableLiveData inputLength = new MutableLiveData<>(0); private MenuItem markAsSeenMenuItem; + private Media tempMedia; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { @@ -335,7 +333,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact fragmentArgs.getPending(), appStateViewModel.getCurrentUser() ); - viewModel = new ViewModelProvider(fragmentActivity, viewModelFactory).get(DirectThreadViewModel.class); + viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectThreadViewModel.class); setHasOptionsMenu(true); } @@ -456,7 +454,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact final Context context = getContext(); if (context == null) return; if (requestCode == STORAGE_PERM_REQUEST_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - // downloadItem(context); + if (tempMedia == null) return; + downloadItem(context, tempMedia); + return; } if (requestCode == AUDIO_RECORD_PERM_REQUEST_CODE) { if (PermissionUtils.hasAudioRecordPerms(context)) { @@ -1319,18 +1319,31 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact appExecutors.mainThread().execute(prevTitleRunnable, 1000); } + private void downloadItem(final DirectItem item) { + final Context context = getContext(); + if (context == null) return; + final DirectItemType itemType = item.getItemType(); + //noinspection SwitchStatementWithTooFewBranches + switch (itemType) { + case VOICE_MEDIA: + downloadItem(context, item.getVoiceMedia() == null ? null : item.getVoiceMedia().getMedia()); + break; + } + } + // currently ONLY for voice - private void downloadItem(final Media media, final Context context) { + private void downloadItem(@NonNull final Context context, final Media media) { if (media == 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.download(context, media); - } else { - requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE); - } - Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show(); + return; } + if (ContextCompat.checkSelfPermission(context, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { + DownloadUtils.download(context, media); + Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show(); + return; + } + tempMedia = media; + requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE); } @NonNull