From c9f46a1986b955e20825d21fac8e736260905cd7 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sun, 28 Mar 2021 16:41:53 +0900 Subject: [PATCH 1/5] Update root project name --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index bf7737cf..77b3c366 100755 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ include ':app' -rootProject.name = "InstaGrabber" +rootProject.name = "Barinsta" From c5d55f366175e7421490fc571c43ab035e2e5dc9 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Mon, 29 Mar 2021 02:01:40 +0900 Subject: [PATCH 2/5] Added auto fetch more posts in feed at init. But disabled due to some weird list merging. --- .../customviews/PostsRecyclerView.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java index cdab91c9..b2456e0a 100644 --- a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java +++ b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java @@ -22,6 +22,7 @@ import androidx.work.WorkManager; import com.google.common.collect.ImmutableList; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -74,11 +75,10 @@ public class PostsRecyclerView extends RecyclerView { } final List models = mediaViewModel.getList().getValue(); final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); - if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)){ + if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)) { final ArrayList items = new ArrayList<>(settingsHelper.getStringSet(Constants.KEYWORD_FILTERS)); modelsCopy.addAll(new KeywordsFilterUtils(items).filter(result)); - } - else { + } else { modelsCopy.addAll(result); } mediaViewModel.getList().postValue(modelsCopy); @@ -194,7 +194,9 @@ public class PostsRecyclerView extends RecyclerView { private void initSelf() { mediaViewModel = new ViewModelProvider(viewModelStoreOwner).get(MediaViewModel.class); mediaViewModel.getList().observe(lifeCycleOwner, list -> { - if (list.size() > 0) feedAdapter.submitList(list, () -> { + if (list.size() <= 0) return; + feedAdapter.submitList(list, () -> { + // postDelayed(this::fetchMoreIfPossible, 1000); if (!shouldScrollToTop) return; smoothScrollToPosition(0); shouldScrollToTop = false; @@ -217,6 +219,20 @@ public class PostsRecyclerView extends RecyclerView { dispatchFetchStatus(); } + private void fetchMoreIfPossible() { + if (!postFetcher.hasMore()) return; + if (feedAdapter.getItemCount() == 0) return; + final LayoutManager layoutManager = getLayoutManager(); + if (!(layoutManager instanceof StaggeredGridLayoutManager)) return; + final int[] itemPositions = ((StaggeredGridLayoutManager) layoutManager).findLastCompletelyVisibleItemPositions(null); + final boolean allNoPosition = Arrays.stream(itemPositions).allMatch(position -> position == RecyclerView.NO_POSITION); + if (allNoPosition) return; + final boolean match = Arrays.stream(itemPositions).anyMatch(position -> position == feedAdapter.getItemCount() - 1); + if (!match) return; + postFetcher.fetch(); + dispatchFetchStatus(); + } + private void initDownloadWorkerListener() { WorkManager.getInstance(getContext()) .getWorkInfosByTagLiveData("download") From 7dc9583e51dbb4517196c333e6d41044127d53f0 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Mon, 29 Mar 2021 22:48:55 +0900 Subject: [PATCH 3/5] Null checks. Fixes https://github.com/austinhuang0131/barinsta/issues/905 --- .../awais/instagrabber/viewmodels/DirectThreadViewModel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java index 1ca3c263..3329d6c8 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java @@ -241,6 +241,7 @@ public class DirectThreadViewModel extends AndroidViewModel { if (users != null && users.getValue() != null) { final List userList = users.getValue(); match = userList.stream() + .filter(Objects::nonNull) .filter(user -> user.getPk() == userId) .findFirst() .orElse(null); @@ -250,6 +251,7 @@ public class DirectThreadViewModel extends AndroidViewModel { if (leftUsers != null && leftUsers.getValue() != null) { final List userList = leftUsers.getValue(); match = userList.stream() + .filter(Objects::nonNull) .filter(user -> user.getPk() == userId) .findFirst() .orElse(null); From 4507d8b5882e283c3e634ff11aa64a85f38c0dc0 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Mon, 29 Mar 2021 23:02:42 +0900 Subject: [PATCH 4/5] Handle unknown dm types. Fixes the crash in https://github.com/austinhuang0131/barinsta/issues/891 --- .../instagrabber/adapters/DirectItemsAdapter.java | 13 +++++++++++-- .../instagrabber/models/enums/DirectItemType.java | 4 ++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index 9fa309f2..f28fb139 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -146,7 +146,12 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter Date: Tue, 30 Mar 2021 00:47:28 +0900 Subject: [PATCH 5/5] Add XMA type direct item and fix default viewholder not visible. Fixes https://github.com/austinhuang0131/barinsta/issues/891 --- .../adapters/DirectItemsAdapter.java | 13 ++- .../DirectItemDefaultViewHolder.java | 6 + .../directmessages/DirectItemViewHolder.java | 2 +- .../DirectItemXmaViewHolder.java | 69 ++++++++++++ .../models/enums/DirectItemType.java | 10 +- .../responses/directmessages/DirectItem.java | 10 +- .../directmessages/DirectItemXma.java | 104 ++++++++++++++++++ .../awais/instagrabber/utils/DMUtils.java | 18 ++- .../instagrabber/utils/DirectItemFactory.java | 4 + 9 files changed, 219 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectItemXmaViewHolder.java create mode 100644 app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemXma.java diff --git a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java index f28fb139..e1469ac5 100644 --- a/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/DirectItemsAdapter.java @@ -34,6 +34,7 @@ import awais.instagrabber.adapters.viewholder.directmessages.DirectItemTextViewH import awais.instagrabber.adapters.viewholder.directmessages.DirectItemVideoCallEventViewHolder; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemViewHolder; import awais.instagrabber.adapters.viewholder.directmessages.DirectItemVoiceMediaViewHolder; +import awais.instagrabber.adapters.viewholder.directmessages.DirectItemXmaViewHolder; import awais.instagrabber.customviews.emoji.Emoji; import awais.instagrabber.databinding.LayoutDmActionLogBinding; import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding; @@ -146,12 +147,7 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter widthHeight = NumberUtils.calculateWidthHeight( + urlInfo.getHeight(), + urlInfo.getWidth(), + mediaImageMaxHeight, + mediaImageMaxWidth + ); + 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(); + binding.ivAnimatedMessage.setController(Fresco.newDraweeControllerBuilder() + .setUri(url) + .setAutoPlayAnimations(true) + .build()); + } + + @Override + public int getSwipeDirection() { + return ItemTouchHelper.ACTION_STATE_IDLE; + } +} diff --git a/app/src/main/java/awais/instagrabber/models/enums/DirectItemType.java b/app/src/main/java/awais/instagrabber/models/enums/DirectItemType.java index 58821f5c..83d655f2 100755 --- a/app/src/main/java/awais/instagrabber/models/enums/DirectItemType.java +++ b/app/src/main/java/awais/instagrabber/models/enums/DirectItemType.java @@ -1,7 +1,5 @@ package awais.instagrabber.models.enums; -import androidx.annotation.Nullable; - import com.google.gson.annotations.SerializedName; import java.io.Serializable; @@ -9,6 +7,7 @@ import java.util.HashMap; import java.util.Map; public enum DirectItemType implements Serializable { + UNKNOWN(0), @SerializedName("text") TEXT(1), @SerializedName("like") @@ -42,7 +41,9 @@ public enum DirectItemType implements Serializable { @SerializedName("felix_share") FELIX_SHARE(16), // media_share but igtv @SerializedName("location") - LOCATION(17); + LOCATION(17), + @SerializedName("xma") + XMA(18); // self avatar stickers private final int id; private static final Map map = new HashMap<>(); @@ -61,9 +62,8 @@ public enum DirectItemType implements Serializable { return id; } - @Nullable public static DirectItemType valueOf(final int id) { - if (!map.containsKey(id)) return null; + if (!map.containsKey(id)) return DirectItemType.UNKNOWN; return map.get(id); } diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java index 1845c61a..52ad8818 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java +++ b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItem.java @@ -41,6 +41,7 @@ public class DirectItem implements Cloneable, Serializable { private final DirectItem repliedToMessage; private final DirectItemVoiceMedia voiceMedia; private final Location location; + private final DirectItemXma xma; private final int hideInThread; private Date date; private boolean isPending; @@ -72,6 +73,7 @@ public class DirectItem implements Cloneable, Serializable { final DirectItem repliedToMessage, final DirectItemVoiceMedia voiceMedia, final Location location, + final DirectItemXma xma, final int hideInThread, final boolean showForwardAttribution) { this.itemId = itemId; @@ -99,6 +101,7 @@ public class DirectItem implements Cloneable, Serializable { this.repliedToMessage = repliedToMessage; this.voiceMedia = voiceMedia; this.location = location; + this.xma = xma; this.hideInThread = hideInThread; this.showForwardAttribution = showForwardAttribution; } @@ -208,6 +211,10 @@ public class DirectItem implements Cloneable, Serializable { return location; } + public DirectItemXma getXma() { + return xma; + } + public int getHideInThread() { return hideInThread; } @@ -286,6 +293,7 @@ public class DirectItem implements Cloneable, Serializable { Objects.equals(repliedToMessage, that.repliedToMessage) && Objects.equals(voiceMedia, that.voiceMedia) && Objects.equals(location, that.location) && + Objects.equals(xma, that.xma) && Objects.equals(date, that.date); } @@ -294,6 +302,6 @@ public class DirectItem implements Cloneable, Serializable { return Objects .hash(itemId, userId, timestamp, itemType, text, like, link, clientContext, reelShare, storyShare, mediaShare, profile, placeholder, media, previewMedias, actionLog, videoCallEvent, clip, felixShare, visualMedia, animatedMedia, reactions, repliedToMessage, - voiceMedia, location, hideInThread, date, isPending, showForwardAttribution); + voiceMedia, location, xma, hideInThread, date, isPending, showForwardAttribution); } } diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemXma.java b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemXma.java new file mode 100644 index 00000000..518e6efc --- /dev/null +++ b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectItemXma.java @@ -0,0 +1,104 @@ +package awais.instagrabber.repositories.responses.directmessages; + +import androidx.annotation.NonNull; + +import java.io.Serializable; +import java.util.Objects; + +public class DirectItemXma { + private final XmaUrlInfo previewUrlInfo; + private final XmaUrlInfo playableUrlInfo; + + public DirectItemXma(final XmaUrlInfo previewUrlInfo, final XmaUrlInfo playableUrlInfo) { + this.previewUrlInfo = previewUrlInfo; + this.playableUrlInfo = playableUrlInfo; + } + + public XmaUrlInfo getPreviewUrlInfo() { + return previewUrlInfo; + } + + public XmaUrlInfo getPlayableUrlInfo() { + return playableUrlInfo; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final DirectItemXma that = (DirectItemXma) o; + return Objects.equals(previewUrlInfo, that.previewUrlInfo) && + Objects.equals(playableUrlInfo, that.playableUrlInfo); + } + + @Override + public int hashCode() { + return Objects.hash(previewUrlInfo, playableUrlInfo); + } + + @NonNull + @Override + public String toString() { + return "DirectItemXma{" + + "previewUrlInfo=" + previewUrlInfo + + ", playableUrlInfo=" + playableUrlInfo + + '}'; + } + + public static class XmaUrlInfo implements Serializable { + private final String url; + private final long urlExpirationTimestampUs; + private final int width; + private final int height; + + public XmaUrlInfo(final String url, final long urlExpirationTimestampUs, final int width, final int height) { + this.url = url; + this.urlExpirationTimestampUs = urlExpirationTimestampUs; + this.width = width; + this.height = height; + } + + public String getUrl() { + return url; + } + + public long getUrlExpirationTimestampUs() { + return urlExpirationTimestampUs; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final XmaUrlInfo that = (XmaUrlInfo) o; + return urlExpirationTimestampUs == that.urlExpirationTimestampUs && + width == that.width && + height == that.height && + Objects.equals(url, that.url); + } + + @Override + public int hashCode() { + return Objects.hash(url, urlExpirationTimestampUs, width, height); + } + + @NonNull + @Override + public String toString() { + return "XmaUrlInfo{" + + "url='" + url + '\'' + + ", urlExpirationTimestampUs=" + urlExpirationTimestampUs + + ", width=" + width + + ", height=" + height + + '}'; + } + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/DMUtils.java b/app/src/main/java/awais/instagrabber/utils/DMUtils.java index 674e8722..12aa2e07 100644 --- a/app/src/main/java/awais/instagrabber/utils/DMUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/DMUtils.java @@ -44,9 +44,9 @@ public final class DMUtils { public static boolean isRead(@NonNull final DirectThread thread) { final boolean read; -// if (thread.getDirectStory() != null) { -// return false; -// } + // if (thread.getDirectStory() != null) { + // return false; + // } final DirectItem item = thread.getFirstDirectItem(); final long viewerId = thread.getViewerId(); if (item != null && item.getUserId() == viewerId) { @@ -188,6 +188,9 @@ public final class DMUtils { break; } break; + case XMA: + subtitle = resources.getString(R.string.dms_inbox_shared_sticker, username != null ? username : ""); + break; default: message = resources.getString(R.string.dms_inbox_raven_message_unknown); } @@ -213,7 +216,14 @@ public final class DMUtils { .filter(Objects::nonNull) .filter(user -> user.getPk() == userId) .findFirst(); - return senderOptional.map(User::getUsername).orElse(null); + return senderOptional.map(user -> { + // return full name for fb users + final String username = user.getUsername(); + if (TextUtils.isEmpty(username)) { + return user.getFullName(); + } + return username; + }).orElse(null); } public static String getMediaSpecificSubtitle(final String username, final Resources resources, final MediaItemType mediaType) { diff --git a/app/src/main/java/awais/instagrabber/utils/DirectItemFactory.java b/app/src/main/java/awais/instagrabber/utils/DirectItemFactory.java index 85e6f9ae..3ef9ddee 100644 --- a/app/src/main/java/awais/instagrabber/utils/DirectItemFactory.java +++ b/app/src/main/java/awais/instagrabber/utils/DirectItemFactory.java @@ -51,6 +51,7 @@ public final class DirectItemFactory { repliedToMessage, null, null, + null, 0, false); } @@ -132,6 +133,7 @@ public final class DirectItemFactory { null, null, null, + null, 0, false); } @@ -213,6 +215,7 @@ public final class DirectItemFactory { null, voiceMedia, null, + null, 0, false); } @@ -253,6 +256,7 @@ public final class DirectItemFactory { null, null, null, + null, 0, false );