From ba10f8b410c465d30a47d8e7d5f3e52ea885c143 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sun, 10 Jan 2021 18:19:27 +0900 Subject: [PATCH] Support opening media, hashtag, location, mentions in direct thread --- .../instagrabber/activities/MainActivity.java | 2 +- .../adapters/DirectItemsAdapter.java | 50 +++++--- .../DirectItemActionLogViewHolder.java | 12 +- .../DirectItemAnimatedMediaViewHolder.java | 7 +- .../DirectItemDefaultViewHolder.java | 9 +- .../DirectItemLikeViewHolder.java | 7 +- .../DirectItemLinkViewHolder.java | 21 ++- .../DirectItemMediaShareViewHolder.java | 105 +++++++++------ .../DirectItemMediaViewHolder.java | 9 +- .../DirectItemPlaceholderViewHolder.java | 9 +- .../DirectItemProfileViewHolder.java | 7 +- .../DirectItemRavenMediaViewHolder.java | 8 +- .../DirectItemReelShareViewHolder.java | 8 +- .../DirectItemStoryShareViewHolder.java | 33 +++-- .../DirectItemTextViewHolder.java | 27 +--- .../DirectItemVideoCallEventViewHolder.java | 7 +- .../directmessages/DirectItemViewHolder.java | 49 ++++++- .../DirectItemVoiceMediaViewHolder.java | 5 +- .../customviews/ChatMessageLayout.java | 2 +- .../fragments/PostViewV2Fragment.java | 80 +++++++++--- .../DirectMessageThreadFragment.java | 120 +++++++----------- .../fragments/main/FeedFragment.java | 3 +- .../repositories/responses/Media.java | 7 + .../instagrabber/utils/DeepLinkParser.java | 67 ++++++++++ .../viewmodels/PostViewV2ViewModel.java | 16 ++- app/src/main/res/layout/dialog_post_view.xml | 59 +++++---- .../fragment_direct_messages_thread.xml | 2 +- .../navigation/direct_messages_nav_graph.xml | 3 +- app/src/main/res/values/strings.xml | 5 + 29 files changed, 465 insertions(+), 274 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/utils/DeepLinkParser.java diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java index eeb721b1..fa022192 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java @@ -686,7 +686,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage R.array.com_google_android_gms_fonts_certs); final EmojiCompat.Config config = new FontRequestEmojiCompatConfig(getApplicationContext(), fontRequest); config.setReplaceAll(true) - .setUseEmojiAsDefaultStyle(true) + // .setUseEmojiAsDefaultStyle(true) .registerInitCallback(new EmojiCompat.InitCallback() { @Override public void onInitialized() { diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index 509794de..3d386857 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -47,6 +47,7 @@ import awais.instagrabber.databinding.LayoutDmStoryShareBinding; import awais.instagrabber.databinding.LayoutDmTextBinding; import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; import awais.instagrabber.models.enums.DirectItemType; +import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectThread; @@ -57,6 +58,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter differ; private List items; @@ -99,9 +101,11 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter(new AdapterListUpdateCallback(this), new AsyncDifferConfig.Builder<>(diffCallback).build()); // this.onClickListener = onClickListener; @@ -128,66 +132,66 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter openURL(linkContext.getLinkUrl()); + binding.preview.setOnClickListener(onClickListener); + binding.title.setOnClickListener(onClickListener); + binding.summary.setOnClickListener(onClickListener); + binding.url.setOnClickListener(onClickListener); } @Override diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java index 168b9fff..72f6144e 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaShareViewHolder.java @@ -13,9 +13,9 @@ import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.generic.RoundingParams; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmMediaShareBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.enums.DirectItemType; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.Caption; @@ -38,9 +38,8 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmMediaShareBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; incomingRoundingParams = RoundingParams.fromCornersRadii(dmRadiusSmall, dmRadius, dmRadius, dmRadius); outgoingRoundingParams = RoundingParams.fromCornersRadii(dmRadius, dmRadiusSmall, dmRadius, dmRadius); @@ -59,36 +58,36 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder { : R.drawable.bg_media_share_top_outgoing); Media media = getMedia(item); if (media == null) return; - final User user = media.getUser(); - if (user != null) { - binding.username.setVisibility(View.VISIBLE); - binding.profilePic.setVisibility(View.VISIBLE); - binding.username.setText(user.getUsername()); - binding.profilePic.setImageURI(user.getProfilePicUrl()); + itemView.post(() -> { + setupUser(media); + setupTitle(media); + setupCaption(media); + }); + itemView.post(() -> { + final MediaItemType mediaType = media.getMediaType(); + setupTypeIndicator(mediaType); + if (mediaType == MediaItemType.MEDIA_TYPE_SLIDER) { + setupPreview(media.getCarouselMedia().get(0)); + return; + } + setupPreview(media); + }); + itemView.setOnClickListener(v -> openMedia(media)); + } + + private void setupTypeIndicator(final MediaItemType mediaType) { + final boolean showTypeIcon = mediaType == MediaItemType.MEDIA_TYPE_VIDEO || mediaType == MediaItemType.MEDIA_TYPE_SLIDER; + if (!showTypeIcon) { + binding.typeIcon.setVisibility(View.GONE); } else { - binding.username.setVisibility(View.GONE); - binding.profilePic.setVisibility(View.GONE); - } - final String title = media.getTitle(); - if (!TextUtils.isEmpty(title)) { - binding.title.setVisibility(View.VISIBLE); - binding.title.setText(title); - } else { - binding.title.setVisibility(View.GONE); - } - final Caption caption = media.getCaption(); - if (caption != null) { - binding.caption.setVisibility(View.VISIBLE); - binding.caption.setText(caption.getText()); - binding.caption.setEllipsize(TextUtils.TruncateAt.END); - binding.caption.setMaxLines(2); - } else { - binding.caption.setVisibility(View.GONE); - } - final MediaItemType mediaType = media.getMediaType(); - if (mediaType == MediaItemType.MEDIA_TYPE_SLIDER) { - media = media.getCarouselMedia().get(0); + binding.typeIcon.setVisibility(View.VISIBLE); + binding.typeIcon.setImageResource(mediaType == MediaItemType.MEDIA_TYPE_VIDEO + ? R.drawable.ic_video_24 + : R.drawable.ic_checkbox_multiple_blank_stroke); } + } + + private void setupPreview(@NonNull final Media media) { final Pair widthHeight = NumberUtils.calculateWidthHeight( media.getOriginalHeight(), media.getOriginalWidth(), @@ -101,15 +100,41 @@ public class DirectItemMediaShareViewHolder extends DirectItemViewHolder { binding.mediaPreview.requestLayout(); final String url = ResponseBodyUtils.getThumbUrl(media.getImageVersions2()); binding.mediaPreview.setImageURI(url); - final boolean showTypeIcon = mediaType == MediaItemType.MEDIA_TYPE_VIDEO || mediaType == MediaItemType.MEDIA_TYPE_SLIDER; - if (!showTypeIcon) { - binding.typeIcon.setVisibility(View.GONE); - return; + } + + private void setupCaption(@NonNull final Media media) { + final Caption caption = media.getCaption(); + if (caption != null) { + binding.caption.setVisibility(View.VISIBLE); + binding.caption.setText(caption.getText()); + binding.caption.setEllipsize(TextUtils.TruncateAt.END); + binding.caption.setMaxLines(2); + } else { + binding.caption.setVisibility(View.GONE); + } + } + + private void setupTitle(@NonNull final Media media) { + final String title = media.getTitle(); + if (!TextUtils.isEmpty(title)) { + binding.title.setVisibility(View.VISIBLE); + binding.title.setText(title); + } else { + binding.title.setVisibility(View.GONE); + } + } + + private void setupUser(@NonNull final Media media) { + final User user = media.getUser(); + if (user != null) { + binding.username.setVisibility(View.VISIBLE); + binding.profilePic.setVisibility(View.VISIBLE); + binding.username.setText(user.getUsername()); + binding.profilePic.setImageURI(user.getProfilePicUrl()); + } else { + binding.username.setVisibility(View.GONE); + binding.profilePic.setVisibility(View.GONE); } - binding.typeIcon.setVisibility(View.VISIBLE); - binding.typeIcon.setImageResource(mediaType == MediaItemType.MEDIA_TYPE_VIDEO - ? R.drawable.ic_video_24 - : R.drawable.ic_checkbox_multiple_blank_stroke); } @Nullable diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java index ddf9ef94..cb32f0f1 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemMediaViewHolder.java @@ -10,9 +10,9 @@ import com.facebook.drawee.drawable.ScalingUtils; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.generic.RoundingParams; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmMediaBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.ImageVersions2; import awais.instagrabber.repositories.responses.Media; @@ -32,9 +32,8 @@ public class DirectItemMediaViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmMediaBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; incomingRoundingParams = RoundingParams.fromCornersRadii(dmRadiusSmall, dmRadius, dmRadius, dmRadius); outgoingRoundingParams = RoundingParams.fromCornersRadii(dmRadius, dmRadiusSmall, dmRadius, dmRadius); @@ -49,6 +48,7 @@ public class DirectItemMediaViewHolder extends DirectItemViewHolder { .setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP) .build()); final Media media = directItemModel.getMedia(); + itemView.setOnClickListener(v -> openMedia(media)); final MediaItemType modelMediaType = media.getMediaType(); binding.typeIcon.setVisibility(modelMediaType == MediaItemType.MEDIA_TYPE_VIDEO || modelMediaType == MediaItemType.MEDIA_TYPE_SLIDER ? View.VISIBLE @@ -71,4 +71,5 @@ public class DirectItemMediaViewHolder extends DirectItemViewHolder { final String thumbUrl = ResponseBodyUtils.getThumbUrl(imageVersions2); binding.mediaPreview.setImageURI(thumbUrl); } + } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemPlaceholderViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemPlaceholderViewHolder.java index 7c7da9ff..d4bf903b 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemPlaceholderViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemPlaceholderViewHolder.java @@ -1,12 +1,10 @@ package awais.instagrabber.adapters.viewholder.directmessages; -import android.view.View; - import androidx.annotation.NonNull; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmTextBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectThread; @@ -19,9 +17,8 @@ public class DirectItemPlaceholderViewHolder extends DirectItemViewHolder { final LayoutDmTextBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; setItemView(binding.getRoot()); } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemProfileViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemProfileViewHolder.java index 4d5c3705..39dc2cae 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemProfileViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemProfileViewHolder.java @@ -13,6 +13,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmProfileBinding; import awais.instagrabber.models.enums.DirectItemType; @@ -34,8 +35,8 @@ public class DirectItemProfileViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmProfileBinding binding, final User currentUser, final DirectThread thread, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; setItemView(binding.getRoot()); previewViews = ImmutableList.of( @@ -98,6 +99,7 @@ public class DirectItemProfileViewHolder extends DirectItemViewHolder { binding.username.setText(profile.getUsername()); binding.fullName.setText(profile.getFullName()); binding.isVerified.setVisibility(profile.isVerified() ? View.VISIBLE : View.GONE); + itemView.setOnClickListener(v -> openProfile(profile.getUsername())); } private void setLocation(@NonNull final DirectItem item) { @@ -113,5 +115,6 @@ public class DirectItemProfileViewHolder extends DirectItemViewHolder { binding.fullName.setVisibility(View.GONE); } binding.isVerified.setVisibility(View.GONE); + itemView.setOnClickListener(v -> openLocation(location.getPk())); } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java index c3efb38a..b20077ba 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemRavenMediaViewHolder.java @@ -10,6 +10,7 @@ import com.facebook.drawee.drawable.ScalingUtils; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.generic.RoundingParams; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmRavenMediaBinding; import awais.instagrabber.models.enums.MediaItemType; @@ -32,8 +33,8 @@ public class DirectItemRavenMediaViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmRavenMediaBinding binding, final User currentUser, final DirectThread thread, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; maxWidth = windowWidth - margin - dmRadiusSmall; setItemView(binding.getRoot()); @@ -46,6 +47,9 @@ public class DirectItemRavenMediaViewHolder extends DirectItemViewHolder { if (media == null) return; setExpiryInfo(visualMedia); setPreview(visualMedia, messageDirection); + final boolean expired = media.getPk() == null; + if (expired) return; + itemView.setOnClickListener(v -> openMedia(media)); /*final boolean isExpired = visualMedia == null || (mediaModel = visualMedia.getMedia()) == null || TextUtils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1; diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java index 3782f028..80fbce8e 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemReelShareViewHolder.java @@ -10,9 +10,9 @@ import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.generic.RoundingParams; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmReelShareBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.ImageVersions2; import awais.instagrabber.repositories.responses.Media; @@ -31,9 +31,8 @@ public class DirectItemReelShareViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmReelShareBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; setItemView(binding.getRoot()); } @@ -72,6 +71,7 @@ public class DirectItemReelShareViewHolder extends DirectItemViewHolder { } if (!expired) { setPreview(media); + itemView.setOnClickListener(v -> openMedia(media)); } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemStoryShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemStoryShareViewHolder.java index cddae1d2..6faa7684 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemStoryShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemStoryShareViewHolder.java @@ -10,9 +10,9 @@ import com.facebook.drawee.drawable.ScalingUtils; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.generic.RoundingParams; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmStoryShareBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.ImageVersions2; import awais.instagrabber.repositories.responses.Media; @@ -27,17 +27,14 @@ import awais.instagrabber.utils.TextUtils; public class DirectItemStoryShareViewHolder extends DirectItemViewHolder { private final LayoutDmStoryShareBinding binding; - // private final int maxWidth; public DirectItemStoryShareViewHolder(@NonNull final LayoutDmBaseBinding baseBinding, @NonNull final LayoutDmStoryShareBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; - // maxWidth = windowWidth - margin - dmRadiusSmall; setItemView(binding.getRoot()); } @@ -58,13 +55,13 @@ public class DirectItemStoryShareViewHolder extends DirectItemViewHolder { binding.ivMediaPreview.setController(null); final DirectItemStoryShare storyShare = item.getStoryShare(); if (storyShare == null) return; - final String text = storyShare.getText(); - if (!TextUtils.isEmpty(text)) { - binding.text.setText(text); - binding.text.setVisibility(View.VISIBLE); - return; - } - final Media storyShareMedia = storyShare.getMedia(); + setText(storyShare); + final Media media = storyShare.getMedia(); + setupPreview(messageDirection, media); + itemView.setOnClickListener(v -> openMedia(media)); + } + + private void setupPreview(final MessageDirection messageDirection, final Media storyShareMedia) { final MediaItemType mediaType = storyShareMedia.getMediaType(); binding.typeIcon.setVisibility(mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? View.VISIBLE : View.GONE); final RoundingParams roundingParams = messageDirection == MessageDirection.INCOMING @@ -90,6 +87,16 @@ public class DirectItemStoryShareViewHolder extends DirectItemViewHolder { binding.ivMediaPreview.setImageURI(thumbUrl); } + private void setText(final DirectItemStoryShare storyShare) { + final String text = storyShare.getText(); + if (!TextUtils.isEmpty(text)) { + binding.text.setText(text); + binding.text.setVisibility(View.VISIBLE); + return; + } + binding.text.setVisibility(View.GONE); + } + private void setExpiredStoryInfo(final DirectItem item) { binding.shareInfo.setText(item.getStoryShare().getTitle()); binding.text.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemTextViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemTextViewHolder.java index 3c96e9da..b0eaa779 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemTextViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemTextViewHolder.java @@ -1,9 +1,8 @@ package awais.instagrabber.adapters.viewholder.directmessages; -import android.view.View; - import androidx.annotation.NonNull; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmTextBinding; import awais.instagrabber.repositories.responses.User; @@ -18,8 +17,8 @@ public class DirectItemTextViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmTextBinding binding, final User currentUser, final DirectThread thread, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + @NonNull final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; setItemView(binding.getRoot()); } @@ -29,29 +28,11 @@ public class DirectItemTextViewHolder extends DirectItemViewHolder { final String text = directItemModel.getText(); if (text == null) return; binding.tvMessage.setText(text); - // setupListeners(); + setupRamboTextListeners(binding.tvMessage); } @Override protected boolean showBackground() { return true; } - - // private void setupListeners() { - // binding.tvMessage.addOnHashtagListener(autoLinkItem -> { - // final String hashtag = autoLinkItem.getOriginalText().trim(); - // }); - // binding.tvMessage.addOnMentionClickListener(autoLinkItem -> { - // final String mention = autoLinkItem.getOriginalText().trim(); - // }); - // binding.tvMessage.addOnEmailClickListener(autoLinkItem -> { - // final String email = autoLinkItem.getOriginalText().trim(); - // }); - // binding.tvMessage.addOnURLClickListener(autoLinkItem -> { - // final String url = autoLinkItem.getOriginalText().trim(); - // }); - // binding.tvMessage.setOnLongClickListener(v -> { - // return true; - // }); - // } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVideoCallEventViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVideoCallEventViewHolder.java index f8d1c9f6..1c316d1a 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVideoCallEventViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemVideoCallEventViewHolder.java @@ -11,9 +11,9 @@ import androidx.annotation.NonNull; import java.util.List; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmActionLogBinding; import awais.instagrabber.databinding.LayoutDmBaseBinding; -import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectItemActionLog; @@ -29,9 +29,8 @@ public class DirectItemVideoCallEventViewHolder extends DirectItemViewHolder { final LayoutDmActionLogBinding binding, final User currentUser, final DirectThread thread, - final MentionClickListener mentionClickListener, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; setItemView(binding.getRoot()); } 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 1620115d..9eb223ca 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 @@ -19,6 +19,8 @@ import java.util.Locale; import java.util.stream.Collectors; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; +import awais.instagrabber.customviews.RamboTextViewV2; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.models.enums.DirectItemType; import awais.instagrabber.models.enums.MediaItemType; @@ -28,6 +30,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectItemEmojiReaction; import awais.instagrabber.repositories.responses.directmessages.DirectItemReactions; import awais.instagrabber.repositories.responses.directmessages.DirectThread; +import awais.instagrabber.utils.DeepLinkParser; import awais.instagrabber.utils.ResponseBodyUtils; public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder { @@ -36,12 +39,14 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder { private final LayoutDmBaseBinding binding; private final User currentUser; private final DirectThread thread; + private final int groupMessageWidth; + private final List userIds; + private final DirectItemCallback callback; + protected final int margin; protected final int dmRadius; protected final int dmRadiusSmall; protected final int messageInfoPaddingSmall; - private final int groupMessageWidth; - private final List userIds; protected final int mediaImageMaxHeight; protected final int windowWidth; protected final int mediaImageMaxWidth; @@ -49,18 +54,18 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder { public DirectItemViewHolder(@NonNull final LayoutDmBaseBinding binding, @NonNull final User currentUser, @NonNull final DirectThread thread, - @NonNull final View.OnClickListener onClickListener) { + @NonNull final DirectItemCallback callback) { super(binding.getRoot()); this.binding = binding; this.currentUser = currentUser; this.thread = thread; + this.callback = callback; userIds = thread.getUsers() .stream() .map(User::getPk) .collect(Collectors.toList()); binding.ivProfilePic.setVisibility(thread.isGroup() ? View.VISIBLE : View.GONE); - binding.ivProfilePic.setOnClickListener(thread.isGroup() ? onClickListener : null); - // binding.messageCard.setOnClickListener(onClickListener); + binding.ivProfilePic.setOnClickListener(null); final Resources resources = itemView.getResources(); margin = resources.getDimensionPixelSize(R.dimen.dm_message_item_margin); final int avatarSize = resources.getDimensionPixelSize(R.dimen.dm_message_item_avatar_size); @@ -366,6 +371,40 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder { public void cleanup() {} + protected void setupRamboTextListeners(@NonNull final RamboTextViewV2 textView) { + textView.addOnHashtagListener(autoLinkItem -> callback.onHashtagClick(autoLinkItem.getOriginalText().trim())); + textView.addOnMentionClickListener(autoLinkItem -> openProfile(autoLinkItem.getOriginalText().trim())); + textView.addOnEmailClickListener(autoLinkItem -> callback.onEmailClick(autoLinkItem.getOriginalText().trim())); + textView.addOnURLClickListener(autoLinkItem -> openURL(autoLinkItem.getOriginalText().trim())); + } + + protected void openProfile(final String username) { + callback.onMentionClick(username); + } + + protected void openLocation(final long locationId) { + callback.onLocationClick(locationId); + } + + protected void openURL(final String url) { + callback.onURLClick(url); + } + + protected void openMedia(final Media media) { + callback.onMediaClick(media); + } + + protected void handleDeepLink(final String deepLinkText) { + if (deepLinkText == null) return; + final DeepLinkParser.DeepLink deepLink = DeepLinkParser.parse(deepLinkText); + if (deepLink == null) return; + switch (deepLink.getType()) { + case USER: + callback.onMentionClick(deepLink.getValue()); + break; + } + } + public enum MessageDirection { INCOMING, OUTGOING 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 c9268a67..b26bfa90 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 @@ -17,6 +17,7 @@ import com.google.common.primitives.Floats; import java.util.List; import awais.instagrabber.R; +import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; import awais.instagrabber.repositories.responses.Audio; @@ -43,8 +44,8 @@ public class DirectItemVoiceMediaViewHolder extends DirectItemViewHolder { @NonNull final LayoutDmVoiceMediaBinding binding, final User currentUser, final DirectThread thread, - final View.OnClickListener onClickListener) { - super(baseBinding, currentUser, thread, onClickListener); + final DirectItemCallback callback) { + super(baseBinding, currentUser, thread, callback); this.binding = binding; this.dataSourceFactory = new DefaultDataSourceFactory(binding.getRoot().getContext(), "instagram"); setItemView(binding.getRoot()); diff --git a/app/src/main/java/awais/instagrabber/customviews/ChatMessageLayout.java b/app/src/main/java/awais/instagrabber/customviews/ChatMessageLayout.java index 629917e1..26cb242a 100644 --- a/app/src/main/java/awais/instagrabber/customviews/ChatMessageLayout.java +++ b/app/src/main/java/awais/instagrabber/customviews/ChatMessageLayout.java @@ -93,7 +93,7 @@ public class ChatMessageLayout extends FrameLayout { widthSize += viewPartMainWidth; heightSize += viewPartMainHeight; } else if (firstChildId == R.id.raven_media_container || firstChildId == R.id.profile_container || firstChildId == R.id.voice_media - || firstChildId == R.id.story_container || firstChildId == R.id.media_share_container) { + || firstChildId == R.id.story_container || firstChildId == R.id.media_share_container || firstChildId == R.id.link_container) { widthSize += viewPartMainWidth; heightSize += viewPartMainHeight + viewPartInfoHeight; } else { diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java index 46b38e04..60a3b8f6 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java @@ -442,12 +442,16 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im setProfilePicSharedElement(); setupCaptionBottomSheet(); setupCommonActions(); - setupShare(); setObservers(); } private void setObservers() { viewModel.getUser().observe(getViewLifecycleOwner(), user -> { + if (user == null) { + binding.userDetailsGroup.setVisibility(View.GONE); + return; + } + binding.userDetailsGroup.setVisibility(View.VISIBLE); binding.getRoot().post(() -> setupProfilePic(user)); binding.getRoot().post(() -> setupTitles(user)); }); @@ -461,15 +465,27 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im binding.date.setVisibility(View.VISIBLE); binding.date.setText(date); })); - viewModel.getLikeCount().observe(getViewLifecycleOwner(), count -> { + if (viewModel.getMedia().isCommentLikesEnabled()) { + viewModel.getLikeCount().observe(getViewLifecycleOwner(), count -> { + final long safeCount = getSafeCount(count); + final String likesString = getResources().getQuantityString(R.plurals.likes_count, (int) safeCount, safeCount); + binding.likesCount.setText(likesString); + }); + viewModel.getCommentCount().observe(getViewLifecycleOwner(), count -> { + final long safeCount = getSafeCount(count); + final String likesString = getResources().getQuantityString(R.plurals.comments_count, (int) safeCount, safeCount); + binding.likesCount.setText(likesString); + }); + } + viewModel.getViewCount().observe(getViewLifecycleOwner(), count -> { + if (count == null) { + binding.viewsCount.setVisibility(View.GONE); + return; + } + binding.viewsCount.setVisibility(View.VISIBLE); final long safeCount = getSafeCount(count); - final String likesString = getResources().getQuantityString(R.plurals.likes_count, (int) safeCount, safeCount); - binding.likesCount.setText(likesString); - }); - viewModel.getCommentCount().observe(getViewLifecycleOwner(), count -> { - final long safeCount = getSafeCount(count); - final String likesString = getResources().getQuantityString(R.plurals.comments_count, (int) safeCount, safeCount); - binding.likesCount.setText(likesString); + final String viewString = getResources().getQuantityString(R.plurals.views_count, (int) safeCount, safeCount); + binding.viewsCount.setText(viewString); }); viewModel.getType().observe(getViewLifecycleOwner(), this::setupPostTypeLayout); viewModel.getLiked().observe(getViewLifecycleOwner(), this::setLikedResources); @@ -518,9 +534,16 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im setupSave(); setupDownload(); setupComment(); + setupShare(); } private void setupComment() { + if (!viewModel.hasPk() || !viewModel.getMedia().isCommentLikesEnabled()) { + binding.comment.setVisibility(View.GONE); + binding.commentsCount.setVisibility(View.GONE); + return; + } + binding.comment.setVisibility(View.VISIBLE); binding.comment.setOnClickListener(v -> { final Media media = viewModel.getMedia(); final User user = media.getUser(); @@ -554,6 +577,12 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } private void setupLike() { + final boolean likableMedia = viewModel.hasPk() && viewModel.getMedia().isCommentLikesEnabled(); + if (!likableMedia) { + binding.like.setVisibility(View.GONE); + binding.likesCount.setVisibility(View.GONE); + return; + } if (!viewModel.isLoggedIn()) { binding.like.setVisibility(View.GONE); return; @@ -626,7 +655,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } private void setupSave() { - if (!viewModel.isLoggedIn()) { + if (!viewModel.isLoggedIn() || !viewModel.hasPk() || !viewModel.getMedia().canViewerSave()) { binding.save.setVisibility(View.GONE); return; } @@ -854,6 +883,11 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } private void setupShare() { + if (!viewModel.hasPk()) { + binding.share.setVisibility(View.GONE); + return; + } + binding.share.setVisibility(View.VISIBLE); binding.share.setOnLongClickListener(v -> { Utils.displayToastAboveView(context, v, getString(R.string.share)); return true; @@ -1017,7 +1051,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im sliderPosition = position; final String text = (position + 1) + "/" + size; binding.mediaCounter.setText(text); - final Media postChild = media.getCarouselMedia().get(position); + final Media childMedia = media.getCarouselMedia().get(position); final View view = binding.sliderParent.getChildAt(0); if (prevPosition != -1) { if (view instanceof RecyclerView) { @@ -1027,7 +1061,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } } } - if (postChild.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO) { + if (childMedia.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO) { if (view instanceof RecyclerView) { final RecyclerView.ViewHolder viewHolder = ((RecyclerView) view).findViewHolderForAdapterPosition(position); if (viewHolder instanceof SliderVideoViewHolder) { @@ -1035,8 +1069,10 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } } enablePlayerControls(true); + viewModel.setViewCount(childMedia.getViewCount()); return; } + viewModel.setViewCount(null); enablePlayerControls(false); } @@ -1325,10 +1361,12 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im TransitionManager.beginDelayedTransition(binding.getRoot()); if (detailsVisible) { detailsVisible = false; - binding.profilePic.setVisibility(View.GONE); - binding.title.setVisibility(View.GONE); - binding.subtitle.setVisibility(View.GONE); - binding.topBg.setVisibility(View.GONE); + if (media.getUser() != null) { + binding.profilePic.setVisibility(View.GONE); + binding.title.setVisibility(View.GONE); + binding.subtitle.setVisibility(View.GONE); + binding.topBg.setVisibility(View.GONE); + } if (media.getLocation() != null) { binding.location.setVisibility(View.GONE); } @@ -1355,10 +1393,12 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im } return; } - binding.profilePic.setVisibility(View.VISIBLE); - binding.title.setVisibility(View.VISIBLE); - binding.subtitle.setVisibility(View.VISIBLE); - binding.topBg.setVisibility(View.VISIBLE); + if (media.getUser() != null) { + binding.profilePic.setVisibility(View.VISIBLE); + binding.title.setVisibility(View.VISIBLE); + binding.subtitle.setVisibility(View.VISIBLE); + binding.topBg.setVisibility(View.VISIBLE); + } if (media.getLocation() != null) { binding.location.setVisibility(View.VISIBLE); } 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 8f68b927..ac2a0fe6 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -68,7 +68,9 @@ import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge; import awais.instagrabber.customviews.helpers.TextWatcherAdapter; import awais.instagrabber.databinding.FragmentDirectMessagesThreadBinding; import awais.instagrabber.dialogs.MediaPickerBottomDialogFragment; +import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.models.Resource; +import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.directmessages.DirectItem; import awais.instagrabber.repositories.responses.directmessages.DirectThread; @@ -96,11 +98,9 @@ public class DirectMessageThreadFragment extends Fragment { private DirectItemsAdapter itemsAdapter; private MainActivity fragmentActivity; private DirectThreadViewModel viewModel; - public static boolean hasSentSomething; private ConstraintLayout root; private boolean shouldRefresh = true; private List itemOrHeaders; - private MenuItem markAsSeenMenuItem; private FragmentDirectMessagesThreadBinding binding; private Tooltip tooltip; private float initialSendX; @@ -116,75 +116,6 @@ public class DirectMessageThreadFragment extends Fragment { private boolean wasKbShowing; private int keyboardHeight = Utils.convertDpToPx(250); - // private final View.OnClickListener clickListener = v -> { - // if (v == binding.commentSend) { - // final String text = binding.commentText.getText().toString(); - // if (TextUtils.isEmpty(text)) { - // final Context context = getContext(); - // if (context == null) return; - // Toast.makeText(context, R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show(); - // return; - // } - // sendText(text, null, false); - // return; - // } - // if (v == binding.image) { - // final Intent intent = new Intent(); - // intent.setType("image/*"); - // intent.setAction(Intent.ACTION_GET_CONTENT); - // startActivityForResult(Intent.createChooser(intent, getString(R.string.select_picture)), PICK_IMAGE); - // } - // }; - // private final FetchListener fetchListener = new FetchListener() { - // @Override - // public void doBefore() { - // setTitle(true);g - // } - // - // @Override - // public void onResult(final InboxThreadModel result) { - // if (result == null && ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor) || TextUtils.isEmpty(cursor))) { - // final Context context = getContext(); - // if (context == null) return; - // Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); - // } - // - // if (result != null) { - // cursor = result.getOldestCursor(); - // hasOlder = result.hasOlder(); - // if ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor)) { - // cursor = null; - // } - // users.clear(); - // users.addAll(result.getUsers()); - // leftUsers.clear(); - // leftUsers.addAll(result.getLeftUsers()); - // - // List list = listViewModel.getList().getValue(); - // final List newList = result.getItems(); - // list = list != null ? new LinkedList<>(list) : new LinkedList<>(); - // if (hasSentSomething || hasDeletedSomething) { - // list = newList; - // final Handler handler = new Handler(); - // if (hasSentSomething) handler.postDelayed(() -> { - // binding.messageList.smoothScrollToPosition(0); - // }, 200); - // hasSentSomething = false; - // hasDeletedSomething = false; - // } else { - // list.addAll(newList); - // } - // listViewModel.getList().postValue(list); - // lastMessage = result.getNewestCursor(); - // - // // if (Utils.settingsHelper.getBoolean(Constants.DM_MARK_AS_SEEN)) new ThreadAction().execute("seen", lastMessage); - // } - // setTitle(false); - // } - // }; - // private DirectItemMediaModel downloadMediaItem; - // private int prevSizeChangeHeight; - // private ArrayAdapter dialogAdapter; private final AppExecutors appExecutors = AppExecutors.getInstance(); private final Animatable2Compat.AnimationCallback micToSendAnimationCallback = new Animatable2Compat.AnimationCallback() { @Override @@ -200,7 +131,46 @@ public class DirectMessageThreadFragment extends Fragment { setMicToSendIcon(); } }; + private final DirectItemsAdapter.DirectItemCallback directItemCallback = new DirectItemsAdapter.DirectItemCallback() { + @Override + public void onHashtagClick(final String hashtag) { + final NavDirections action = DirectMessageThreadFragmentDirections.actionGlobalHashTagFragment(hashtag); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + } + @Override + public void onMentionClick(final String mention) { + final Bundle bundle = new Bundle(); + bundle.putString("username", "@" + mention); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(R.id.action_global_profileFragment, bundle); + } + + @Override + public void onLocationClick(final long locationId) { + final NavDirections action = DirectMessageThreadFragmentDirections.actionGlobalLocationFragment(locationId); + NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); + } + + @Override + public void onURLClick(final String url) { + final Context context = getContext(); + if (context == null) return; + Utils.openURL(context, url); + } + + @Override + public void onEmailClick(final String email) { + final Context context = getContext(); + if (context == null) return; + Utils.openEmailAddress(context, email); + } + + @Override + public void onMediaClick(final Media media) { + final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(media); + builder.build().show(getChildFragmentManager(), "post_view"); + } + }; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { @@ -243,7 +213,7 @@ public class DirectMessageThreadFragment extends Fragment { @Override public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) { inflater.inflate(R.menu.dm_thread_menu, menu); - markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen); + final MenuItem markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen); if (markAsSeenMenuItem != null) { markAsSeenMenuItem.setVisible(false); } @@ -253,7 +223,8 @@ public class DirectMessageThreadFragment extends Fragment { public boolean onOptionsItemSelected(@NonNull final MenuItem item) { final int itemId = item.getItemId(); if (itemId == R.id.info) { - final NavDirections action = DirectMessageThreadFragmentDirections.actionDMThreadFragmentToDMSettingsFragment(viewModel.getThreadId(), null); + final NavDirections action = DirectMessageThreadFragmentDirections + .actionDMThreadFragmentToDMSettingsFragment(viewModel.getThreadId(), null); NavHostFragment.findNavController(this).navigate(action); return true; } @@ -379,7 +350,6 @@ public class DirectMessageThreadFragment extends Fragment { .findFirst() : Optional.empty(); if (first.isPresent()) { - // setTitle(UPDATING_TITLE); final DirectThread thread = first.get(); viewModel.setThread(thread); return; @@ -590,7 +560,7 @@ public class DirectMessageThreadFragment extends Fragment { itemsAdapter.setThread(thread); return; } - itemsAdapter = new DirectItemsAdapter(currentUser, thread); + itemsAdapter = new DirectItemsAdapter(currentUser, thread, directItemCallback); itemsAdapter.setHasStableIds(true); itemsAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); binding.chats.setAdapter(itemsAdapter); diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index 197e4a46..b9c6d465 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -169,8 +169,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre final View profilePicView, final View mainPostImage, final int position) { - final PostViewV2Fragment.Builder builder = PostViewV2Fragment - .builder(feedModel); + final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(feedModel); if (position >= 0) { builder.setPosition(position); } diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/Media.java b/app/src/main/java/awais/instagrabber/repositories/responses/Media.java index a3c7bf12..6667fd1e 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/Media.java +++ b/app/src/main/java/awais/instagrabber/repositories/responses/Media.java @@ -1,5 +1,7 @@ package awais.instagrabber.repositories.responses; +import androidx.annotation.Nullable; + import java.io.Serializable; import java.util.Date; import java.util.List; @@ -123,6 +125,7 @@ public class Media implements Serializable { return takenAt; } + @Nullable public User getUser() { return user; } @@ -231,7 +234,11 @@ public class Media implements Serializable { return injected != null; } + @Nullable public String getDate() { + if (takenAt <= 0) { + return null; + } if (dateString == null) { dateString = Utils.datetimeParser.format(new Date(takenAt * 1000L)); } diff --git a/app/src/main/java/awais/instagrabber/utils/DeepLinkParser.java b/app/src/main/java/awais/instagrabber/utils/DeepLinkParser.java new file mode 100644 index 00000000..0ef240e4 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/DeepLinkParser.java @@ -0,0 +1,67 @@ +package awais.instagrabber.utils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; +import java.util.regex.Pattern; + +public final class DeepLinkParser { + private static final Map TYPE_PATTERN_MAP = ImmutableMap + .builder() + .put(DeepLink.Type.USER, new DeepLinkPattern("instagram://user?username=")) + .build(); + + @Nullable + public static DeepLink parse(@NonNull final String text) { + for (final Map.Entry entry : TYPE_PATTERN_MAP.entrySet()) { + if (text.startsWith(entry.getValue().getPatternText())) { + final String value = entry.getValue().getPattern().matcher(text).replaceAll(""); + return new DeepLink(entry.getKey(), value); + } + } + return null; + } + + public static class DeepLinkPattern { + private final String patternText; + private final Pattern pattern; + + public DeepLinkPattern(final String patternText) { + this.patternText = patternText; + pattern = Pattern.compile(patternText, Pattern.LITERAL); + } + + public String getPatternText() { + return patternText; + } + + public Pattern getPattern() { + return pattern; + } + } + + public static class DeepLink { + private final Type type; + private final String value; + + public DeepLink(final Type type, final String value) { + this.type = type; + this.value = value; + } + + public Type getType() { + return type; + } + + public String getValue() { + return value; + } + + public enum Type { + USER, + } + } +} diff --git a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.java index 865043fc..4575a344 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.java @@ -36,6 +36,7 @@ public class PostViewV2ViewModel extends ViewModel { private final MutableLiveData date = new MutableLiveData<>(); private final MutableLiveData likeCount = new MutableLiveData<>(0L); private final MutableLiveData commentCount = new MutableLiveData<>(0L); + private final MutableLiveData viewCount = new MutableLiveData<>(0L); private final MutableLiveData type = new MutableLiveData<>(); private final MutableLiveData liked = new MutableLiveData<>(false); private final MutableLiveData saved = new MutableLiveData<>(false); @@ -63,6 +64,7 @@ public class PostViewV2ViewModel extends ViewModel { date.postValue(media.getDate()); likeCount.postValue(media.getLikeCount()); commentCount.postValue(media.getCommentCount()); + viewCount.postValue(media.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? media.getViewCount() : null); type.postValue(media.getMediaType()); liked.postValue(media.hasLiked()); saved.postValue(media.hasViewerSaved()); @@ -71,7 +73,7 @@ public class PostViewV2ViewModel extends ViewModel { private void initOptions() { final ImmutableList.Builder builder = ImmutableList.builder(); - if (isLoggedIn && media.getUser().getPk() == viewerId) { + if (isLoggedIn && media.getUser() != null && media.getUser().getPk() == viewerId) { builder.add(R.id.edit_caption); } options.postValue(builder.build()); @@ -109,6 +111,10 @@ public class PostViewV2ViewModel extends ViewModel { return commentCount; } + public LiveData getViewCount() { + return viewCount; + } + public LiveData getType() { return type; } @@ -270,4 +276,12 @@ public class PostViewV2ViewModel extends ViewModel { }); return data; } + + public boolean hasPk() { + return media.getPk() != null; + } + + public void setViewCount(final Long viewCount) { + this.viewCount.postValue(viewCount); + } } diff --git a/app/src/main/res/layout/dialog_post_view.xml b/app/src/main/res/layout/dialog_post_view.xml index 3d8c1a7d..b56dd31c 100644 --- a/app/src/main/res/layout/dialog_post_view.xml +++ b/app/src/main/res/layout/dialog_post_view.xml @@ -73,18 +73,6 @@ app:layout_constraintTop_toTopOf="@id/profile_pic" tools:text="Username Username Username" /> - - - - - - - - - - - - + + + app:constraint_referenced_ids="likes_count,comments_count,views_count" /> + tools:visibility="gone" /> + tools:visibility="gone" /> + tools:visibility="gone" /> + + + app:layout_constraintTop_toBottomOf="@id/counts_barrier" + tools:text="2020-11-07 11:18:55" + tools:visibility="visible" /> + app:constraint_referenced_ids="date" /> + app:argType="string" + app:nullable="true" /> %d comment %d comments + + %d view + %d views + %s story %s stories @@ -391,4 +395,5 @@ Make Admin Remove as Admin Edit was unsuccessful + Message