Merge branch 'master' into retrofit-intercept-errors

This commit is contained in:
Ammar Githam 2021-03-30 20:01:08 +09:00
commit f7b918d91b
12 changed files with 246 additions and 13 deletions

View File

@ -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;
@ -207,6 +208,11 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter<RecyclerView.
final LayoutDmRavenMediaBinding binding = LayoutDmRavenMediaBinding.inflate(layoutInflater, baseBinding.message, false);
return new DirectItemRavenMediaViewHolder(baseBinding, binding, currentUser, thread, callback);
}
case XMA: {
final LayoutDmAnimatedMediaBinding binding = LayoutDmAnimatedMediaBinding.inflate(layoutInflater, baseBinding.message, false);
return new DirectItemXmaViewHolder(baseBinding, binding, currentUser, thread, callback);
}
case UNKNOWN:
default: {
final LayoutDmTextBinding binding = LayoutDmTextBinding.inflate(layoutInflater, baseBinding.message, false);
return new DirectItemDefaultViewHolder(baseBinding, binding, currentUser, thread, callback);
@ -240,7 +246,11 @@ public final class DirectItemsAdapter extends RecyclerView.Adapter<RecyclerView.
if (itemOrHeader.isHeader()) {
return -1;
}
return itemOrHeader.item.getItemType().getId();
final DirectItemType itemType = itemOrHeader.item.getItemType();
if (itemType == null) {
return 0;
}
return itemType.getId();
}
@Override

View File

@ -24,6 +24,7 @@ public class DirectItemDefaultViewHolder extends DirectItemViewHolder {
final DirectItemCallback callback) {
super(baseBinding, currentUser, thread, callback);
this.binding = binding;
setItemView(binding.getRoot());
}
@Override
@ -32,6 +33,11 @@ public class DirectItemDefaultViewHolder extends DirectItemViewHolder {
binding.tvMessage.setText(context.getText(R.string.dms_inbox_raven_message_unknown));
}
@Override
protected boolean showBackground() {
return true;
}
@Override
protected boolean allowLongClick() {
return false;

View File

@ -134,7 +134,7 @@ public abstract class DirectItemViewHolder extends RecyclerView.ViewHolder imple
containerLayoutParams.setMarginStart(0);
containerLayoutParams.setMarginEnd(0);
}
if (itemType == DirectItemType.TEXT || itemType == DirectItemType.LINK) {
if (itemType == DirectItemType.TEXT || itemType == DirectItemType.LINK || itemType == DirectItemType.UNKNOWN) {
binding.messageInfo.setPadding(0, 0, dmRadius, dmRadiusSmall);
} else {
if (showMessageInfo()) {

View File

@ -0,0 +1,69 @@
package awais.instagrabber.adapters.viewholder.directmessages;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.util.Pair;
import androidx.recyclerview.widget.ItemTouchHelper;
import com.facebook.drawee.backends.pipeline.Fresco;
import awais.instagrabber.adapters.DirectItemsAdapter.DirectItemCallback;
import awais.instagrabber.databinding.LayoutDmAnimatedMediaBinding;
import awais.instagrabber.databinding.LayoutDmBaseBinding;
import awais.instagrabber.repositories.responses.User;
import awais.instagrabber.repositories.responses.directmessages.DirectItem;
import awais.instagrabber.repositories.responses.directmessages.DirectItemXma;
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
import awais.instagrabber.utils.NumberUtils;
public class DirectItemXmaViewHolder extends DirectItemViewHolder {
private final LayoutDmAnimatedMediaBinding binding;
public DirectItemXmaViewHolder(@NonNull final LayoutDmBaseBinding baseBinding,
@NonNull final LayoutDmAnimatedMediaBinding binding,
final User currentUser,
final DirectThread thread,
final DirectItemCallback callback) {
super(baseBinding, currentUser, thread, callback);
this.binding = binding;
setItemView(binding.getRoot());
}
@Override
public void bindItem(final DirectItem item, final MessageDirection messageDirection) {
final DirectItemXma xma = item.getXma();
final DirectItemXma.XmaUrlInfo playableUrlInfo = xma.getPlayableUrlInfo();
final DirectItemXma.XmaUrlInfo previewUrlInfo = xma.getPreviewUrlInfo();
if (playableUrlInfo == null && previewUrlInfo == null) {
binding.ivAnimatedMessage.setController(null);
return;
}
final DirectItemXma.XmaUrlInfo urlInfo = playableUrlInfo != null ? playableUrlInfo : previewUrlInfo;
final String url = urlInfo.getUrl();
final Pair<Integer, Integer> 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;
}
}

View File

@ -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<Media> models = mediaViewModel.getList().getValue();
final List<Media> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)){
if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)) {
final ArrayList<String> 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")

View File

@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.Map;
public enum DirectItemType implements Serializable {
UNKNOWN(0),
@SerializedName("text")
TEXT(1),
@SerializedName("like")
@ -40,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<Integer, DirectItemType> map = new HashMap<>();
@ -60,6 +63,7 @@ public enum DirectItemType implements Serializable {
}
public static DirectItemType valueOf(final int id) {
if (!map.containsKey(id)) return DirectItemType.UNKNOWN;
return map.get(id);
}

View File

@ -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);
}
}

View File

@ -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 +
'}';
}
}
}

View File

@ -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) {

View File

@ -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
);

View File

@ -241,6 +241,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
if (users != null && users.getValue() != null) {
final List<User> 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<User> userList = leftUsers.getValue();
match = userList.stream()
.filter(Objects::nonNull)
.filter(user -> user.getPk() == userId)
.findFirst()
.orElse(null);

View File

@ -1,2 +1,2 @@
include ':app'
rootProject.name = "InstaGrabber"
rootProject.name = "Barinsta"