Browse Source

Refactor giphy and voice options to their own viewholder, fix download when permission requested.

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
38bd1c9cbd
  1. 3
      app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java
  2. 16
      app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemAnimatedMediaViewHolder.java
  3. 11
      app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemViewHolder.java
  4. 9
      app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVoiceMediaViewHolder.java
  5. 20
      app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java
  6. 2
      app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java
  7. 51
      app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java

3
app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function;
import awais.instagrabber.adapters.viewholder.directmessages.DirectItemActionLogViewHolder; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemActionLogViewHolder;
import awais.instagrabber.adapters.viewholder.directmessages.DirectItemAnimatedMediaViewHolder; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemAnimatedMediaViewHolder;
@ -404,7 +405,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter<RecyclerView.
void onReactionClick(DirectItem item, int position); void onReactionClick(DirectItem item, int position);
void onOptionSelect(DirectItem item, @IdRes int itemId);
void onOptionSelect(DirectItem item, @IdRes int itemId, final Function<DirectItem, Void> callback);
} }
public interface DirectItemInternalLongClickListener { public interface DirectItemInternalLongClickListener {

16
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 androidx.recyclerview.widget.ItemTouchHelper;
import com.facebook.drawee.backends.pipeline.Fresco; 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.adapters.DirectItemsAdapter.DirectItemCallback;
import awais.instagrabber.customviews.DirectItemContextMenu;
import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding; import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding;
import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.repositories.responses.AnimatedMediaFixedHeight; 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.DirectItemAnimatedMedia;
import awais.instagrabber.repositories.responses.directmessages.DirectThread; import awais.instagrabber.repositories.responses.directmessages.DirectThread;
import awais.instagrabber.utils.NumberUtils; import awais.instagrabber.utils.NumberUtils;
import awais.instagrabber.utils.Utils;
public class DirectItemAnimatedMediaViewHolder extends DirectItemViewHolder { public class DirectItemAnimatedMediaViewHolder extends DirectItemViewHolder {
@ -65,4 +71,14 @@ public class DirectItemAnimatedMediaViewHolder extends DirectItemViewHolder {
public int getSwipeDirection() { public int getSwipeDirection() {
return ItemTouchHelper.ACTION_STATE_IDLE; return ItemTouchHelper.ACTION_STATE_IDLE;
} }
@Override
protected List<DirectItemContextMenu.MenuItem> 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;
})
);
}
} }

11
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) { if (thread.getInputMode() != 1 && messageDirection == MessageDirection.OUTGOING) {
builder.add(new DirectItemContextMenu.MenuItem(R.id.unsend, R.string.dms_inbox_unsend)); 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 boolean showReactions = thread.getInputMode() != 1 && allowReaction();
final ImmutableList<DirectItemContextMenu.MenuItem> menuItems = builder.build(); final ImmutableList<DirectItemContextMenu.MenuItem> menuItems = builder.build();
if (!showReactions && menuItems.isEmpty()) return; if (!showReactions && menuItems.isEmpty()) return;
final DirectItemContextMenu menu = new DirectItemContextMenu(itemView.getContext(), showReactions, menuItems); final DirectItemContextMenu menu = new DirectItemContextMenu(itemView.getContext(), showReactions, menuItems);
menu.setOnDismissListener(() -> setSelected(false)); menu.setOnDismissListener(() -> setSelected(false));
menu.setOnReactionClickListener(emoji -> callback.onReaction(item, emoji)); 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); menu.show(itemView, location);
} }

9
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.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Floats; import com.google.common.primitives.Floats;
import java.util.List; import java.util.List;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback;
import awais.instagrabber.customviews.DirectItemContextMenu;
import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding;
import awais.instagrabber.repositories.responses.Audio; import awais.instagrabber.repositories.responses.Audio;
@ -174,6 +176,13 @@ public class DirectItemVoiceMediaViewHolder extends DirectItemViewHolder {
return false; return false;
} }
@Override
protected List<DirectItemContextMenu.MenuItem> getLongClickOptions() {
return ImmutableList.of(
new DirectItemContextMenu.MenuItem(R.id.download, R.string.action_download)
);
}
private static class AudioItemState { private static class AudioItemState {
private boolean prepared; private boolean prepared;

20
app/src/main/java/awais/instagrabber/customviews/DirectItemContextMenu.java

@ -29,12 +29,14 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.util.Pair; import androidx.core.util.Pair;
import java.util.List; import java.util.List;
import java.util.function.Function;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.animations.RoundedRectRevealOutlineProvider; import awais.instagrabber.animations.RoundedRectRevealOutlineProvider;
import awais.instagrabber.customviews.emoji.Emoji; import awais.instagrabber.customviews.emoji.Emoji;
import awais.instagrabber.customviews.emoji.ReactionsManager; import awais.instagrabber.customviews.emoji.ReactionsManager;
import awais.instagrabber.databinding.LayoutDirectItemOptionsBinding; import awais.instagrabber.databinding.LayoutDirectItemOptionsBinding;
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.MeasureSpec.makeMeasureSpec;
@ -345,7 +347,7 @@ public class DirectItemContextMenu extends PopupWindow {
textView.setText(context.getString(menuItem.getTitleRes())); textView.setText(context.getString(menuItem.getTitleRes()));
textView.setOnClickListener(v -> { textView.setOnClickListener(v -> {
if (onOptionSelectListener != null) { if (onOptionSelectListener != null) {
onOptionSelectListener.onSelect(menuItem.getItemId());
onOptionSelectListener.onSelect(menuItem.getItemId(), menuItem.getCallback());
} }
dismiss(); dismiss();
}); });
@ -397,9 +399,19 @@ public class DirectItemContextMenu extends PopupWindow {
@StringRes @StringRes
private final int titleRes; private final int titleRes;
/**
* Callback function
*/
private final Function<DirectItem, Void> callback;
public MenuItem(@IdRes final int itemId, @StringRes final int titleRes) { 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<DirectItem, Void> callback) {
this.itemId = itemId; this.itemId = itemId;
this.titleRes = titleRes; this.titleRes = titleRes;
this.callback = callback;
} }
public int getItemId() { public int getItemId() {
@ -409,10 +421,14 @@ public class DirectItemContextMenu extends PopupWindow {
public int getTitleRes() { public int getTitleRes() {
return titleRes; return titleRes;
} }
public Function<DirectItem, Void> getCallback() {
return callback;
}
} }
public interface OnOptionSelectListener { public interface OnOptionSelectListener {
void onSelect(int itemId);
void onSelect(int itemId, @Nullable Function<DirectItem, Void> callback);
} }
public interface OnReactionClickListener { public interface OnReactionClickListener {

2
app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java

@ -85,7 +85,7 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi
args.getPending(), args.getPending(),
appStateViewModel.getCurrentUser() appStateViewModel.getCurrentUser()
); );
viewModel = new ViewModelProvider(fragmentActivity, viewModelFactory).get(DirectSettingsViewModel.class);
viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectSettingsViewModel.class);
} }
@NonNull @NonNull

51
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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
import awais.instagrabber.ProfileNavGraphDirections; import awais.instagrabber.ProfileNavGraphDirections;
import awais.instagrabber.R; import awais.instagrabber.R;
@ -258,7 +259,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
} }
@Override @Override
public void onOptionSelect(final DirectItem item, final int itemId) {
public void onOptionSelect(final DirectItem item, final int itemId, final Function<DirectItem, Void> cb) {
if (itemId == R.id.unsend) { if (itemId == R.id.unsend) {
handleSentMessage(viewModel.unsend(item)); handleSentMessage(viewModel.unsend(item));
return; return;
@ -275,21 +276,17 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this); final NavController navController = NavHostFragment.findNavController(DirectMessageThreadFragment.this);
navController.navigate(actionGlobalUserSearch); 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 -> { private final DirectItemLongClickListener directItemLongClickListener = position -> {
// viewModel.setSelectedPosition(position); // viewModel.setSelectedPosition(position);
}; };
@ -319,6 +316,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
}; };
private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0); private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0);
private MenuItem markAsSeenMenuItem; private MenuItem markAsSeenMenuItem;
private Media tempMedia;
@Override @Override
public void onCreate(@Nullable final Bundle savedInstanceState) { public void onCreate(@Nullable final Bundle savedInstanceState) {
@ -335,7 +333,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
fragmentArgs.getPending(), fragmentArgs.getPending(),
appStateViewModel.getCurrentUser() appStateViewModel.getCurrentUser()
); );
viewModel = new ViewModelProvider(fragmentActivity, viewModelFactory).get(DirectThreadViewModel.class);
viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectThreadViewModel.class);
setHasOptionsMenu(true); setHasOptionsMenu(true);
} }
@ -456,7 +454,9 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
final Context context = getContext(); final Context context = getContext();
if (context == null) return; if (context == null) return;
if (requestCode == STORAGE_PERM_REQUEST_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 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 (requestCode == AUDIO_RECORD_PERM_REQUEST_CODE) {
if (PermissionUtils.hasAudioRecordPerms(context)) { if (PermissionUtils.hasAudioRecordPerms(context)) {
@ -1319,18 +1319,31 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
appExecutors.mainThread().execute(prevTitleRunnable, 1000); 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 // 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) { if (media == null) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
} else {
return;
}
if (ContextCompat.checkSelfPermission(context, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(context, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
DownloadUtils.download(context, media); DownloadUtils.download(context, media);
} else {
requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
}
Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show();
return;
} }
tempMedia = media;
requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
} }
@NonNull @NonNull

Loading…
Cancel
Save