diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 00000000..61a9130c
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ac6b0aec..23a89bbb 100755
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -15,6 +15,7 @@
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 3ea378e6..6e6363fe 100755
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/.idea/runConfigurations/app.xml b/.idea/runConfigurations/app.xml
index fe1ee5d0..6276ac27 100755
--- a/.idea/runConfigurations/app.xml
+++ b/.idea/runConfigurations/app.xml
@@ -1,11 +1,12 @@
-
+
+
@@ -41,11 +42,16 @@
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index ec04f426..d7c439a6 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -39,6 +39,12 @@ android {
}
}
+
+
+configurations.all {
+ resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
+}
+
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
@@ -62,7 +68,8 @@ dependencies {
implementation 'com.google.guava:guava:27.0.1-android'
// implementation 'com.github.hendrawd:StorageUtil:1.1.0'
- implementation 'com.github.armcha:AutoLinkTextViewV2:2.1.1'
+// implementation 'com.github.armcha:AutoLinkTextViewV2:2.1.1'
+ implementation 'com.github.ammargitham:AutoLinkTextViewV2:master-SNAPSHOT'
implementation 'org.jsoup:jsoup:1.13.1'
implementation 'com.facebook.fresco:fresco:2.3.0'
diff --git a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
index 6a00ff33..fb59c71b 100755
--- a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java
@@ -2,137 +2,189 @@ package awais.instagrabber.adapters;
import android.content.Context;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
-import android.widget.Filter;
-import android.widget.Filterable;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.viewholder.CommentViewHolder;
-import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.adapters.viewholder.comments.ChildCommentViewHolder;
+import awais.instagrabber.adapters.viewholder.comments.ParentCommentViewHolder;
+import awais.instagrabber.databinding.ItemCommentBinding;
+import awais.instagrabber.databinding.ItemCommentSmallBinding;
import awais.instagrabber.models.CommentModel;
-import awais.instagrabber.models.ProfileModel;
-import awais.instagrabber.utils.LocaleUtils;
-import awais.instagrabber.utils.TextUtils;
-public final class CommentsAdapter extends RecyclerView.Adapter implements Filterable {
+public final class CommentsAdapter extends ListAdapter {
+ private static final int TYPE_PARENT = 1;
+ private static final int TYPE_CHILD = 2;
- private CommentModel[] filteredCommentModels;
- private LayoutInflater layoutInflater;
+ private final Map positionTypeMap = new HashMap<>();
- private final boolean isParent;
- private final View.OnClickListener onClickListener;
- private final MentionClickListener mentionClickListener;
- private final CommentModel[] commentModels;
- private final String[] quantityStrings = new String[2];
- private final Filter filter = new Filter() {
- @NonNull
+ // private final Filter filter = new Filter() {
+ // @NonNull
+ // @Override
+ // protected FilterResults performFiltering(final CharSequence filter) {
+ // final FilterResults results = new FilterResults();
+ // results.values = commentModels;
+ //
+ // final int commentsLen = commentModels == null ? 0 : commentModels.size();
+ // if (commentModels != null && commentsLen > 0 && !TextUtils.isEmpty(filter)) {
+ // final String query = filter.toString().toLowerCase();
+ // final ArrayList filterList = new ArrayList<>(commentsLen);
+ //
+ // for (final CommentModel commentModel : commentModels) {
+ // final String commentText = commentModel.getText().toString().toLowerCase();
+ //
+ // if (commentText.contains(query)) filterList.add(commentModel);
+ // else {
+ // final List childCommentModels = commentModel.getChildCommentModels();
+ // if (childCommentModels != null) {
+ // for (final CommentModel childCommentModel : childCommentModels) {
+ // final String childCommentText = childCommentModel.getText().toString().toLowerCase();
+ // if (childCommentText.contains(query)) filterList.add(commentModel);
+ // }
+ // }
+ // }
+ // }
+ // filterList.trimToSize();
+ // results.values = filterList.toArray(new CommentModel[0]);
+ // }
+ //
+ // return results;
+ // }
+ //
+ // @Override
+ // protected void publishResults(final CharSequence constraint, @NonNull final FilterResults results) {
+ // if (results.values instanceof List) {
+ // //noinspection unchecked
+ // filteredCommentModels = (List) results.values;
+ // notifyDataSetChanged();
+ // }
+ // }
+ // };
+
+ private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
@Override
- protected FilterResults performFiltering(final CharSequence filter) {
- final FilterResults results = new FilterResults();
- results.values = commentModels;
-
- final int commentsLen = commentModels == null ? 0 : commentModels.length;
- if (commentModels != null && commentsLen > 0 && !TextUtils.isEmpty(filter)) {
- final String query = filter.toString().toLowerCase();
- final ArrayList filterList = new ArrayList<>(commentsLen);
-
- for (final CommentModel commentModel : commentModels) {
- final String commentText = commentModel.getText().toString().toLowerCase();
-
- if (commentText.contains(query)) filterList.add(commentModel);
- else {
- final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
- if (childCommentModels != null) {
- for (final CommentModel childCommentModel : childCommentModels) {
- final String childCommentText = childCommentModel.getText().toString().toLowerCase();
- if (childCommentText.contains(query)) filterList.add(commentModel);
- }
- }
- }
- }
- filterList.trimToSize();
- results.values = filterList.toArray(new CommentModel[0]);
- }
-
- return results;
+ public boolean areItemsTheSame(@NonNull final CommentModel oldItem, @NonNull final CommentModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
}
@Override
- protected void publishResults(final CharSequence constraint, @NonNull final FilterResults results) {
- if (results.values instanceof CommentModel[]) {
- filteredCommentModels = (CommentModel[]) results.values;
- notifyDataSetChanged();
- }
+ public boolean areContentsTheSame(@NonNull final CommentModel oldItem, @NonNull final CommentModel newItem) {
+ return oldItem.getId().equals(newItem.getId());
}
};
+ private final CommentCallback commentCallback;
+ private CommentModel selected;
+ private int selectedIndex;
- public CommentsAdapter(final CommentModel[] commentModels,
- final boolean isParent,
- final View.OnClickListener onClickListener,
- final MentionClickListener mentionClickListener) {
- super();
- this.commentModels = this.filteredCommentModels = commentModels;
- this.isParent = isParent;
- this.onClickListener = onClickListener;
- this.mentionClickListener = mentionClickListener;
- }
-
- @Override
- public Filter getFilter() {
- return filter;
+ public CommentsAdapter(final CommentCallback commentCallback) {
+ super(DIFF_CALLBACK);
+ this.commentCallback = commentCallback;
}
@NonNull
@Override
- public CommentViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
final Context context = parent.getContext();
- if (quantityStrings[0] == null) quantityStrings[0] = context.getString(R.string.single_like);
- if (quantityStrings[1] == null) quantityStrings[1] = context.getString(R.string.multiple_likes);
- if (layoutInflater == null) layoutInflater = LayoutInflater.from(context);
- final View view = layoutInflater.inflate(isParent ? R.layout.item_comment
- : R.layout.item_comment_small,
- parent,
- false);
- return new CommentViewHolder(view,
- onClickListener,
- mentionClickListener);
+ final LayoutInflater layoutInflater = LayoutInflater.from(context);
+ if (type == TYPE_PARENT) {
+ final ItemCommentBinding binding = ItemCommentBinding.inflate(layoutInflater, parent, false);
+ return new ParentCommentViewHolder(binding);
+ }
+ final ItemCommentSmallBinding binding = ItemCommentSmallBinding.inflate(layoutInflater, parent, false);
+ return new ChildCommentViewHolder(binding);
}
@Override
- public void onBindViewHolder(@NonNull final CommentViewHolder holder, final int position) {
- final CommentModel commentModel = filteredCommentModels[position];
- if (commentModel != null) {
- holder.setCommentModel(commentModel);
+ public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
+ final CommentModel commentModel = getItem(position);
+ if (commentModel == null) return;
+ final int type = getItemViewType(position);
+ final boolean selected = this.selected != null && this.selected.getId().equals(commentModel.getId());
+ if (type == TYPE_PARENT) {
+ final ParentCommentViewHolder viewHolder = (ParentCommentViewHolder) holder;
+ viewHolder.bind(commentModel, selected, commentCallback);
+ return;
+ }
+ final ChildCommentViewHolder viewHolder = (ChildCommentViewHolder) holder;
+ viewHolder.bind(commentModel, selected, commentCallback);
+ }
- holder.setComment(commentModel.getText());
- holder.setDate(commentModel.getDateTime());
- holder.setLiked(commentModel.getLiked());
+ @Override
+ public void submitList(@Nullable final List list) {
+ final List flatList = flattenList(list);
+ super.submitList(flatList);
+ }
- final long likes = commentModel.getLikes();
- holder.setLikes(String.format(LocaleUtils.getCurrentLocale(), "%d %s", likes, quantityStrings[likes == 1 ? 0 : 1]));
+ @Override
+ public void submitList(@Nullable final List list, @Nullable final Runnable commitCallback) {
+ final List flatList = flattenList(list);
+ super.submitList(flatList, commitCallback);
+ }
- final ProfileModel profileModel = commentModel.getProfileModel();
- if (profileModel != null) {
- holder.setUsername(profileModel.getUsername());
- holder.getProfilePicView().setImageURI(profileModel.getSdProfilePic());
- }
- if (holder.isParent()) {
- final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
- if (childCommentModels != null && childCommentModels.length > 0)
- holder.setChildAdapter(new CommentsAdapter(childCommentModels, false, onClickListener, mentionClickListener));
- else holder.hideChildComments();
+ private List flattenList(final List list) {
+ if (list == null) {
+ return Collections.emptyList();
+ }
+ final List flatList = new ArrayList<>();
+ int lastCommentIndex = -1;
+ for (final CommentModel parent : list) {
+ lastCommentIndex++;
+ flatList.add(parent);
+ positionTypeMap.put(lastCommentIndex, TYPE_PARENT);
+ final List children = parent.getChildCommentModels();
+ for (final CommentModel child : children) {
+ lastCommentIndex++;
+ flatList.add(child);
+ positionTypeMap.put(lastCommentIndex, TYPE_CHILD);
}
}
+ return flatList;
}
+
@Override
- public int getItemCount() {
- return filteredCommentModels == null ? 0 : filteredCommentModels.length;
+ public int getItemViewType(final int position) {
+ final Integer type = positionTypeMap.get(position);
+ if (type == null) {
+ return TYPE_PARENT;
+ }
+ return type;
+ }
+
+ public void setSelected(final CommentModel commentModel) {
+ this.selected = commentModel;
+ selectedIndex = getCurrentList().indexOf(commentModel);
+ notifyItemChanged(selectedIndex);
+ }
+
+ public void clearSelection() {
+ this.selected = null;
+ notifyItemChanged(selectedIndex);
+ }
+
+ public CommentModel getSelected() {
+ return selected;
+ }
+
+ public interface CommentCallback {
+ void onClick(final CommentModel comment);
+
+ void onHashtagClick(final String hashtag);
+
+ void onMentionClick(final String mention);
+
+ void onURLClick(final String url);
+
+ void onEmailClick(final String emailAddress);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
index af8e8476..6ffc88e0 100755
--- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java
@@ -1,111 +1,111 @@
-package awais.instagrabber.adapters;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.DiffUtil;
-import androidx.recyclerview.widget.ListAdapter;
-
-import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder;
-import awais.instagrabber.adapters.viewholder.feed.FeedPhotoViewHolder;
-import awais.instagrabber.adapters.viewholder.feed.FeedSliderViewHolder;
-import awais.instagrabber.adapters.viewholder.feed.FeedVideoViewHolder;
-import awais.instagrabber.customviews.RamboTextView;
-import awais.instagrabber.databinding.ItemFeedPhotoBinding;
-import awais.instagrabber.databinding.ItemFeedSliderBinding;
-import awais.instagrabber.databinding.ItemFeedVideoBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
-import awais.instagrabber.models.FeedModel;
-import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Utils;
-
-public final class FeedAdapter extends ListAdapter {
- private static final String TAG = "FeedAdapter";
- private final View.OnClickListener clickListener;
- private final MentionClickListener mentionClickListener;
- private final View.OnLongClickListener longClickListener = v -> {
- final Object tag;
- if (v instanceof RamboTextView && (tag = v.getTag()) instanceof FeedModel)
- Utils.copyText(v.getContext(), ((FeedModel) tag).getPostCaption());
- return true;
- };
-
- private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
- @Override
- public boolean areItemsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
- return oldItem.getPostId().equals(newItem.getPostId());
- }
-
- @Override
- public boolean areContentsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
- return oldItem.getPostId().equals(newItem.getPostId());
- }
- };
-
- public FeedAdapter(final View.OnClickListener clickListener,
- final MentionClickListener mentionClickListener) {
- super(diffCallback);
- // private final static String ellipsize = "… more";
- this.clickListener = clickListener;
- this.mentionClickListener = mentionClickListener;
- }
-
- @NonNull
- @Override
- public FeedItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
- final Context context = parent.getContext();
- final LayoutInflater layoutInflater = LayoutInflater.from(context);
- final MediaItemType type = MediaItemType.valueOf(viewType);
- switch (type) {
- case MEDIA_TYPE_VIDEO: {
- final ItemFeedVideoBinding binding = ItemFeedVideoBinding.inflate(layoutInflater, parent, false);
- return new FeedVideoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
- }
- case MEDIA_TYPE_SLIDER: {
- final ItemFeedSliderBinding binding = ItemFeedSliderBinding.inflate(layoutInflater, parent, false);
- return new FeedSliderViewHolder(binding, mentionClickListener, clickListener, longClickListener);
- }
- case MEDIA_TYPE_IMAGE:
- default: {
- final ItemFeedPhotoBinding binding = ItemFeedPhotoBinding.inflate(layoutInflater, parent, false);
- return new FeedPhotoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
- }
- }
- }
-
- @Override
- public void onBindViewHolder(@NonNull final FeedItemViewHolder viewHolder, final int position) {
- final FeedModel feedModel = getItem(position);
- if (feedModel == null) {
- return;
- }
- feedModel.setPosition(position);
- viewHolder.bind(feedModel, (feedModel1, view, postImage) -> {});
- }
-
- @Override
- public int getItemViewType(final int position) {
- return getItem(position).getItemType().getId();
- }
-
- @Override
- public void onViewAttachedToWindow(@NonNull final FeedItemViewHolder holder) {
- super.onViewAttachedToWindow(holder);
- // Log.d(TAG, "attached holder: " + holder);
- if (!(holder instanceof FeedSliderViewHolder)) return;
- final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
- feedSliderViewHolder.startPlayingVideo();
- }
-
- @Override
- public void onViewDetachedFromWindow(@NonNull final FeedItemViewHolder holder) {
- super.onViewDetachedFromWindow(holder);
- // Log.d(TAG, "detached holder: " + holder);
- if (!(holder instanceof FeedSliderViewHolder)) return;
- final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
- feedSliderViewHolder.stopPlayingVideo();
- }
-}
\ No newline at end of file
+// package awais.instagrabber.adapters;
+//
+// import android.content.Context;
+// import android.view.LayoutInflater;
+// import android.view.View;
+// import android.view.ViewGroup;
+//
+// import androidx.annotation.NonNull;
+// import androidx.recyclerview.widget.DiffUtil;
+// import androidx.recyclerview.widget.ListAdapter;
+//
+// import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder;
+// import awais.instagrabber.adapters.viewholder.feed.FeedPhotoViewHolder;
+// import awais.instagrabber.adapters.viewholder.feed.FeedSliderViewHolder;
+// import awais.instagrabber.adapters.viewholder.feed.FeedVideoViewHolder;
+// import awais.instagrabber.customviews.RamboTextView;
+// import awais.instagrabber.databinding.ItemFeedPhotoBinding;
+// import awais.instagrabber.databinding.ItemFeedSliderBinding;
+// import awais.instagrabber.databinding.ItemFeedVideoBinding;
+// import awais.instagrabber.interfaces.MentionClickListener;
+// import awais.instagrabber.models.FeedModel;
+// import awais.instagrabber.models.enums.MediaItemType;
+// import awais.instagrabber.utils.Utils;
+//
+// public final class FeedAdapter extends ListAdapter {
+// private static final String TAG = "FeedAdapter";
+// private final View.OnClickListener clickListener;
+// private final MentionClickListener mentionClickListener;
+// private final View.OnLongClickListener longClickListener = v -> {
+// final Object tag;
+// if (v instanceof RamboTextView && (tag = v.getTag()) instanceof FeedModel)
+// Utils.copyText(v.getContext(), ((FeedModel) tag).getPostCaption());
+// return true;
+// };
+//
+// private static final DiffUtil.ItemCallback diffCallback = new DiffUtil.ItemCallback() {
+// @Override
+// public boolean areItemsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
+// return oldItem.getPostId().equals(newItem.getPostId());
+// }
+//
+// @Override
+// public boolean areContentsTheSame(@NonNull final FeedModel oldItem, @NonNull final FeedModel newItem) {
+// return oldItem.getPostId().equals(newItem.getPostId());
+// }
+// };
+//
+// public FeedAdapter(final View.OnClickListener clickListener,
+// final MentionClickListener mentionClickListener) {
+// super(diffCallback);
+// // private final static String ellipsize = "… more";
+// this.clickListener = clickListener;
+// this.mentionClickListener = mentionClickListener;
+// }
+//
+// @NonNull
+// @Override
+// public FeedItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+// final Context context = parent.getContext();
+// final LayoutInflater layoutInflater = LayoutInflater.from(context);
+// final MediaItemType type = MediaItemType.valueOf(viewType);
+// switch (type) {
+// case MEDIA_TYPE_VIDEO: {
+// final ItemFeedVideoBinding binding = ItemFeedVideoBinding.inflate(layoutInflater, parent, false);
+// return new FeedVideoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
+// }
+// case MEDIA_TYPE_SLIDER: {
+// final ItemFeedSliderBinding binding = ItemFeedSliderBinding.inflate(layoutInflater, parent, false);
+// return new FeedSliderViewHolder(binding, mentionClickListener, clickListener, longClickListener);
+// }
+// case MEDIA_TYPE_IMAGE:
+// default: {
+// final ItemFeedPhotoBinding binding = ItemFeedPhotoBinding.inflate(layoutInflater, parent, false);
+// return new FeedPhotoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
+// }
+// }
+// }
+//
+// @Override
+// public void onBindViewHolder(@NonNull final FeedItemViewHolder viewHolder, final int position) {
+// final FeedModel feedModel = getItem(position);
+// if (feedModel == null) {
+// return;
+// }
+// feedModel.setPosition(position);
+// viewHolder.bind(feedModel, (feedModel1, view, postImage) -> {});
+// }
+//
+// @Override
+// public int getItemViewType(final int position) {
+// return getItem(position).getItemType().getId();
+// }
+//
+// @Override
+// public void onViewAttachedToWindow(@NonNull final FeedItemViewHolder holder) {
+// super.onViewAttachedToWindow(holder);
+// // Log.d(TAG, "attached holder: " + holder);
+// if (!(holder instanceof FeedSliderViewHolder)) return;
+// final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
+// feedSliderViewHolder.startPlayingVideo();
+// }
+//
+// @Override
+// public void onViewDetachedFromWindow(@NonNull final FeedItemViewHolder holder) {
+// super.onViewDetachedFromWindow(holder);
+// // Log.d(TAG, "detached holder: " + holder);
+// if (!(holder instanceof FeedSliderViewHolder)) return;
+// final FeedSliderViewHolder feedSliderViewHolder = (FeedSliderViewHolder) holder;
+// feedSliderViewHolder.stopPlayingVideo();
+// }
+// }
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
index a9e78333..30baeda0 100644
--- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
+++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapterV2.java
@@ -15,32 +15,26 @@ import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder;
import awais.instagrabber.adapters.viewholder.feed.FeedPhotoViewHolder;
import awais.instagrabber.adapters.viewholder.feed.FeedSliderViewHolder;
import awais.instagrabber.adapters.viewholder.feed.FeedVideoViewHolder;
-import awais.instagrabber.customviews.RamboTextView;
import awais.instagrabber.databinding.ItemFeedGridBinding;
import awais.instagrabber.databinding.ItemFeedPhotoBinding;
import awais.instagrabber.databinding.ItemFeedSliderBinding;
import awais.instagrabber.databinding.ItemFeedVideoBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.enums.MediaItemType;
-import awais.instagrabber.utils.Utils;
public final class FeedAdapterV2 extends ListAdapter {
private static final String TAG = "FeedAdapterV2";
private PostsLayoutPreferences layoutPreferences;
- private OnPostClickListener postClickListener;
- private int lastAnimatedPosition;
+ private final FeedItemCallback feedItemCallback;
- private final View.OnClickListener clickListener;
- private final MentionClickListener mentionClickListener;
- private final View.OnLongClickListener longClickListener = v -> {
- final Object tag;
- if (v instanceof RamboTextView && (tag = v.getTag()) instanceof FeedModel)
- Utils.copyText(v.getContext(), ((FeedModel) tag).getPostCaption());
- return true;
- };
+ // private final View.OnLongClickListener longClickListener = v -> {
+ // final Object tag;
+ // if (v instanceof RamboTextView && (tag = v.getTag()) instanceof FeedModel)
+ // Utils.copyText(v.getContext(), ((FeedModel) tag).getPostCaption());
+ // return true;
+ // };
private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() {
@@ -56,14 +50,10 @@ public final class FeedAdapterV2 extends ListAdapter lastAnimatedPosition;
- ((FeedGridItemViewHolder) viewHolder).bind(feedModel, layoutPreferences, postClickListener, false);
+ ((FeedGridItemViewHolder) viewHolder).bind(feedModel, layoutPreferences, feedItemCallback);
}
- lastAnimatedPosition = position;
}
@Override
@@ -126,19 +114,6 @@ public final class FeedAdapterV2 extends ListAdapter {
private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener;
+ private final boolean loadVideoOnItemClick;
private final SliderCallback sliderCallback;
private final awais.instagrabber.databinding.LayoutExoCustomControlsBinding controlsBinding;
@@ -35,15 +36,13 @@ public final class SliderItemsAdapter extends ListAdapter postClickListener.onPostClick(feedModel, binding.profilePic, binding.postImage));
+ final FeedAdapterV2.FeedItemCallback feedItemCallback) {
+ if (feedItemCallback != null) {
+ itemView.setOnClickListener(v -> feedItemCallback.onPostClick(feedModel, binding.profilePic, binding.postImage));
}
itemView.setClipToOutline(layoutPreferences.getHasRoundedCorners());
if (layoutPreferences.getType() == STAGGERED_GRID) {
@@ -123,25 +117,6 @@ public class FeedGridItemViewHolder extends RecyclerView.ViewHolder {
final PipelineDraweeControllerBuilder builder = Fresco.newDraweeControllerBuilder()
.setImageRequest(requestBuilder)
.setOldController(binding.postImage.getController());
- if (animate) {
- final BaseControllerListener imageListener = new BaseControllerListener() {
- @Override
- public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
- setAnimation(binding.getRoot());
- }
- };
- builder.setControllerListener(imageListener);
- }
binding.postImage.setController(builder.build());
}
-
- private void setAnimation(View viewToAnimate) {
- final Animation animation = AnimationUtils.loadAnimation(viewToAnimate.getContext(), android.R.anim.fade_in);
- animation.setDuration(300);
- viewToAnimate.startAnimation(animation);
- }
-
- public void clearAnimation() {
- binding.getRoot().clearAnimation();
- }
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/SliderVideoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/SliderVideoViewHolder.java
index 00c70ee6..325aa720 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/SliderVideoViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/SliderVideoViewHolder.java
@@ -22,34 +22,39 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
private static final String TAG = "SliderVideoViewHolder";
private final LayoutVideoPlayerWithThumbnailBinding binding;
- private final awais.instagrabber.databinding.LayoutExoCustomControlsBinding controlsBinding;
+ private final LayoutExoCustomControlsBinding controlsBinding;
+ private final boolean loadVideoOnItemClick;
private VideoPlayerViewHelper videoPlayerViewHelper;
@SuppressLint("ClickableViewAccessibility")
public SliderVideoViewHolder(@NonNull final LayoutVideoPlayerWithThumbnailBinding binding,
final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener,
- final LayoutExoCustomControlsBinding controlsBinding) {
+ final LayoutExoCustomControlsBinding controlsBinding,
+ final boolean loadVideoOnItemClick) {
super(binding.getRoot());
this.binding = binding;
this.controlsBinding = controlsBinding;
- final VerticalDragHelper thumbnailVerticalDragHelper = new VerticalDragHelper(binding.thumbnailParent);
- final VerticalDragHelper playerVerticalDragHelper = new VerticalDragHelper(binding.playerView);
- thumbnailVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
- playerVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
- binding.thumbnailParent.setOnTouchListener((v, event) -> {
- final boolean onDragTouch = thumbnailVerticalDragHelper.onDragTouch(event);
- if (onDragTouch) {
- return true;
- }
- return thumbnailVerticalDragHelper.onGestureTouchEvent(event);
- });
- binding.playerView.setOnTouchListener((v, event) -> {
- final boolean onDragTouch = playerVerticalDragHelper.onDragTouch(event);
- if (onDragTouch) {
- return true;
- }
- return playerVerticalDragHelper.onGestureTouchEvent(event);
- });
+ this.loadVideoOnItemClick = loadVideoOnItemClick;
+ if (onVerticalDragListener != null) {
+ final VerticalDragHelper thumbnailVerticalDragHelper = new VerticalDragHelper(binding.thumbnailParent);
+ final VerticalDragHelper playerVerticalDragHelper = new VerticalDragHelper(binding.playerView);
+ thumbnailVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
+ playerVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
+ binding.thumbnailParent.setOnTouchListener((v, event) -> {
+ final boolean onDragTouch = thumbnailVerticalDragHelper.onDragTouch(event);
+ if (onDragTouch) {
+ return true;
+ }
+ return thumbnailVerticalDragHelper.onGestureTouchEvent(event);
+ });
+ binding.playerView.setOnTouchListener((v, event) -> {
+ final boolean onDragTouch = playerVerticalDragHelper.onDragTouch(event);
+ if (onDragTouch) {
+ return true;
+ }
+ return playerVerticalDragHelper.onGestureTouchEvent(event);
+ });
+ }
}
public void bind(@NonNull final PostChild model,
@@ -57,6 +62,14 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
final SliderItemsAdapter.SliderCallback sliderCallback) {
final float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
final VideoPlayerViewHelper.VideoPlayerCallback videoPlayerCallback = new VideoPlayerCallbackAdapter() {
+
+ @Override
+ public void onThumbnailClick() {
+ if (sliderCallback != null) {
+ sliderCallback.onItemClicked(position);
+ }
+ }
+
@Override
public void onThumbnailLoaded() {
if (sliderCallback != null) {
@@ -97,6 +110,7 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
vol,
aspectRatio,
model.getThumbnailUrl(),
+ loadVideoOnItemClick,
controlsBinding,
videoPlayerCallback);
// binding.itemFeedBottom.btnMute.setOnClickListener(v -> {
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ChildCommentViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ChildCommentViewHolder.java
new file mode 100644
index 00000000..27c82580
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ChildCommentViewHolder.java
@@ -0,0 +1,93 @@
+package awais.instagrabber.adapters.viewholder.comments;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.CommentsAdapter.CommentCallback;
+import awais.instagrabber.databinding.ItemCommentSmallBinding;
+import awais.instagrabber.models.CommentModel;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.utils.Utils;
+
+public final class ChildCommentViewHolder extends RecyclerView.ViewHolder {
+
+ private final ItemCommentSmallBinding binding;
+
+ public ChildCommentViewHolder(@NonNull final ItemCommentSmallBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final CommentModel comment,
+ final boolean selected,
+ final CommentCallback commentCallback) {
+ if (comment == null) return;
+ if (commentCallback != null) {
+ itemView.setOnClickListener(v -> commentCallback.onClick(comment));
+ }
+ if (selected) {
+ itemView.setBackgroundColor(itemView.getResources().getColor(R.color.comment_selected));
+ } else {
+ itemView.setBackgroundColor(itemView.getResources().getColor(android.R.color.transparent));
+ }
+ setupCommentText(comment, commentCallback);
+ binding.tvDate.setText(comment.getDateTime());
+ setLiked(comment.getLiked());
+ setLikes((int) comment.getLikes());
+ setUser(comment);
+ }
+
+ private void setupCommentText(final CommentModel comment, final CommentCallback commentCallback) {
+ binding.tvComment.clearOnURLClickListeners();
+ binding.tvComment.clearOnHashtagClickListeners();
+ binding.tvComment.clearOnMentionClickListeners();
+ binding.tvComment.clearOnEmailClickListeners();
+ binding.tvComment.setText(comment.getText());
+ binding.tvComment.addOnHashtagListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onHashtagClick(originalText);
+ });
+ binding.tvComment.addOnMentionClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onMentionClick(originalText);
+
+ });
+ binding.tvComment.addOnEmailClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onEmailClick(originalText);
+ });
+ binding.tvComment.addOnURLClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onURLClick(originalText);
+ });
+ binding.tvComment.setOnLongClickListener(v -> {
+ Utils.copyText(itemView.getContext(), comment.getText());
+ return true;
+ });
+ binding.tvComment.setOnClickListener(v -> commentCallback.onClick(comment));
+ }
+
+ private void setUser(final CommentModel comment) {
+ final ProfileModel profileModel = comment.getProfileModel();
+ if (profileModel == null) return;
+ binding.tvUsername.setText(profileModel.getUsername());
+ binding.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
+ }
+
+ private void setLikes(final int likes) {
+ final String likesString = itemView.getResources().getQuantityString(R.plurals.likes_count, likes, likes);
+ binding.tvLikes.setText(likesString);
+ }
+
+ public final void setLiked(final boolean liked) {
+ if (liked) {
+ // container.setBackgroundColor(0x40FF69B4);
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ParentCommentViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ParentCommentViewHolder.java
new file mode 100644
index 00000000..71ae48c2
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/comments/ParentCommentViewHolder.java
@@ -0,0 +1,93 @@
+package awais.instagrabber.adapters.viewholder.comments;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.CommentsAdapter.CommentCallback;
+import awais.instagrabber.databinding.ItemCommentBinding;
+import awais.instagrabber.models.CommentModel;
+import awais.instagrabber.models.ProfileModel;
+import awais.instagrabber.utils.Utils;
+
+public final class ParentCommentViewHolder extends RecyclerView.ViewHolder {
+
+ private final ItemCommentBinding binding;
+
+ public ParentCommentViewHolder(@NonNull final ItemCommentBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public void bind(final CommentModel comment,
+ final boolean selected,
+ final CommentCallback commentCallback) {
+ if (comment == null) return;
+ if (commentCallback != null) {
+ itemView.setOnClickListener(v -> commentCallback.onClick(comment));
+ }
+ if (selected) {
+ itemView.setBackgroundColor(itemView.getResources().getColor(R.color.comment_selected));
+ } else {
+ itemView.setBackgroundColor(itemView.getResources().getColor(android.R.color.transparent));
+ }
+ setupCommentText(comment, commentCallback);
+ binding.tvDate.setText(comment.getDateTime());
+ setLiked(comment.getLiked());
+ setLikes((int) comment.getLikes());
+ setUser(comment);
+ }
+
+ private void setupCommentText(final CommentModel comment, final CommentCallback commentCallback) {
+ binding.tvComment.clearOnURLClickListeners();
+ binding.tvComment.clearOnHashtagClickListeners();
+ binding.tvComment.clearOnMentionClickListeners();
+ binding.tvComment.clearOnEmailClickListeners();
+ binding.tvComment.setText(comment.getText());
+ binding.tvComment.addOnHashtagListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onHashtagClick(originalText);
+ });
+ binding.tvComment.addOnMentionClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onMentionClick(originalText);
+
+ });
+ binding.tvComment.addOnEmailClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onEmailClick(originalText);
+ });
+ binding.tvComment.addOnURLClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText();
+ if (commentCallback == null) return;
+ commentCallback.onURLClick(originalText);
+ });
+ binding.tvComment.setOnLongClickListener(v -> {
+ Utils.copyText(itemView.getContext(), comment.getText());
+ return true;
+ });
+ binding.tvComment.setOnClickListener(v -> commentCallback.onClick(comment));
+ }
+
+ private void setUser(final CommentModel comment) {
+ final ProfileModel profileModel = comment.getProfileModel();
+ if (profileModel == null) return;
+ binding.tvUsername.setText(profileModel.getUsername());
+ binding.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
+ }
+
+ private void setLikes(final int likes) {
+ final String likesString = itemView.getResources().getQuantityString(R.plurals.likes_count, likes, likes);
+ binding.tvLikes.setText(likesString);
+ }
+
+ public final void setLiked(final boolean liked) {
+ if (liked) {
+ // container.setBackgroundColor(0x40FF69B4);
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
index 9fe7efab..1555a9bc 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java
@@ -1,95 +1,107 @@
package awais.instagrabber.adapters.viewholder.feed;
-import android.text.SpannableString;
-import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.transition.TransitionManager;
import android.view.View;
import android.widget.RelativeLayout;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import awais.instagrabber.adapters.FeedAdapterV2;
-import awais.instagrabber.customviews.CommentMentionClickSpan;
-import awais.instagrabber.customviews.RamboTextView;
import awais.instagrabber.databinding.ItemFeedBottomBinding;
import awais.instagrabber.databinding.ItemFeedTopBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.TextUtils;
+import static android.text.TextUtils.TruncateAt.END;
+
public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
- public static final int MAX_CHARS = 255;
+ public static final int MAX_LINES_COLLAPSED = 5;
private final ItemFeedTopBinding topBinding;
private final ItemFeedBottomBinding bottomBinding;
- private final MentionClickListener mentionClickListener;
+ private final FeedAdapterV2.FeedItemCallback feedItemCallback;
public FeedItemViewHolder(@NonNull final View root,
final ItemFeedTopBinding topBinding,
final ItemFeedBottomBinding bottomBinding,
- final MentionClickListener mentionClickListener,
- final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
+ final FeedAdapterV2.FeedItemCallback feedItemCallback) {
super(root);
this.topBinding = topBinding;
this.bottomBinding = bottomBinding;
- this.mentionClickListener = mentionClickListener;
- // itemView.setOnClickListener(clickListener);
- // topBinding.title.setMovementMethod(new LinkMovementMethod());
- // bottomBinding.btnComments.setOnClickListener(clickListener);
- // topBinding.viewStoryPost.setOnClickListener(clickListener);
- // topBinding.ivProfilePic.setOnClickListener(clickListener);
- // bottomBinding.btnDownload.setOnClickListener(clickListener);
- // bottomBinding.viewerCaption.setOnClickListener(clickListener);
- // bottomBinding.viewerCaption.setOnLongClickListener(longClickListener);
- // bottomBinding.viewerCaption.setMentionClickListener(mentionClickListener);
+ topBinding.title.setMovementMethod(new LinkMovementMethod());
+ this.feedItemCallback = feedItemCallback;
}
- public void bind(final FeedModel feedModel,
- final FeedAdapterV2.OnPostClickListener postClickListener) {
+ public void bind(final FeedModel feedModel) {
if (feedModel == null) {
return;
}
- topBinding.viewStoryPost.setTag(feedModel);
- topBinding.ivProfilePic.setTag(feedModel);
- bottomBinding.btnDownload.setTag(feedModel);
- bottomBinding.viewerCaption.setTag(feedModel);
- bottomBinding.btnComments.setTag(feedModel);
- final ProfileModel profileModel = feedModel.getProfileModel();
- if (profileModel != null) {
- topBinding.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
- final int titleLen = profileModel.getUsername().length() + 1;
- final SpannableString spannableString = new SpannableString("@" + profileModel.getUsername());
- spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
- topBinding.title.setText(spannableString);
- topBinding.title.setMentionClickListener(
- (view, text, isHashtag, isLocation) -> mentionClickListener.onClick(null, profileModel.getUsername(), false, false));
- }
+ setupProfilePic(feedModel);
+ setupLocation(feedModel);
bottomBinding.tvPostDate.setText(feedModel.getPostDate());
- final long commentsCount = feedModel.getCommentsCount();
- bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
-
- final String locationName = feedModel.getLocationName();
- final String locationId = feedModel.getLocationId();
- setLocation(locationName, locationId);
- CharSequence postCaption = feedModel.getPostCaption();
- final boolean captionEmpty = TextUtils.isEmpty(postCaption);
- bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
- if (!captionEmpty) {
- if (TextUtils.hasMentions(postCaption)) {
- postCaption = TextUtils.getMentionText(postCaption);
- feedModel.setPostCaption(postCaption);
- bottomBinding.viewerCaption.setText(postCaption, TextView.BufferType.SPANNABLE);
- } else {
- bottomBinding.viewerCaption.setText(postCaption);
- }
- }
- expandCollapseTextView(bottomBinding.viewerCaption, feedModel.getPostCaption());
- bindItem(feedModel, postClickListener);
+ setupComments(feedModel);
+ setupCaption(feedModel);
+ bottomBinding.btnDownload.setOnClickListener(v -> feedItemCallback.onDownloadClick(feedModel));
+ bindItem(feedModel);
}
- private void setLocation(final String locationName, final String locationId) {
+ private void setupComments(final FeedModel feedModel) {
+ final long commentsCount = feedModel.getCommentsCount();
+ bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
+ bottomBinding.commentsCount.setOnClickListener(v -> feedItemCallback.onCommentsClick(feedModel));
+ }
+
+ private void setupProfilePic(final FeedModel feedModel) {
+ final ProfileModel profileModel = feedModel.getProfileModel();
+ if (profileModel != null) {
+ topBinding.ivProfilePic.setOnClickListener(v -> feedItemCallback.onProfilePicClick(feedModel, topBinding.ivProfilePic));
+ topBinding.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
+ setupTitle(feedModel);
+ }
+ }
+
+ private void setupTitle(final FeedModel feedModel) {
+ // final int titleLen = profileModel.getUsername().length() + 1;
+ // final SpannableString spannableString = new SpannableString();
+ // spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
+ final ProfileModel profileModel = feedModel.getProfileModel();
+ final String title = "@" + profileModel.getUsername();
+ topBinding.title.setText(title);
+ topBinding.title.setOnClickListener(v -> feedItemCallback.onNameClick(feedModel, topBinding.ivProfilePic));
+ }
+
+ private void setupCaption(final FeedModel feedModel) {
+ bottomBinding.viewerCaption.clearOnMentionClickListeners();
+ bottomBinding.viewerCaption.clearOnHashtagClickListeners();
+ bottomBinding.viewerCaption.clearOnURLClickListeners();
+ bottomBinding.viewerCaption.clearOnEmailClickListeners();
+ final CharSequence postCaption = feedModel.getPostCaption();
+ final boolean captionEmpty = TextUtils.isEmpty(postCaption);
+ bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
+ if (captionEmpty) return;
+ bottomBinding.viewerCaption.setText(postCaption);
+ bottomBinding.viewerCaption.setMaxLines(MAX_LINES_COLLAPSED);
+ bottomBinding.viewerCaption.setEllipsize(END);
+ bottomBinding.viewerCaption.setOnClickListener(v -> bottomBinding.getRoot().post(() -> {
+ TransitionManager.beginDelayedTransition(bottomBinding.getRoot());
+ if (bottomBinding.viewerCaption.getMaxLines() == MAX_LINES_COLLAPSED) {
+ bottomBinding.viewerCaption.setMaxLines(Integer.MAX_VALUE);
+ bottomBinding.viewerCaption.setEllipsize(null);
+ return;
+ }
+ bottomBinding.viewerCaption.setMaxLines(MAX_LINES_COLLAPSED);
+ bottomBinding.viewerCaption.setEllipsize(END);
+ }));
+ bottomBinding.viewerCaption.addOnMentionClickListener(autoLinkItem -> feedItemCallback.onMentionClick(autoLinkItem.getOriginalText()));
+ bottomBinding.viewerCaption.addOnHashtagListener(autoLinkItem -> feedItemCallback.onHashtagClick(autoLinkItem.getOriginalText()));
+ bottomBinding.viewerCaption.addOnEmailClickListener(autoLinkItem -> feedItemCallback.onEmailClick(autoLinkItem.getOriginalText()));
+ bottomBinding.viewerCaption.addOnURLClickListener(autoLinkItem -> feedItemCallback.onURLClick(autoLinkItem.getOriginalText()));
+ }
+
+ private void setupLocation(final FeedModel feedModel) {
+ final String locationName = feedModel.getLocationName();
if (TextUtils.isEmpty(locationName)) {
topBinding.location.setVisibility(View.GONE);
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
@@ -101,46 +113,9 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
));
- topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location, locationId, false, true));
+ topBinding.location.setOnClickListener(v -> feedItemCallback.onLocationClick(feedModel));
}
}
- /**
- * expands or collapses {@link RamboTextView} [stg idek why i wrote this documentation]
- *
- * @param textView the {@link RamboTextView} view, to expand and collapse
- * @param caption caption
- * @return isExpanded
- */
- public static boolean expandCollapseTextView(@NonNull final RamboTextView textView, final CharSequence caption) {
- if (TextUtils.isEmpty(caption)) return false;
-
- final TextView.BufferType bufferType = caption instanceof Spanned ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL;
-
- if (textView.isCaptionExpanded()) {
- textView.setText(caption, bufferType);
- // textView.setCaptionIsExpanded(false);
- return true;
- }
- int i = TextUtils.indexOfChar(caption, '\r', 0);
- if (i == -1) i = TextUtils.indexOfChar(caption, '\n', 0);
- if (i == -1) i = MAX_CHARS;
-
- final int captionLen = caption.length();
- final int minTrim = Math.min(MAX_CHARS, i);
- if (captionLen <= minTrim) return false;
-
- if (TextUtils.hasMentions(caption))
- textView.setText(TextUtils.getMentionText(caption), TextView.BufferType.SPANNABLE);
- // textView.setCaptionIsExpandable(true);
- // textView.setCaptionIsExpanded(true);
- return true;
- }
-
- public abstract void bindItem(final FeedModel feedModel,
- final FeedAdapterV2.OnPostClickListener postClickListener);
-
- public void clearAnimation() {
- itemView.clearAnimation();
- }
+ public abstract void bindItem(final FeedModel feedModel);
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java
index c67a4808..633886a4 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java
@@ -16,7 +16,6 @@ import com.facebook.imagepipeline.request.ImageRequestBuilder;
import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.databinding.ItemFeedPhotoBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.utils.TextUtils;
@@ -24,17 +23,15 @@ public class FeedPhotoViewHolder extends FeedItemViewHolder {
private static final String TAG = "FeedPhotoViewHolder";
private final ItemFeedPhotoBinding binding;
- // private final long animationDuration;
+ private final FeedAdapterV2.FeedItemCallback feedItemCallback;
public FeedPhotoViewHolder(@NonNull final ItemFeedPhotoBinding binding,
- final MentionClickListener mentionClickListener,
- final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
- super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ final FeedAdapterV2.FeedItemCallback feedItemCallback) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, feedItemCallback);
this.binding = binding;
- // this.animationDuration = animationDuration;
- binding.itemFeedBottom.videoViewsContainer.setVisibility(View.GONE);
- binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
+ this.feedItemCallback = feedItemCallback;
+ binding.itemFeedBottom.tvVideoViews.setVisibility(View.GONE);
+ // binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
binding.imageViewer.setAllowTouchInterceptionWhileZoomed(false);
final GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(itemView.getContext().getResources())
.setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER)
@@ -43,85 +40,39 @@ public class FeedPhotoViewHolder extends FeedItemViewHolder {
}
@Override
- public void bindItem(final FeedModel feedModel,
- final FeedAdapterV2.OnPostClickListener postClickListener) {
+ public void bindItem(final FeedModel feedModel) {
if (feedModel == null) {
return;
}
- setDimensions(feedModel);
- showOrHideDetails(false);
- final String thumbnailUrl = feedModel.getThumbnailUrl();
- String url = feedModel.getDisplayUrl();
- if (TextUtils.isEmpty(url)) url = thumbnailUrl;
- final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
- .setLocalThumbnailPreviewsEnabled(true)
- .setProgressiveRenderingEnabled(true)
- .build();
- binding.imageViewer.setController(Fresco.newDraweeControllerBuilder()
- .setImageRequest(requestBuilder)
- .setOldController(binding.imageViewer.getController())
- .setLowResImageRequest(ImageRequest.fromUri(thumbnailUrl))
- .build());
- binding.imageViewer.setTapListener(new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onSingleTapConfirmed(final MotionEvent e) {
- if (postClickListener != null) {
- postClickListener.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.imageViewer);
- return true;
+ binding.getRoot().post(() -> {
+ setDimensions(feedModel);
+ final String thumbnailUrl = feedModel.getThumbnailUrl();
+ String url = feedModel.getDisplayUrl();
+ if (TextUtils.isEmpty(url)) url = thumbnailUrl;
+ final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
+ // .setLocalThumbnailPreviewsEnabled(true)
+ // .setProgressiveRenderingEnabled(true)
+ .build();
+ binding.imageViewer.setController(Fresco.newDraweeControllerBuilder()
+ .setImageRequest(requestBuilder)
+ .setOldController(binding.imageViewer.getController())
+ .setLowResImageRequest(ImageRequest.fromUri(thumbnailUrl))
+ .build());
+ binding.imageViewer.setTapListener(new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapConfirmed(final MotionEvent e) {
+ if (feedItemCallback != null) {
+ feedItemCallback.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.imageViewer);
+ return true;
+ }
+ return false;
}
- return false;
- }
+ });
});
}
private void setDimensions(final FeedModel feedModel) {
- // final ViewGroup.LayoutParams layoutParams = binding.imageViewer.getLayoutParams();
- // final int deviceWidth = Utils.displayMetrics.widthPixels;
- // final int spanWidth = deviceWidth / spanCount;
- // final int spanHeight = NumberUtils.getResultingHeight(spanWidth, feedModel.getImageHeight(), feedModel.getImageWidth());
- // final int width = spanWidth == 0 ? deviceWidth : spanWidth;
- // final int height = spanHeight == 0 ? deviceWidth + 1 : spanHeight;
final float aspectRatio = (float) feedModel.getImageWidth() / feedModel.getImageHeight();
binding.imageViewer.setAspectRatio(aspectRatio);
- // Log.d(TAG, "setDimensions: aspectRatio:" + aspectRatio);
- // if (animate) {
- // Animation animation = AnimationUtils.expand(
- // binding.imageViewer,
- // layoutParams.width,
- // layoutParams.height,
- // width,
- // height,
- // new Animation.AnimationListener() {
- // @Override
- // public void onAnimationStart(final Animation animation) {
- // showOrHideDetails(spanCount);
- // }
- //
- // @Override
- // public void onAnimationEnd(final Animation animation) {
- // // showOrHideDetails(spanCount);
- // }
- //
- // @Override
- // public void onAnimationRepeat(final Animation animation) {
- //
- // }
- // });
- // binding.imageViewer.startAnimation(animation);
- // } else {
- // layoutParams.width = width;
- // layoutParams.height = height;
- // binding.imageViewer.requestLayout();
- // }
- }
-
- private void showOrHideDetails(final boolean show) {
- if (show) {
- binding.itemFeedTop.getRoot().setVisibility(View.VISIBLE);
- binding.itemFeedBottom.getRoot().setVisibility(View.VISIBLE);
- } else {
- binding.itemFeedTop.getRoot().setVisibility(View.GONE);
- binding.itemFeedBottom.getRoot().setVisibility(View.GONE);
- }
}
}
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
index 12cde610..2b71cd7c 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedSliderViewHolder.java
@@ -21,11 +21,10 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import java.util.List;
-import awais.instagrabber.R;
import awais.instagrabber.adapters.FeedAdapterV2;
+import awais.instagrabber.adapters.SliderCallbackAdapter;
import awais.instagrabber.adapters.SliderItemsAdapter;
import awais.instagrabber.databinding.ItemFeedSliderBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.PostChild;
import awais.instagrabber.models.enums.MediaItemType;
@@ -40,25 +39,20 @@ public class FeedSliderViewHolder extends FeedItemViewHolder {
private static final boolean shouldAutoPlay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
private final ItemFeedSliderBinding binding;
+ private final FeedAdapterV2.FeedItemCallback feedItemCallback;
private final DefaultDataSourceFactory dataSourceFactory;
- private final PlayerChangeListener playerChangeListener = (position, player) -> {
- pagerPlayer = player;
- playerPosition = position;
- };
-
private CacheDataSourceFactory cacheDataSourceFactory;
private SimpleExoPlayer pagerPlayer;
private int playerPosition = 0;
public FeedSliderViewHolder(@NonNull final ItemFeedSliderBinding binding,
- final MentionClickListener mentionClickListener,
- final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
- super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ final FeedAdapterV2.FeedItemCallback feedItemCallback) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, feedItemCallback);
this.binding = binding;
- binding.itemFeedBottom.videoViewsContainer.setVisibility(View.GONE);
- binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
+ this.feedItemCallback = feedItemCallback;
+ binding.itemFeedBottom.tvVideoViews.setVisibility(View.GONE);
+ // binding.itemFeedBottom.btnMute.setVisibility(View.GONE);
final ViewGroup.LayoutParams layoutParams = binding.mediaList.getLayoutParams();
layoutParams.height = Utils.displayMetrics.widthPixels + 1;
binding.mediaList.setLayoutParams(layoutParams);
@@ -71,31 +65,31 @@ public class FeedSliderViewHolder extends FeedItemViewHolder {
}
@Override
- public void bindItem(final FeedModel feedModel,
- final FeedAdapterV2.OnPostClickListener postClickListener) {
+ public void bindItem(final FeedModel feedModel) {
final List sliderItems = feedModel.getSliderItems();
final int sliderItemLen = sliderItems != null ? sliderItems.size() : 0;
if (sliderItemLen <= 0) return;
final String text = "1/" + sliderItemLen;
binding.mediaCounter.setText(text);
binding.mediaList.setOffscreenPageLimit(1);
- SliderItemsAdapter adapter = (SliderItemsAdapter) binding.mediaList.getAdapter();
- if (adapter == null) {
- adapter = new SliderItemsAdapter();
- }
- // adapter.setSpanCount(spanCount);
+ final SliderItemsAdapter adapter = new SliderItemsAdapter(null, null, false, new SliderCallbackAdapter() {
+ @Override
+ public void onItemClicked(final int position) {
+ feedItemCallback.onSliderClick(feedModel, position);
+ }
+ });
binding.mediaList.setAdapter(adapter);
binding.mediaList.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(final int position) {
if (position >= sliderItemLen) return;
+ final String text = (position + 1) + "/" + sliderItemLen;
+ binding.mediaCounter.setText(text);
setDimensions(binding.mediaList, sliderItems.get(position));
}
});
setDimensions(binding.mediaList, sliderItems.get(0));
-
- //noinspection deprecation
// binding.mediaList.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
// private int prevPos = 0;
//
@@ -149,15 +143,15 @@ public class FeedSliderViewHolder extends FeedItemViewHolder {
final SimpleExoPlayer player = (SimpleExoPlayer) tag;
final float intVol = player.getVolume() == 0f ? 1f : 0f;
player.setVolume(intVol);
- binding.itemFeedBottom.btnMute.setImageResource(intVol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
- Utils.sessionVolumeFull = intVol == 1f;
+ // binding.itemFeedBottom.btnMute.setImageResource(intVol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
+ // Utils.sessionVolumeFull = intVol == 1f;
};
- final PostChild firstItem = sliderItems.get(0);
- if (firstItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
- binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
- }
- binding.itemFeedBottom.btnMute.setImageResource(Utils.sessionVolumeFull ? R.drawable.ic_volume_off_24 : R.drawable.ic_volume_up_24);
- binding.itemFeedBottom.btnMute.setOnClickListener(muteClickListener);
+ // final PostChild firstItem = sliderItems.get(0);
+ // if (firstItem.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
+ // binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
+ // }
+ // binding.itemFeedBottom.btnMute.setImageResource(Utils.sessionVolumeFull ? R.drawable.ic_volume_off_24 : R.drawable.ic_volume_up_24);
+ // binding.itemFeedBottom.btnMute.setOnClickListener(muteClickListener);
}
private void setDimensions(final View view, final PostChild model) {
diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java
index b124699a..e82e9893 100644
--- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java
+++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java
@@ -12,12 +12,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
-import awais.instagrabber.R;
import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.customviews.VideoPlayerCallbackAdapter;
import awais.instagrabber.customviews.VideoPlayerViewHelper;
import awais.instagrabber.databinding.ItemFeedVideoBinding;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NumberUtils;
@@ -29,6 +27,7 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
private static final String TAG = "FeedVideoViewHolder";
private final ItemFeedVideoBinding binding;
+ private final FeedAdapterV2.FeedItemCallback feedItemCallback;
private final Handler handler;
private final DefaultDataSourceFactory dataSourceFactory;
@@ -43,12 +42,11 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
// };
public FeedVideoViewHolder(@NonNull final ItemFeedVideoBinding binding,
- final MentionClickListener mentionClickListener,
- final View.OnClickListener clickListener,
- final View.OnLongClickListener longClickListener) {
- super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, mentionClickListener, clickListener, longClickListener);
+ final FeedAdapterV2.FeedItemCallback feedItemCallback) {
+ super(binding.getRoot(), binding.itemFeedTop, binding.itemFeedBottom, feedItemCallback);
this.binding = binding;
- binding.itemFeedBottom.videoViewsContainer.setVisibility(View.VISIBLE);
+ this.feedItemCallback = feedItemCallback;
+ binding.itemFeedBottom.tvVideoViews.setVisibility(View.VISIBLE);
handler = new Handler(Looper.getMainLooper());
final Context context = binding.getRoot().getContext();
dataSourceFactory = new DefaultDataSourceFactory(context, "instagram");
@@ -59,8 +57,7 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
}
@Override
- public void bindItem(final FeedModel feedModel,
- final FeedAdapterV2.OnPostClickListener postClickListener) {
+ public void bindItem(final FeedModel feedModel) {
// Log.d(TAG, "Binding post: " + feedModel.getPostId());
this.feedModel = feedModel;
binding.itemFeedBottom.tvVideoViews.setText(String.valueOf(feedModel.getViewCount()));
@@ -70,12 +67,12 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
@Override
public void onThumbnailClick() {
- postClickListener.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.videoPost.thumbnail);
+ feedItemCallback.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.videoPost.thumbnail);
}
@Override
public void onPlayerViewLoaded() {
- binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
+ // binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE);
final ViewGroup.LayoutParams layoutParams = binding.videoPost.playerView.getLayoutParams();
final int requiredWidth = Utils.displayMetrics.widthPixels;
final int resultingHeight = NumberUtils.getResultingHeight(requiredWidth, feedModel.getImageHeight(), feedModel.getImageWidth());
@@ -97,19 +94,27 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
vol,
aspectRatio,
feedModel.getThumbnailUrl(),
+ false,
null,
videoPlayerCallback);
- binding.itemFeedBottom.btnMute.setOnClickListener(v -> {
- final float newVol = videoPlayerViewHelper.toggleMute();
- setMuteIcon(newVol);
- Utils.sessionVolumeFull = newVol == 1f;
+ binding.videoPost.thumbnail.post(() -> {
+ if (feedModel.getImageHeight() > 0.8 * Utils.displayMetrics.heightPixels) {
+ final ViewGroup.LayoutParams layoutParams = binding.videoPost.thumbnail.getLayoutParams();
+ layoutParams.height = (int) (0.8 * Utils.displayMetrics.heightPixels);
+ binding.videoPost.thumbnail.requestLayout();
+ }
});
- binding.videoPost.playerView.setOnClickListener(v -> videoPlayerViewHelper.togglePlayback());
+ // binding.itemFeedBottom.btnMute.setOnClickListener(v -> {
+ // final float newVol = videoPlayerViewHelper.toggleMute();
+ // setMuteIcon(newVol);
+ // Utils.sessionVolumeFull = newVol == 1f;
+ // });
+ // binding.videoPost.playerView.setOnClickListener(v -> videoPlayerViewHelper.togglePlayback());
}
private void setMuteIcon(final float vol) {
- binding.itemFeedBottom.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
+ // binding.itemFeedBottom.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
}
public FeedModel getCurrentFeedModel() {
@@ -131,14 +136,4 @@ public class FeedVideoViewHolder extends FeedItemViewHolder {
// handler.removeCallbacks(loadRunnable);
// handler.postDelayed(loadRunnable, 800);
// }
-
- private void showOrHideDetails(final boolean show) {
- if (show) {
- binding.itemFeedTop.getRoot().setVisibility(View.VISIBLE);
- binding.itemFeedBottom.getRoot().setVisibility(View.VISIBLE);
- } else {
- binding.itemFeedTop.getRoot().setVisibility(View.GONE);
- binding.itemFeedBottom.getRoot().setVisibility(View.GONE);
- }
- }
}
diff --git a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
index 6107a038..d1736b49 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
@@ -12,7 +12,7 @@ import org.json.JSONObject;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.List;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
@@ -25,23 +25,20 @@ import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
-public final class CommentsFetcher extends AsyncTask {
- private final String shortCode;
- private final FetchListener fetchListener;
+public final class CommentsFetcher extends AsyncTask> {
+ private static final String TAG = "CommentsFetcher";
- /*
- * i fucking spent the whole day on this and fixing all the fucking problems in this class.
- * DO NO FUCK WITH THIS CODE!
- * -AWAiS (The Badak) @the.badak
- */
- public CommentsFetcher(final String shortCode, final FetchListener fetchListener) {
+ private final String shortCode;
+ private final FetchListener> fetchListener;
+
+ public CommentsFetcher(final String shortCode, final FetchListener> fetchListener) {
this.shortCode = shortCode;
this.fetchListener = fetchListener;
}
@NonNull
@Override
- protected CommentModel[] doInBackground(final Void... voids) {
+ protected List doInBackground(final Void... voids) {
/*
"https://www.instagram.com/graphql/query/?query_hash=97b41c52301f77ce508f55e66d17620e&variables=" + "{\"shortcode\":\"" + shortcode + "\",\"first\":50,\"after\":\"" + endCursor + "\"}";
@@ -50,23 +47,20 @@ public final class CommentsFetcher extends AsyncTask
https://www.instagram.com/graphql/query/?query_hash=51fdd02b67508306ad4484ff574a0b62&variables={"comment_id":"18100041898085322","first":50,"after":""}
*/
- final ArrayList commentModels = getParentComments();
-
+ final List commentModels = getParentComments();
for (final CommentModel commentModel : commentModels) {
- final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
+ final List childCommentModels = commentModel.getChildCommentModels();
if (childCommentModels != null) {
- final int childCommentsLen = childCommentModels.length;
-
- final CommentModel lastChild = childCommentModels[childCommentsLen - 1];
+ final int childCommentsLen = childCommentModels.size();
+ final CommentModel lastChild = childCommentModels.get(childCommentsLen - 1);
if (lastChild != null && lastChild.hasNextPage() && !TextUtils.isEmpty(lastChild.getEndCursor())) {
- final CommentModel[] remoteChildComments = getChildComments(commentModel.getId());
+ final List remoteChildComments = getChildComments(commentModel.getId());
commentModel.setChildCommentModels(remoteChildComments);
lastChild.setPageCursor(false, null);
}
}
}
-
- return commentModels.toArray(new CommentModel[0]);
+ return commentModels;
}
@Override
@@ -75,14 +69,13 @@ public final class CommentsFetcher extends AsyncTask
}
@Override
- protected void onPostExecute(final CommentModel[] result) {
+ protected void onPostExecute(final List result) {
if (fetchListener != null) fetchListener.onResult(result);
}
@NonNull
- private synchronized CommentModel[] getChildComments(final String commentId) {
- final ArrayList commentModels = new ArrayList<>();
-
+ private synchronized List getChildComments(final String commentId) {
+ final List commentModels = new ArrayList<>();
String endCursor = "";
while (endCursor != null) {
final String url = "https://www.instagram.com/graphql/query/?query_hash=51fdd02b67508306ad4484ff574a0b62&variables=" +
@@ -96,7 +89,8 @@ public final class CommentsFetcher extends AsyncTask
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break;
else {
final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data")
- .getJSONObject("comment").getJSONObject("edge_threaded_comments");
+ .getJSONObject("comment")
+ .getJSONObject("edge_threaded_comments");
final JSONObject pageInfo = data.getJSONObject("page_info");
endCursor = pageInfo.getString("end_cursor");
@@ -110,43 +104,54 @@ public final class CommentsFetcher extends AsyncTask
if (childComment != null) {
final JSONObject owner = childComment.getJSONObject("owner");
- final ProfileModel profileModel = new ProfileModel(false, false, false,
- owner.getString(Constants.EXTRAS_ID),
- owner.getString(Constants.EXTRAS_USERNAME),
- null, null, null,
- owner.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ final ProfileModel profileModel = new ProfileModel(false,
+ false,
+ false,
+ owner.getString(Constants.EXTRAS_ID),
+ owner.getString(Constants.EXTRAS_USERNAME),
+ null,
+ null,
+ null,
+ owner.getString("profile_pic_url"),
+ null,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false);
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
commentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),
- childComment.getString("text"),
- childComment.getLong("created_at"),
- likedBy != null ? likedBy.optLong("count", 0) : 0,
- childComment.getBoolean("viewer_has_liked"),
- profileModel));
+ childComment.getString("text"),
+ childComment.getLong("created_at"),
+ likedBy != null ? likedBy.optLong("count", 0) : 0,
+ childComment.getBoolean("viewer_has_liked"),
+ profileModel));
}
}
}
}
-
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.ASYNC_COMMENTS_FETCHER, "getChildComments",
- new Pair<>("commentModels.size", commentModels.size()));
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ logCollector.appendException(e,
+ LogCollector.LogFile.ASYNC_COMMENTS_FETCHER,
+ "getChildComments",
+ new Pair<>("commentModels.size", commentModels.size()));
+ if (BuildConfig.DEBUG) Log.e(TAG, "", e);
break;
}
}
- return commentModels.toArray(new CommentModel[0]);
+ return commentModels;
}
@NonNull
- private synchronized ArrayList getParentComments() {
- final ArrayList commentModelsList = new ArrayList<>();
-
+ private synchronized List getParentComments() {
+ final List commentModels = new ArrayList<>();
String endCursor = "";
while (endCursor != null) {
final String url = "https://www.instagram.com/graphql/query/?query_hash=bc3296d1ce80a24b1b6e40b1e72903f5&variables=" +
@@ -160,7 +165,9 @@ public final class CommentsFetcher extends AsyncTask
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break;
else {
final JSONObject parentComments = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data")
- .getJSONObject("shortcode_media").getJSONObject("edge_media_to_parent_comment");
+ .getJSONObject("shortcode_media")
+ .getJSONObject(
+ "edge_media_to_parent_comment");
final JSONObject pageInfo = parentComments.getJSONObject("page_info");
endCursor = pageInfo.optString("end_cursor");
@@ -182,31 +189,37 @@ public final class CommentsFetcher extends AsyncTask
final JSONArray comments = parentComments.getJSONArray("edges");
final int commentsLen = comments.length();
- final CommentModel[] commentModels = new CommentModel[commentsLen];
-
for (int i = 0; i < commentsLen; ++i) {
final JSONObject comment = comments.getJSONObject(i).getJSONObject("node");
final JSONObject owner = comment.getJSONObject("owner");
- final ProfileModel profileModel = new ProfileModel(false, false,
- owner.optBoolean("is_verified"),
- owner.getString(Constants.EXTRAS_ID),
- owner.getString(Constants.EXTRAS_USERNAME),
- null, null, null,
- owner.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ final ProfileModel profileModel = new ProfileModel(false,
+ false,
+ owner.optBoolean("is_verified"),
+ owner.getString(Constants.EXTRAS_ID),
+ owner.getString(Constants.EXTRAS_USERNAME),
+ null,
+ null,
+ null,
+ owner.getString("profile_pic_url"),
+ null,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false);
final JSONObject likedBy = comment.optJSONObject("edge_liked_by");
final String commentId = comment.getString(Constants.EXTRAS_ID);
- commentModels[i] = new CommentModel(commentId,
- comment.getString("text"),
- comment.getLong("created_at"),
- likedBy != null ? likedBy.optLong("count", 0) : 0,
- comment.getBoolean("viewer_has_liked"),
- profileModel);
-
+ final CommentModel commentModel = new CommentModel(commentId,
+ comment.getString("text"),
+ comment.getLong("created_at"),
+ likedBy != null ? likedBy.optLong("count", 0) : 0,
+ comment.getBoolean("viewer_has_liked"),
+ profileModel);
JSONObject tempJsonObject;
-
final JSONArray childCommentsArray;
final int childCommentsLen;
if ((tempJsonObject = comment.optJSONObject("edge_threaded_comments")) != null &&
@@ -223,47 +236,53 @@ public final class CommentsFetcher extends AsyncTask
hasNextPage = false;
}
- final CommentModel[] childCommentModels = new CommentModel[childCommentsLen];
+ final List childCommentModels = new ArrayList<>();
for (int j = 0; j < childCommentsLen; ++j) {
final JSONObject childComment = childCommentsArray.getJSONObject(j).getJSONObject("node");
tempJsonObject = childComment.getJSONObject("owner");
- final ProfileModel childProfileModel = new ProfileModel(false, false,
- tempJsonObject.optBoolean("is_verified"),
- tempJsonObject.getString(Constants.EXTRAS_ID),
- tempJsonObject.getString(Constants.EXTRAS_USERNAME),
- null, null, null,
- tempJsonObject.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ final ProfileModel childProfileModel = new ProfileModel(false,
+ false,
+ tempJsonObject.optBoolean("is_verified"),
+ tempJsonObject.getString(Constants.EXTRAS_ID),
+ tempJsonObject.getString(Constants.EXTRAS_USERNAME),
+ null,
+ null,
+ null,
+ tempJsonObject.getString("profile_pic_url"),
+ null,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false);
tempJsonObject = childComment.optJSONObject("edge_liked_by");
- childCommentModels[j] = new CommentModel(childComment.getString(Constants.EXTRAS_ID),
- childComment.getString("text"),
- childComment.getLong("created_at"),
- tempJsonObject != null ? tempJsonObject.optLong("count", 0) : 0,
- childComment.getBoolean("viewer_has_liked"),
- childProfileModel);
+ childCommentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),
+ childComment.getString("text"),
+ childComment.getLong("created_at"),
+ tempJsonObject != null ? tempJsonObject.optLong("count", 0) : 0,
+ childComment.getBoolean("viewer_has_liked"),
+ childProfileModel));
}
-
- childCommentModels[childCommentsLen - 1].setPageCursor(hasNextPage, childEndCursor);
-
- commentModels[i].setChildCommentModels(childCommentModels);
+ childCommentModels.get(childCommentsLen - 1).setPageCursor(hasNextPage, childEndCursor);
+ commentModel.setChildCommentModels(childCommentModels);
+ commentModels.add(commentModel);
}
}
-
- Collections.addAll(commentModelsList, commentModels);
}
conn.disconnect();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_COMMENTS_FETCHER, "getParentComments",
- new Pair<>("commentModelsList.size", commentModelsList.size()));
+ new Pair<>("commentModelsList.size", commentModels.size()));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
break;
}
}
-
- return commentModelsList;
+ return commentModels;
}
}
diff --git a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java
index c91d92f9..3895b27c 100644
--- a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java
+++ b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java
@@ -19,12 +19,10 @@ import java.util.ArrayList;
import java.util.List;
import awais.instagrabber.adapters.FeedAdapterV2;
-import awais.instagrabber.adapters.FeedAdapterV2.OnPostClickListener;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.PostFetcher;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtBottom;
import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.utils.Constants;
@@ -34,12 +32,10 @@ import awais.instagrabber.viewmodels.FeedViewModel;
public class PostsRecyclerView extends RecyclerView {
private static final String TAG = "PostsRecyclerView";
- private StaggeredGridLayoutManager gridLayoutManager;
+ private StaggeredGridLayoutManager layoutManager;
private PostsLayoutPreferences layoutPreferences;
private PostFetcher.PostFetchService postFetchService;
private Transition transition;
- private OnClickListener postViewClickListener;
- private MentionClickListener mentionClickListener;
private PostFetcher postFetcher;
private ViewModelStoreOwner viewModelStoreOwner;
private FeedAdapterV2 feedAdapter;
@@ -48,7 +44,7 @@ public class PostsRecyclerView extends RecyclerView {
private boolean initCalled = false;
private GridSpacingItemDecoration gridSpacingItemDecoration;
private RecyclerLazyLoaderAtBottom lazyLoader;
- private OnPostClickListener onPostClickListener;
+ private FeedAdapterV2.FeedItemCallback feedItemCallback;
private final FetchListener> fetchListener = new FetchListener>() {
@Override
@@ -109,13 +105,8 @@ public class PostsRecyclerView extends RecyclerView {
return this;
}
- public PostsRecyclerView setOnPostClickListener(@NonNull final OnPostClickListener onPostClickListener) {
- this.onPostClickListener = onPostClickListener;
- return this;
- }
-
- public PostsRecyclerView setMentionClickListener(final MentionClickListener mentionClickListener) {
- this.mentionClickListener = mentionClickListener;
+ public PostsRecyclerView setFeedItemCallback(@NonNull final FeedAdapterV2.FeedItemCallback feedItemCallback) {
+ this.feedItemCallback = feedItemCallback;
return this;
}
@@ -160,30 +151,19 @@ public class PostsRecyclerView extends RecyclerView {
private void initTransition() {
transition = new ChangeBounds();
- // transition.addListener(new TransitionListenerAdapter(){
- // @Override
- // public void onTransitionEnd(@NonNull final Transition transition) {
- // super.onTransitionEnd(transition);
- // }
- // });
transition.setDuration(300);
}
private void initLayoutManager() {
- gridLayoutManager = new StaggeredGridLayoutManager(layoutPreferences.getColCount(), StaggeredGridLayoutManager.VERTICAL);
- setLayoutManager(gridLayoutManager);
+ layoutManager = new StaggeredGridLayoutManager(layoutPreferences.getColCount(), StaggeredGridLayoutManager.VERTICAL);
+ if (layoutPreferences.getHasGap()) {
+ addItemDecoration(gridSpacingItemDecoration);
+ }
+ setLayoutManager(layoutManager);
}
private void initAdapter() {
- feedAdapter = new FeedAdapterV2(
- layoutPreferences,
- postViewClickListener,
- mentionClickListener,
- (feedModel, view, postImage) -> {
- if (onPostClickListener != null) {
- onPostClickListener.onPostClick(feedModel, view, postImage);
- }
- });
+ feedAdapter = new FeedAdapterV2(layoutPreferences, feedItemCallback);
feedAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);
setAdapter(feedAdapter);
}
@@ -194,7 +174,8 @@ public class PostsRecyclerView extends RecyclerView {
postFetcher = new PostFetcher(postFetchService, fetchListener);
addItemDecoration(gridSpacingItemDecoration);
setHasFixedSize(true);
- lazyLoader = new RecyclerLazyLoaderAtBottom(gridLayoutManager, (page) -> {
+ setNestedScrollingEnabled(true);
+ lazyLoader = new RecyclerLazyLoaderAtBottom(layoutManager, (page) -> {
if (postFetcher.hasMore()) {
postFetcher.fetchNextPage();
dispatchFetchStatus();
@@ -211,8 +192,23 @@ public class PostsRecyclerView extends RecyclerView {
feedAdapter.notifyDataSetChanged();
if (!layoutPreferences.getHasGap()) {
removeItemDecoration(gridSpacingItemDecoration);
+ } else {
+ addItemDecoration(gridSpacingItemDecoration);
+ }
+ if (layoutPreferences.getType() == PostsLayoutPreferences.PostsLayoutType.LINEAR) {
+ if (layoutManager.getSpanCount() != 1) {
+ layoutManager.setSpanCount(1);
+ setAdapter(null);
+ setAdapter(feedAdapter);
+ }
+ } else {
+ boolean shouldRedraw = layoutManager.getSpanCount() == 1;
+ layoutManager.setSpanCount(layoutPreferences.getColCount());
+ if (shouldRedraw) {
+ setAdapter(null);
+ setAdapter(feedAdapter);
+ }
}
- gridLayoutManager.setSpanCount(layoutPreferences.getColCount());
});
}
diff --git a/app/src/main/java/awais/instagrabber/customviews/RamboTextViewV2.java b/app/src/main/java/awais/instagrabber/customviews/RamboTextViewV2.java
new file mode 100644
index 00000000..d17faedd
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/customviews/RamboTextViewV2.java
@@ -0,0 +1,152 @@
+package awais.instagrabber.customviews;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.github.armcha.autolink.AutoLinkItem;
+import io.github.armcha.autolink.AutoLinkTextView;
+import io.github.armcha.autolink.MODE_EMAIL;
+import io.github.armcha.autolink.MODE_HASHTAG;
+import io.github.armcha.autolink.MODE_MENTION;
+import io.github.armcha.autolink.MODE_URL;
+import io.github.armcha.autolink.Mode;
+import kotlin.Unit;
+
+public class RamboTextViewV2 extends AutoLinkTextView {
+ private final List onMentionClickListeners = new ArrayList<>();
+ private final List onHashtagClickListeners = new ArrayList<>();
+ private final List onURLClickListeners = new ArrayList<>();
+ private final List onEmailClickListeners = new ArrayList<>();
+
+ public RamboTextViewV2(@NotNull final Context context,
+ @Nullable final AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ addAutoLinkMode(MODE_HASHTAG.INSTANCE, MODE_MENTION.INSTANCE, MODE_EMAIL.INSTANCE, MODE_URL.INSTANCE);
+ onAutoLinkClick(autoLinkItem -> {
+ final Mode mode = autoLinkItem.getMode();
+ if (mode.equals(MODE_MENTION.INSTANCE)) {
+ for (final OnMentionClickListener onMentionClickListener : onMentionClickListeners) {
+ onMentionClickListener.onMentionClick(autoLinkItem);
+ }
+ return Unit.INSTANCE;
+ }
+ if (mode.equals(MODE_HASHTAG.INSTANCE)) {
+ for (final OnHashtagClickListener onHashtagClickListener : onHashtagClickListeners) {
+ onHashtagClickListener.onHashtagClick(autoLinkItem);
+ }
+ return Unit.INSTANCE;
+ }
+ if (mode.equals(MODE_URL.INSTANCE)) {
+ for (final OnURLClickListener onURLClickListener : onURLClickListeners) {
+ onURLClickListener.onURLClick(autoLinkItem);
+ }
+ return Unit.INSTANCE;
+ }
+ if (mode.equals(MODE_EMAIL.INSTANCE)) {
+ for (final OnEmailClickListener onEmailClickListener : onEmailClickListeners) {
+ onEmailClickListener.onEmailClick(autoLinkItem);
+ }
+ return Unit.INSTANCE;
+ }
+ return Unit.INSTANCE;
+ });
+ }
+
+ public void addOnMentionClickListener(final OnMentionClickListener onMentionClickListener) {
+ if (onMentionClickListener == null) {
+ return;
+ }
+ onMentionClickListeners.add(onMentionClickListener);
+ }
+
+ public void removeOnMentionClickListener(final OnMentionClickListener onMentionClickListener) {
+ if (onMentionClickListener == null) {
+ return;
+ }
+ onMentionClickListeners.remove(onMentionClickListener);
+ }
+
+ public void clearOnMentionClickListeners() {
+ onMentionClickListeners.clear();
+ }
+
+ public void addOnHashtagListener(final OnHashtagClickListener onHashtagClickListener) {
+ if (onHashtagClickListener == null) {
+ return;
+ }
+ onHashtagClickListeners.add(onHashtagClickListener);
+ }
+
+ public void removeOnHashtagListener(final OnHashtagClickListener onHashtagClickListener) {
+ if (onHashtagClickListener == null) {
+ return;
+ }
+ onHashtagClickListeners.remove(onHashtagClickListener);
+ }
+
+ public void clearOnHashtagClickListeners() {
+ onHashtagClickListeners.clear();
+ }
+
+ public void addOnURLClickListener(final OnURLClickListener onURLClickListener) {
+ if (onURLClickListener == null) {
+ return;
+ }
+ onURLClickListeners.add(onURLClickListener);
+ }
+
+ public void removeOnURLClickListener(final OnURLClickListener onURLClickListener) {
+ if (onURLClickListener == null) {
+ return;
+ }
+ onURLClickListeners.remove(onURLClickListener);
+ }
+
+ public void clearOnURLClickListeners() {
+ onURLClickListeners.clear();
+ }
+
+ public void addOnEmailClickListener(final OnEmailClickListener onEmailClickListener) {
+ if (onEmailClickListener == null) {
+ return;
+ }
+ onEmailClickListeners.add(onEmailClickListener);
+ }
+
+ public void removeOnEmailClickListener(final OnEmailClickListener onEmailClickListener) {
+ if (onEmailClickListener == null) {
+ return;
+ }
+ onEmailClickListeners.remove(onEmailClickListener);
+ }
+
+ public void clearOnEmailClickListeners() {
+ onEmailClickListeners.clear();
+ }
+
+ public interface OnMentionClickListener {
+ void onMentionClick(final AutoLinkItem autoLinkItem);
+ }
+
+ public interface OnHashtagClickListener {
+ void onHashtagClick(final AutoLinkItem autoLinkItem);
+ }
+
+ public interface OnURLClickListener {
+ void onURLClick(final AutoLinkItem autoLinkItem);
+ }
+
+ public interface OnEmailClickListener {
+ void onEmailClick(final AutoLinkItem autoLinkItem);
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/customviews/SharedElementTransitionDialogFragment.java b/app/src/main/java/awais/instagrabber/customviews/SharedElementTransitionDialogFragment.java
index bec8a690..e6e16b0a 100644
--- a/app/src/main/java/awais/instagrabber/customviews/SharedElementTransitionDialogFragment.java
+++ b/app/src/main/java/awais/instagrabber/customviews/SharedElementTransitionDialogFragment.java
@@ -77,6 +77,7 @@ public abstract class SharedElementTransitionDialogFragment extends DialogFragme
final View startView = startViews.get(key);
final View destView = destViews.get(key);
final ViewBounds viewBounds = viewBoundsMap.get(key);
+ if (startView == null || destView == null || viewBounds == null) return;
onEndSharedElementAnimation(startView, destView, viewBounds);
}
}
@@ -87,6 +88,7 @@ public abstract class SharedElementTransitionDialogFragment extends DialogFragme
final View startView = startViews.get(key);
final View destView = destViews.get(key);
final ViewBounds viewBounds = viewBoundsMap.get(key);
+ if (startView == null || destView == null || viewBounds == null) return;
onBeforeSharedElementAnimation(startView, destView, viewBounds);
setDestBounds(key);
}
diff --git a/app/src/main/java/awais/instagrabber/customviews/VideoPlayerViewHelper.java b/app/src/main/java/awais/instagrabber/customviews/VideoPlayerViewHelper.java
index eb23cbe8..04e07854 100644
--- a/app/src/main/java/awais/instagrabber/customviews/VideoPlayerViewHelper.java
+++ b/app/src/main/java/awais/instagrabber/customviews/VideoPlayerViewHelper.java
@@ -45,6 +45,7 @@ public class VideoPlayerViewHelper implements Player.EventListener {
private final float initialVolume;
private final float thumbnailAspectRatio;
private final String thumbnailUrl;
+ private final boolean loadPlayerOnClick;
private final awais.instagrabber.databinding.LayoutExoCustomControlsBinding controlsBinding;
private final VideoPlayerCallback videoPlayerCallback;
private final String videoUrl;
@@ -58,6 +59,7 @@ public class VideoPlayerViewHelper implements Player.EventListener {
final float initialVolume,
final float thumbnailAspectRatio,
final String thumbnailUrl,
+ final boolean loadPlayerOnClick,
final LayoutExoCustomControlsBinding controlsBinding,
final VideoPlayerCallback videoPlayerCallback) {
this.context = context;
@@ -65,6 +67,7 @@ public class VideoPlayerViewHelper implements Player.EventListener {
this.initialVolume = initialVolume;
this.thumbnailAspectRatio = thumbnailAspectRatio;
this.thumbnailUrl = thumbnailUrl;
+ this.loadPlayerOnClick = loadPlayerOnClick;
this.controlsBinding = controlsBinding;
this.videoPlayerCallback = videoPlayerCallback;
this.videoUrl = videoUrl;
@@ -77,7 +80,9 @@ public class VideoPlayerViewHelper implements Player.EventListener {
if (videoPlayerCallback != null) {
videoPlayerCallback.onThumbnailClick();
}
- loadPlayer();
+ if (loadPlayerOnClick) {
+ loadPlayer();
+ }
});
setThumbnail();
setupControls();
@@ -262,38 +267,31 @@ public class VideoPlayerViewHelper implements Player.EventListener {
speedPopup.setOnMenuItemClickListener(item -> {
float nextSpeed;
int textResId;
- switch (item.getItemId()) {
- case R.id.pt_two_five_x:
- nextSpeed = 0.25f;
- textResId = R.string.pt_two_five_x;
- break;
- case R.id.pt_five_x:
- nextSpeed = 0.5f;
- textResId = R.string.pt_five_x;
- break;
- case R.id.pt_seven_five_x:
- nextSpeed = 0.75f;
- textResId = R.string.pt_seven_five_x;
- break;
- case R.id.one_x:
- nextSpeed = 1f;
- textResId = R.string.one_x;
- break;
- case R.id.one_pt_two_five_x:
- nextSpeed = 1.25f;
- textResId = R.string.one_pt_two_five_x;
- break;
- case R.id.one_pt_five_x:
- nextSpeed = 1.5f;
- textResId = R.string.one_pt_five_x;
- break;
- case R.id.two_x:
- nextSpeed = 2f;
- textResId = R.string.two_x;
- break;
- default:
- nextSpeed = 1;
- textResId = R.string.one_x;
+ int itemId = item.getItemId();
+ if (itemId == R.id.pt_two_five_x) {
+ nextSpeed = 0.25f;
+ textResId = R.string.pt_two_five_x;
+ } else if (itemId == R.id.pt_five_x) {
+ nextSpeed = 0.5f;
+ textResId = R.string.pt_five_x;
+ } else if (itemId == R.id.pt_seven_five_x) {
+ nextSpeed = 0.75f;
+ textResId = R.string.pt_seven_five_x;
+ } else if (itemId == R.id.one_x) {
+ nextSpeed = 1f;
+ textResId = R.string.one_x;
+ } else if (itemId == R.id.one_pt_two_five_x) {
+ nextSpeed = 1.25f;
+ textResId = R.string.one_pt_two_five_x;
+ } else if (itemId == R.id.one_pt_five_x) {
+ nextSpeed = 1.5f;
+ textResId = R.string.one_pt_five_x;
+ } else if (itemId == R.id.two_x) {
+ nextSpeed = 2f;
+ textResId = R.string.two_x;
+ } else {
+ nextSpeed = 1;
+ textResId = R.string.one_x;
}
player.setPlaybackParameters(new PlaybackParameters(nextSpeed));
controlsBinding.speed.setText(textResId);
diff --git a/app/src/main/java/awais/instagrabber/dialogs/PostsLayoutPreferencesDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/PostsLayoutPreferencesDialogFragment.java
index e051a3e6..bee6256b 100644
--- a/app/src/main/java/awais/instagrabber/dialogs/PostsLayoutPreferencesDialogFragment.java
+++ b/app/src/main/java/awais/instagrabber/dialogs/PostsLayoutPreferencesDialogFragment.java
@@ -82,26 +82,31 @@ public class PostsLayoutPreferencesDialogFragment extends DialogFragment {
}
private void initLayoutToggle() {
- binding.layoutToggle.check(getSelectedLayoutId());
- // binding.staggeredOrGridOptions.setVisibility(getSelectedLayoutId() != R.id.layout_linear ? View.VISIBLE : View.GONE);
+ final int selectedLayoutId = getSelectedLayoutId();
+ binding.layoutToggle.check(selectedLayoutId);
+ if (selectedLayoutId == R.id.layout_linear) {
+ binding.staggeredOrGridOptions.setVisibility(View.GONE);
+ }
binding.layoutToggle.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (isChecked) {
- switch (checkedId) {
- case R.id.layout_linear:
- preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.LINEAR);
- binding.staggeredOrGridOptions.setVisibility(View.GONE);
- break;
- case R.id.layout_staggered:
- preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.STAGGERED_GRID);
- binding.staggeredOrGridOptions.setVisibility(View.VISIBLE);
- initStaggeredOrGridOptions();
- break;
- case R.id.layout_grid:
- default:
- preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.GRID);
- binding.staggeredOrGridOptions.setVisibility(View.VISIBLE);
- initStaggeredOrGridOptions();
- break;
+ if (checkedId == R.id.layout_linear) {
+ preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.LINEAR);
+ preferencesBuilder.setColCount(1);
+ binding.staggeredOrGridOptions.setVisibility(View.GONE);
+ } else if (checkedId == R.id.layout_staggered) {
+ preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.STAGGERED_GRID);
+ if (preferencesBuilder.getColCount() == 1) {
+ preferencesBuilder.setColCount(2);
+ }
+ binding.staggeredOrGridOptions.setVisibility(View.VISIBLE);
+ initStaggeredOrGridOptions();
+ } else {
+ preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.GRID);
+ if (preferencesBuilder.getColCount() == 1) {
+ preferencesBuilder.setColCount(2);
+ }
+ binding.staggeredOrGridOptions.setVisibility(View.VISIBLE);
+ initStaggeredOrGridOptions();
}
}
});
@@ -111,14 +116,10 @@ public class PostsLayoutPreferencesDialogFragment extends DialogFragment {
binding.colCountToggle.check(getSelectedColCountId());
binding.colCountToggle.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
- switch (checkedId) {
- case R.id.col_count_two:
- preferencesBuilder.setColCount(2);
- break;
- case R.id.col_count_three:
- default:
- preferencesBuilder.setColCount(3);
- break;
+ if (checkedId == R.id.col_count_two) {
+ preferencesBuilder.setColCount(2);
+ } else {
+ preferencesBuilder.setColCount(3);
}
});
}
@@ -135,17 +136,12 @@ public class PostsLayoutPreferencesDialogFragment extends DialogFragment {
binding.avatarSizeToggle.setVisibility(preferencesBuilder.isAvatarVisible() ? View.VISIBLE : View.GONE);
binding.avatarSizeToggle.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
- switch (checkedId) {
- case R.id.avatar_size_tiny:
- preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.TINY);
- break;
- case R.id.avatar_size_small:
- preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.SMALL);
- break;
- case R.id.avatar_size_regular:
- default:
- preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.REGULAR);
- break;
+ if (checkedId == R.id.avatar_size_tiny) {
+ preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.TINY);
+ } else if (checkedId == R.id.avatar_size_small) {
+ preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.SMALL);
+ } else {
+ preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.REGULAR);
}
});
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java
index 09ae3bd8..37be0268 100644
--- a/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java
@@ -12,69 +12,129 @@ import android.text.TextWatcher;
import android.text.style.RelativeSizeSpan;
import android.util.Log;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
-import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.SearchView;
-import androidx.fragment.app.Fragment;
+import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
import awais.instagrabber.R;
import awais.instagrabber.adapters.CommentsAdapter;
import awais.instagrabber.asyncs.CommentsFetcher;
import awais.instagrabber.databinding.FragmentCommentsBinding;
import awais.instagrabber.dialogs.ProfilePicDialogFragment;
-import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.CommentModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.CookieUtils;
import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
+import awais.instagrabber.viewmodels.CommentsViewModel;
import awais.instagrabber.webservices.MediaService;
import awais.instagrabber.webservices.ServiceCallback;
import static android.content.Context.INPUT_METHOD_SERVICE;
-public final class CommentsViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
+public final class CommentsViewerFragment extends BottomSheetDialogFragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "CommentsViewerFragment";
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
private CommentsAdapter commentsAdapter;
- private CommentModel commentModel;
private FragmentCommentsBinding binding;
private String shortCode;
private String userId;
private Resources resources;
private InputMethodManager imm;
private AppCompatActivity fragmentActivity;
- private LinearLayout root;
+ private LinearLayoutCompat root;
private boolean shouldRefresh = true;
private MediaService mediaService;
private String postId;
+ private CommentsViewModel commentsViewModel;
+
+ private final CommentsAdapter.CommentCallback commentCallback = new CommentsAdapter.CommentCallback() {
+ @Override
+ public void onClick(final CommentModel comment) {
+ onCommentClick(comment);
+ }
+
+ @Override
+ public void onHashtagClick(final String hashtag) {
+ final NavDirections action = CommentsViewerFragmentDirections.actionGlobalHashTagFragment(hashtag);
+ NavHostFragment.findNavController(CommentsViewerFragment.this).navigate(action);
+ }
+
+ @Override
+ public void onMentionClick(final String mention) {
+ openProfile(mention);
+ }
+
+ @Override
+ public void onURLClick(final String url) {
+ Utils.openURL(getContext(), url);
+ }
+
+ @Override
+ public void onEmailClick(final String emailAddress) {
+ Utils.openEmailAddress(getContext(), emailAddress);
+ }
+ };
+ private final View.OnClickListener newCommentListener = v -> {
+ final Editable text = binding.commentText.getText();
+ final Context context = getContext();
+ if (context == null) return;
+ if (text == null || TextUtils.isEmpty(text.toString())) {
+ Toast.makeText(context, R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ final String userId = CookieUtils.getUserIdFromCookie(cookie);
+ if (userId == null) return;
+ String replyToId = null;
+ final CommentModel commentModel = commentsAdapter.getSelected();
+ if (commentModel != null) {
+ replyToId = commentModel.getId();
+ }
+ mediaService.comment(postId, text.toString(), userId, replyToId, CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ commentsAdapter.clearSelection();
+ binding.commentText.setText("");
+ if (!result) {
+ Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error during comment", t);
+ Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ };
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentActivity = (AppCompatActivity) getActivity();
mediaService = MediaService.getInstance();
- setHasOptionsMenu(true);
+ // setHasOptionsMenu(true);
}
@NonNull
@@ -85,6 +145,8 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
return root;
}
binding = FragmentCommentsBinding.inflate(getLayoutInflater());
+ binding.swipeRefreshLayout.setEnabled(false);
+ binding.swipeRefreshLayout.setNestedScrollingEnabled(false);
root = binding.getRoot();
return root;
}
@@ -96,34 +158,33 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
shouldRefresh = false;
}
- @Override
- public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
- inflater.inflate(R.menu.follow, menu);
- menu.findItem(R.id.action_compare).setVisible(false);
- final MenuItem menuSearch = menu.findItem(R.id.action_search);
- final SearchView searchView = (SearchView) menuSearch.getActionView();
- searchView.setQueryHint(getResources().getString(R.string.action_search));
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(final String query) {
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(final String query) {
- if (commentsAdapter != null) commentsAdapter.getFilter().filter(query);
- return true;
- }
- });
- }
+ // @Override
+ // public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
+ // inflater.inflate(R.menu.follow, menu);
+ // menu.findItem(R.id.action_compare).setVisible(false);
+ // final MenuItem menuSearch = menu.findItem(R.id.action_search);
+ // final SearchView searchView = (SearchView) menuSearch.getActionView();
+ // searchView.setQueryHint(getResources().getString(R.string.action_search));
+ // searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ // @Override
+ // public boolean onQueryTextSubmit(final String query) {
+ // return false;
+ // }
+ //
+ // @Override
+ // public boolean onQueryTextChange(final String query) {
+ // // if (commentsAdapter != null) commentsAdapter.getFilter().filter(query);
+ // return true;
+ // }
+ // });
+ // }
@Override
public void onRefresh() {
binding.swipeRefreshLayout.setRefreshing(true);
new CommentsFetcher(shortCode, commentModels -> {
+ commentsViewModel.getList().postValue(commentModels);
binding.swipeRefreshLayout.setRefreshing(false);
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
- binding.rvComments.setAdapter(commentsAdapter);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -133,9 +194,14 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
shortCode = fragmentArgs.getShortCode();
postId = fragmentArgs.getPostId();
userId = fragmentArgs.getPostUserId();
- setTitle();
+ // setTitle();
binding.swipeRefreshLayout.setOnRefreshListener(this);
binding.swipeRefreshLayout.setRefreshing(true);
+ commentsViewModel = new ViewModelProvider(this).get(CommentsViewModel.class);
+ binding.rvComments.setLayoutManager(new LinearLayoutManager(getContext()));
+ commentsAdapter = new CommentsAdapter(commentCallback);
+ binding.rvComments.setAdapter(commentsAdapter);
+ commentsViewModel.getList().observe(getViewLifecycleOwner(), commentsAdapter::submitList);
resources = getResources();
if (!TextUtils.isEmpty(cookie)) {
binding.commentField.setStartIconVisible(false);
@@ -155,121 +221,107 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
public void afterTextChanged(final Editable s) {}
});
binding.commentField.setStartIconOnClickListener(v -> {
- if (commentModel != null) {
- final View focus = binding.rvComments.findViewWithTag(commentModel);
- focus.setBackgroundColor(0x00000000);
- commentModel = null;
- }
+ commentsAdapter.clearSelection();
binding.commentText.setText("");
});
binding.commentField.setEndIconOnClickListener(newCommentListener);
}
- new CommentsFetcher(this.shortCode, commentModels -> {
- commentsAdapter = new CommentsAdapter(commentModels, true, clickListener, mentionClickListener);
- binding.rvComments.setAdapter(commentsAdapter);
- binding.swipeRefreshLayout.setRefreshing(false);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ onRefresh();
}
- private void setTitle() {
- final ActionBar actionBar = fragmentActivity.getSupportActionBar();
- if (actionBar == null) return;
- actionBar.setTitle(R.string.title_comments);
+ // private void setTitle() {
+ // final ActionBar actionBar = fragmentActivity.getSupportActionBar();
+ // if (actionBar == null) return;
+ // actionBar.setTitle(R.string.title_comments);
// actionBar.setSubtitle(shortCode);
- }
+ // }
- final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
+ private void onCommentClick(final CommentModel commentModel) {
+ final String username = commentModel.getProfileModel().getUsername();
+ final SpannableString title = new SpannableString(username + ":\n" + commentModel.getText());
+ title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ String[] commentDialogList;
+
+ final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
+ if (!TextUtils.isEmpty(cookie)
+ && userIdFromCookie != null
+ && (userIdFromCookie.equals(commentModel.getProfileModel().getId()) || userIdFromCookie.equals(userId))) {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ // resources.getString(R.string.comment_viewer_copy_comment),
+ resources.getString(R.string.comment_viewer_reply_comment),
+ commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
+ : resources.getString(R.string.comment_viewer_like_comment),
+ resources.getString(R.string.comment_viewer_delete_comment)
+ };
+ } else if (!TextUtils.isEmpty(cookie)) {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ // resources.getString(R.string.comment_viewer_copy_comment),
+ resources.getString(R.string.comment_viewer_reply_comment),
+ commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
+ : resources.getString(R.string.comment_viewer_like_comment),
+ };
+ } else {
+ commentDialogList = new String[]{
+ resources.getString(R.string.open_profile),
+ resources.getString(R.string.view_pfp),
+ resources.getString(R.string.comment_viewer_copy_user),
+ // resources.getString(R.string.comment_viewer_copy_comment)
+ };
+ }
final Context context = getContext();
if (context == null) return;
- if (commentModel == null) {
- Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- return;
- }
- final ProfileModel profileModel = commentModel.getProfileModel();
- switch (which) {
- case 0: // open profile
- openProfile(profileModel.getUsername());
- break;
- case 1: // view profile pic
- final FragmentManager fragmentManager = getParentFragmentManager();
- final ProfilePicDialogFragment fragment = new ProfilePicDialogFragment(profileModel.getId(),
- profileModel.getUsername(),
- profileModel.getHdProfilePic());
- final FragmentTransaction ft = fragmentManager.beginTransaction();
- ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
- .add(fragment, "profilePicDialog")
- .commit();
- break;
- case 2: // copy username
- Utils.copyText(context, profileModel.getUsername());
- break;
- case 3: // copy comment
- Utils.copyText(context, commentModel.getText().toString());
- break;
- case 4: // reply to comment
- final View focus = binding.rvComments.findViewWithTag(commentModel);
- focus.setBackgroundColor(0x80888888);
- String mention = "@" + profileModel.getUsername() + " ";
- binding.commentText.setText(mention);
- binding.commentText.requestFocus();
- binding.commentText.setSelection(mention.length());
- binding.commentText.postDelayed(new Runnable() {
- @Override
- public void run() {
+ final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
+ final ProfileModel profileModel = commentModel.getProfileModel();
+ final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
+ switch (which) {
+ case 0: // open profile
+ openProfile("@" + profileModel.getUsername());
+ break;
+ case 1: // view profile pic
+ final FragmentManager fragmentManager = getParentFragmentManager();
+ final ProfilePicDialogFragment fragment = new ProfilePicDialogFragment(profileModel.getId(),
+ profileModel.getUsername(),
+ profileModel.getHdProfilePic());
+ final FragmentTransaction ft = fragmentManager.beginTransaction();
+ ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+ .add(fragment, "profilePicDialog")
+ .commit();
+ break;
+ case 2: // copy username
+ Utils.copyText(context, profileModel.getUsername());
+ break;
+ // case 3: // copy comment
+ // Utils.copyText(context, commentModel.getText().toString());
+ // break;
+ case 3: // reply to comment
+ // final View focus = binding.rvComments.findViewWithTag(commentModel);
+ // focus.setBackgroundColor(0x80888888);
+ commentsAdapter.setSelected(commentModel);
+ String mention = "@" + profileModel.getUsername() + " ";
+ binding.commentText.setText(mention);
+ binding.commentText.requestFocus();
+ binding.commentText.setSelection(mention.length());
+ binding.commentText.postDelayed(() -> {
imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
if (imm == null) return;
imm.showSoftInput(binding.commentText, 0);
+ }, 200);
+ break;
+ case 4: // like/unlike comment
+ if (csrfToken == null) {
+ return;
}
- }, 200);
- break;
- case 5: // like/unlike comment
- if (!commentModel.getLiked()) {
- mediaService.commentLike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
- @Override
- public void onSuccess(final Boolean result) {
- commentModel = null;
- if (!result) {
- Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- return;
- }
- onRefresh();
- }
-
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error liking comment", t);
- Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
- }
- });
- return;
- }
- mediaService.commentUnlike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
- @Override
- public void onSuccess(final Boolean result) {
- commentModel = null;
- if (!result) {
- Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- return;
- }
- onRefresh();
- }
-
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error unliking comment", t);
- Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
- }
- });
- break;
- case 6: // delete comment
- final String userId = CookieUtils.getUserIdFromCookie(cookie);
- if (userId == null) return;
- mediaService.deleteComment(
- postId, userId, commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
+ if (!commentModel.getLiked()) {
+ mediaService.commentLike(commentModel.getId(), csrfToken, new ServiceCallback() {
@Override
public void onSuccess(final Boolean result) {
- commentModel = null;
if (!result) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
@@ -279,112 +331,62 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
@Override
public void onFailure(final Throwable t) {
- Log.e(TAG, "Error deleting comment", t);
+ Log.e(TAG, "Error liking comment", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
- break;
- }
- };
+ return;
+ }
+ mediaService.commentUnlike(commentModel.getId(), csrfToken, new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ if (!result) {
+ Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
- private final View.OnClickListener clickListener = v -> {
- final Object tag = v.getTag();
- if (tag instanceof CommentModel) {
- commentModel = (CommentModel) tag;
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error unliking comment", t);
+ Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ break;
+ case 5: // delete comment
+ final String userId = CookieUtils.getUserIdFromCookie(cookie);
+ if (userId == null) return;
+ mediaService.deleteComment(
+ postId, userId, commentModel.getId(), csrfToken,
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final Boolean result) {
+ if (!result) {
+ Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ onRefresh();
+ }
- final String username = commentModel.getProfileModel().getUsername();
- final SpannableString title = new SpannableString(username + ":\n" + commentModel.getText());
- title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-
- String[] commentDialogList;
-
- final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
- if (!TextUtils.isEmpty(cookie)
- && userIdFromCookie != null
- && (userIdFromCookie.equals(commentModel.getProfileModel().getId()) || userIdFromCookie.equals(userId))) {
- commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
- : resources.getString(R.string.comment_viewer_like_comment),
- resources.getString(R.string.comment_viewer_delete_comment)
- };
- } else if (!TextUtils.isEmpty(cookie)) {
- commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment),
- resources.getString(R.string.comment_viewer_reply_comment),
- commentModel.getLiked() ? resources.getString(R.string.comment_viewer_unlike_comment)
- : resources.getString(R.string.comment_viewer_like_comment),
- };
- } else {
- commentDialogList = new String[]{
- resources.getString(R.string.open_profile),
- resources.getString(R.string.view_pfp),
- resources.getString(R.string.comment_viewer_copy_user),
- resources.getString(R.string.comment_viewer_copy_comment)
- };
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error deleting comment", t);
+ Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ });
+ break;
}
- final Context context = getContext();
- if (context == null) return;
- new AlertDialog.Builder(context)
- .setTitle(title)
- .setItems(commentDialogList, profileDialogListener)
- .setNegativeButton(R.string.cancel, null)
- .show();
- }
- };
-
- private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
- if (isHashtag) {
- final NavDirections action = CommentsViewerFragmentDirections.actionGlobalHashTagFragment(text);
- NavHostFragment.findNavController(this).navigate(action);
- return;
- }
- openProfile(text);
- };
-
- private final View.OnClickListener newCommentListener = v -> {
- final Editable text = binding.commentText.getText();
- final Context context = getContext();
- if (context == null) return;
- if (text == null || TextUtils.isEmpty(text.toString())) {
- Toast.makeText(context, R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
- return;
- }
- final String userId = CookieUtils.getUserIdFromCookie(cookie);
- if (userId == null) return;
- String replyToId = null;
- if (commentModel != null) {
- replyToId = commentModel.getId();
- }
- mediaService.comment(postId, text.toString(), userId, replyToId, CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() {
- @Override
- public void onSuccess(final Boolean result) {
- commentModel = null;
- binding.commentText.setText("");
- if (!result) {
- Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
- return;
- }
- onRefresh();
- }
-
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error during comment", t);
- Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
- }
- });
- };
+ };
+ new AlertDialog.Builder(context)
+ .setTitle(title)
+ .setItems(commentDialogList, profileDialogListener)
+ .setNegativeButton(R.string.cancel, null)
+ .show();
+ }
private void openProfile(final String username) {
- final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment("@" + username);
+ final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment(username);
NavHostFragment.findNavController(this).navigate(action);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
index 9eab384e..4ecefa83 100644
--- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
@@ -1,7 +1,6 @@
package awais.instagrabber.fragments;
import android.content.Context;
-import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -22,7 +21,6 @@ import androidx.activity.OnBackPressedDispatcher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
@@ -73,6 +71,8 @@ import static awais.instagrabber.utils.Utils.settingsHelper;
public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "HashTagFragment";
+ public static final String ARG_HASHTAG = "hashtag";
+
private MainActivity fragmentActivity;
private FragmentHashtagBinding binding;
private NestedCoordinatorLayout root;
@@ -298,24 +298,24 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
if (context == null) return;
if (isLoggedIn) {
storiesService.getUserStory(hashtagModel.getName(),
- null,
- false,
- true,
- false,
- new ServiceCallback>() {
- @Override
- public void onSuccess(final List storyModels) {
- if (storyModels != null && !storyModels.isEmpty()) {
- binding.mainHashtagImage.setStoriesBorder();
- hasStories = true;
- }
- }
+ null,
+ false,
+ true,
+ false,
+ new ServiceCallback>() {
+ @Override
+ public void onSuccess(final List storyModels) {
+ if (storyModels != null && !storyModels.isEmpty()) {
+ binding.mainHashtagImage.setStoriesBorder();
+ hasStories = true;
+ }
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error", t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error", t);
+ }
+ });
binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.btnFollowTag.setText(hashtagModel.getFollowing() ? R.string.unfollow : R.string.follow);
binding.btnFollowTag.setChipIconResource(hashtagModel.getFollowing()
diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
index c205bcfb..7ef0d79b 100644
--- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
@@ -76,12 +76,9 @@ import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.webservices.MediaService;
import awais.instagrabber.webservices.ServiceCallback;
-import io.github.armcha.autolink.MODE_EMAIL;
-import io.github.armcha.autolink.MODE_HASHTAG;
-import io.github.armcha.autolink.MODE_MENTION;
-import kotlin.Unit;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
+import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.settingsHelper;
@@ -90,6 +87,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
private static final String COOKIE = settingsHelper.getString(Constants.COOKIE);
private static final int DETAILS_HIDE_DELAY_MILLIS = 2000;
private static final String ARG_FEED_MODEL = "feedModel";
+ private static final String ARG_SLIDER_POSITION = "position";
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
private FeedModel feedModel;
@@ -105,6 +103,8 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
private SliderItemsAdapter sliderItemsAdapter;
private boolean wasControlsVisible;
private boolean wasPaused;
+ private int captionState = BottomSheetBehavior.STATE_HIDDEN;
+ private int sliderPosition;
private final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener = new VerticalDragHelper.OnVerticalDragListener() {
@@ -151,6 +151,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
private final FeedModel feedModel;
private View profilePicElement;
private View mainPostElement;
+ private int position;
public Builder setSharedProfilePicElement(final View profilePicElement) {
this.profilePicElement = profilePicElement;
@@ -162,8 +163,13 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
return this;
}
+ public Builder setPosition(final int position) {
+ this.position = position;
+ return this;
+ }
+
public PostViewV2Fragment build() {
- return PostViewV2Fragment.newInstance(feedModel, profilePicElement, mainPostElement);
+ return PostViewV2Fragment.newInstance(feedModel, profilePicElement, mainPostElement, position);
}
public Builder(final FeedModel feedModel) {
@@ -171,10 +177,16 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
}
}
- private static PostViewV2Fragment newInstance(final FeedModel feedModel, final View profilePicElement, final View mainPostElement) {
+ private static PostViewV2Fragment newInstance(final FeedModel feedModel,
+ final View profilePicElement,
+ final View mainPostElement,
+ final int position) {
final PostViewV2Fragment f = new PostViewV2Fragment(profilePicElement, mainPostElement);
final Bundle args = new Bundle();
args.putSerializable(ARG_FEED_MODEL, feedModel);
+ if (position >= 0) {
+ args.putInt(ARG_SLIDER_POSITION, position);
+ }
f.setArguments(args);
return f;
}
@@ -353,6 +365,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
return;
}
feedModel = (FeedModel) feedModelSerializable;
+ if (feedModel.getItemType() == MediaItemType.MEDIA_TYPE_SLIDER) {
+ sliderPosition = arguments.getInt(ARG_SLIDER_POSITION, 0);
+ }
}
@Nullable
@@ -402,6 +417,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
public void onPause() {
super.onPause();
wasPaused = true;
+ captionState = bottomSheetBehavior.getState();
}
@Override
@@ -424,7 +440,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
@Override
public void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
- Log.d(TAG, "onSaveInstanceState");
+ if (feedModel.getItemType() == MediaItemType.MEDIA_TYPE_SLIDER) {
+ outState.putInt(ARG_SLIDER_POSITION, sliderPosition);
+ }
}
@Override
@@ -505,32 +523,34 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
}
private void init() {
- binding.getRoot().getBackground().mutate().setAlpha(0);
- // if (getArguments() == null) return;
- // final PostViewV2FragmentArgs fragmentArgs = PostViewV2FragmentArgs.fromBundle(getArguments());
- // feedModel = fragmentArgs.getFeedModel();
+ if (!wasPaused && (sharedProfilePicElement != null || sharedMainPostElement != null)) {
+ binding.getRoot().getBackground().mutate().setAlpha(0);
+ }
setupProfilePic();
setupTitles();
setupCaption();
setupCounts();
setupPostTypeLayout();
setupCommonActions();
- // binding.getRoot().setOnTouchListener(onTouchListener);
- // final String[] idOrCodeArray = fragmentArgs.getIdOrCodeArray();
- // if (idOrCodeArray.length == 0) return;
- // currentPostIndex = fragmentArgs.getIndex();
- // if (currentPostIndex < 0) return;
- // if (currentPostIndex >= idOrCodeArray.length) return;
- // idOrCodeList = Arrays.asList(idOrCodeArray);
- // viewerPostViewModel.getList().setValue(createPlaceholderModels(idOrCodeArray.length));
- // isId = fragmentArgs.getIsId();
- // fetchPost();
}
private void setupCommonActions() {
setupLike();
setupSave();
setupDownload();
+ setupComment();
+ }
+
+ private void setupComment() {
+ binding.comment.setOnClickListener(v -> {
+ final NavController navController = getNavController();
+ if (navController == null) return;
+ final Bundle bundle = new Bundle();
+ bundle.putString("shortCode", feedModel.getShortCode());
+ bundle.putString("postId", feedModel.getPostId());
+ bundle.putString("postUserId", feedModel.getProfileModel().getId());
+ navController.navigate(R.id.action_global_commentsViewerFragment, bundle);
+ });
}
private void setupDownload() {
@@ -758,30 +778,26 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
private void setupCaption() {
final CharSequence postCaption = feedModel.getPostCaption();
- binding.caption.addAutoLinkMode(MODE_HASHTAG.INSTANCE, MODE_MENTION.INSTANCE, MODE_EMAIL.INSTANCE);
- binding.caption.onAutoLinkClick(autoLinkItem -> {
- // Log.d(TAG, "setupCaption: autoLinkItem: " + autoLinkItem.getMode().getModeName() + " : " + autoLinkItem.getOriginalText());
- final String originalText = autoLinkItem.getOriginalText();
- if (autoLinkItem.getMode().equals(MODE_HASHTAG.INSTANCE)) {
- final NavController navController = NavHostFragment.findNavController(this);
- final Bundle bundle = new Bundle();
- bundle.putString("hashtag", originalText);
- navController.navigate(R.id.action_global_hashTagFragment, bundle);
- return Unit.INSTANCE;
- }
- if (autoLinkItem.getMode().equals(MODE_MENTION.INSTANCE)) {
- navigateToProfile(originalText);
- return Unit.INSTANCE;
- }
- return Unit.INSTANCE;
+ binding.caption.addOnHashtagListener(autoLinkItem -> {
+ final NavController navController = NavHostFragment.findNavController(this);
+ final Bundle bundle = new Bundle();
+ final String originalText = autoLinkItem.getOriginalText().trim();
+ bundle.putString(ARG_HASHTAG, originalText);
+ navController.navigate(R.id.action_global_hashTagFragment, bundle);
});
+ binding.caption.addOnMentionClickListener(autoLinkItem -> {
+ final String originalText = autoLinkItem.getOriginalText().trim();
+ navigateToProfile(originalText);
+ });
+ binding.caption.addOnEmailClickListener(autoLinkItem -> Utils.openEmailAddress(getContext(), autoLinkItem.getOriginalText().trim()));
+ binding.caption.addOnURLClickListener(autoLinkItem -> Utils.openURL(getContext(), autoLinkItem.getOriginalText().trim()));
binding.caption.setOnLongClickListener(v -> {
- Utils.copyText(getContext(), postCaption);
+ Utils.copyText(context, postCaption);
return true;
});
binding.caption.setText(postCaption);
bottomSheetBehavior = BottomSheetBehavior.from(binding.captionParent);
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
+ bottomSheetBehavior.setState(captionState);
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull final View bottomSheet, final int newState) {}
@@ -900,7 +916,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
if (sharedMainPostElement != null) {
addSharedElement(sharedMainPostElement, binding.sliderParent);
}
- sliderItemsAdapter = new SliderItemsAdapter(onVerticalDragListener, binding.playerControls, new SliderCallbackAdapter() {
+ sliderItemsAdapter = new SliderItemsAdapter(onVerticalDragListener, binding.playerControls, true, new SliderCallbackAdapter() {
@Override
public void onThumbnailLoaded(final int position) {
if (position != 0) return;
@@ -926,6 +942,9 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
}
});
binding.sliderParent.setAdapter(sliderItemsAdapter);
+ if (sliderPosition >= 0 && sliderPosition < feedModel.getSliderItems().size()) {
+ binding.sliderParent.setCurrentItem(sliderPosition);
+ }
binding.sliderParent.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
int prevPosition = -1;
@@ -947,6 +966,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
public void onPageSelected(final int position) {
final int size = feedModel.getSliderItems().size();
if (position < 0 || position >= size) return;
+ sliderPosition = position;
final String text = (position + 1) + "/" + size;
binding.mediaCounter.setText(text);
final PostChild postChild = feedModel.getSliderItems().get(position);
@@ -1046,6 +1066,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment {
vol,
aspectRatio,
feedModel.getThumbnailUrl(),
+ true,
binding.playerControls,
videoPlayerCallback);
}
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 33368f43..16b75d2b 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java
@@ -14,265 +14,159 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
+import androidx.navigation.NavController;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity;
+import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.adapters.FeedStoriesAdapter;
import awais.instagrabber.asyncs.FeedPostFetchService;
-import awais.instagrabber.customviews.helpers.VideoAwareRecyclerScroller;
import awais.instagrabber.databinding.FragmentFeedBinding;
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
import awais.instagrabber.fragments.PostViewV2Fragment;
-import awais.instagrabber.interfaces.MentionClickListener;
+import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.utils.Constants;
+import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.Utils;
import awais.instagrabber.viewmodels.FeedStoriesViewModel;
import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesService;
+import static androidx.core.content.PermissionChecker.checkSelfPermission;
+import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "FeedFragment";
- private static final double MAX_VIDEO_HEIGHT = 0.9 * Utils.displayMetrics.heightPixels;
- private static final int RESIZED_VIDEO_HEIGHT = (int) (0.8 * Utils.displayMetrics.heightPixels);
+ private static final int STORAGE_PERM_REQUEST_CODE = 8020;
+ // private static final double MAX_VIDEO_HEIGHT = 0.9 * Utils.displayMetrics.heightPixels;
+ // private static final int RESIZED_VIDEO_HEIGHT = (int) (0.8 * Utils.displayMetrics.heightPixels);
private MainActivity fragmentActivity;
private CoordinatorLayout root;
private FragmentFeedBinding binding;
private StoriesService storiesService;
- private boolean feedHasNextPage = false;
- private String feedEndCursor = null;
+ // private boolean feedHasNextPage = false;
+ // private String feedEndCursor = null;
// private FeedViewModel feedViewModel;
- private VideoAwareRecyclerScroller videoAwareRecyclerScroller;
+ // private VideoAwareRecyclerScroller videoAwareRecyclerScroller;
private boolean shouldRefresh = true;
- private boolean isPullToRefresh;
+ // private boolean isPullToRefresh;
private FeedStoriesViewModel feedStoriesViewModel;
- private StaggeredGridLayoutManager gridLayoutManager;
+ // private StaggeredGridLayoutManager gridLayoutManager;
private boolean storiesFetching;
- private final boolean shouldAutoPlay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
- // private final FetchListener feedFetchListener = new FetchListener() {
- // @Override
- // public void doBefore() {
- // binding.feedSwipeRefreshLayout.post(() -> binding.feedSwipeRefreshLayout.setRefreshing(true));
- // }
- //
- // @Override
- // public void onResult(final FeedModel[] result) {
- // if (result == null || result.length <= 0) {
- // binding.feedSwipeRefreshLayout.setRefreshing(false);
- // return;
- // }
- // final List currentFeedModelList = feedViewModel.getList().getValue();
- // final Map thumbToFeedMap = new HashMap<>();
- // for (final FeedModel feedModel : result) {
- // thumbToFeedMap.put(feedModel.getThumbnailUrl(), feedModel);
- // }
- // final BaseDataSubscriber subscriber = new BaseDataSubscriber() {
- // int success = 0;
- // int failed = 0;
- //
- // @Override
- // protected void onNewResultImpl(@NonNull final DataSource dataSource) {
- // final Map extras = dataSource.getExtras();
- // if (extras == null) return;
- // final Uri thumbUri = (Uri) extras.get("uri_source");
- // if (thumbUri == null) return;
- // final Integer encodedWidth = (Integer) extras.get("encoded_width");
- // final Integer encodedHeight = (Integer) extras.get("encoded_height");
- // if (encodedWidth == null || encodedHeight == null) return;
- // final FeedModel feedModel = thumbToFeedMap.get(thumbUri.toString());
- // if (feedModel == null) return;
- // int requiredWidth = Utils.displayMetrics.widthPixels;
- // int resultingHeight = NumberUtils
- // .getResultingHeight(requiredWidth, encodedHeight, encodedWidth);
- // if (feedModel
- // .getItemType() == MediaItemType.MEDIA_TYPE_VIDEO && resultingHeight >= MAX_VIDEO_HEIGHT) {
- // // If its a video and the height is too large, need to reduce the height,
- // // so that entire video fits on screen
- // resultingHeight = RESIZED_VIDEO_HEIGHT;
- // requiredWidth = NumberUtils.getResultingWidth(RESIZED_VIDEO_HEIGHT,
- // resultingHeight,
- // requiredWidth);
- // }
- // feedModel.setImageWidth(requiredWidth);
- // feedModel.setImageHeight(resultingHeight);
- // success++;
- // updateAdapter();
- // }
- //
- // @Override
- // protected void onFailureImpl(@NonNull final DataSource dataSource) {
- // failed++;
- // updateAdapter();
- // }
- //
- // public void updateAdapter() {
- // if (failed + success != result.length) return;
- //
- // }
- // };
- // for (final FeedModel feedModel : result) {
- // final DataSource ds = Fresco.getImagePipeline()
- // .prefetchToBitmapCache(ImageRequest.fromUri(feedModel.getThumbnailUrl()), null);
- // ds.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
- // }
- // List finalList = currentFeedModelList == null || currentFeedModelList.isEmpty()
- // ? new ArrayList<>()
- // : new ArrayList<>(currentFeedModelList);
- // final List resultList = Arrays.asList(result);
- // if (isPullToRefresh) {
- // finalList = resultList;
- // isPullToRefresh = false;
- // } else {
- // finalList.addAll(resultList);
- // }
- // // feedViewModel.getList().postValue(finalList);
- // final PostModel feedPostModel = result[result.length - 1];
- // if (feedPostModel != null) {
- // feedEndCursor = feedPostModel.getEndCursor();
- // feedHasNextPage = feedPostModel.hasNextPage();
- // feedPostModel.setPageCursor(false, null);
- // }
- // binding.feedSwipeRefreshLayout.setRefreshing(false);
- // }
- // };
- private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
- if (isHashtag) {
- final NavDirections action = FeedFragmentDirections.actionGlobalHashTagFragment(text);
- NavHostFragment.findNavController(this).navigate(action);
- return;
+ // private final boolean shouldAutoPlay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
+ private final FeedAdapterV2.FeedItemCallback feedItemCallback = new FeedAdapterV2.FeedItemCallback() {
+ @Override
+ public void onPostClick(final FeedModel feedModel, final View profilePicView, final View mainPostImage) {
+ openPostDialog(feedModel, profilePicView, mainPostImage, -1);
}
- if (isLocation) {
- final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
- NavHostFragment.findNavController(this).navigate(action);
- return;
+
+ @Override
+ public void onSliderClick(final FeedModel feedModel, final int position) {
+ openPostDialog(feedModel, null, null, position);
+ }
+
+ @Override
+ public void onCommentsClick(final FeedModel feedModel) {
+ final NavDirections commentsAction = FeedFragmentDirections.actionGlobalCommentsViewerFragment(
+ feedModel.getShortCode(),
+ feedModel.getPostId(),
+ feedModel.getProfileModel().getId()
+ );
+ NavHostFragment.findNavController(FeedFragment.this).navigate(commentsAction);
+ }
+
+ @Override
+ public void onDownloadClick(final FeedModel feedModel) {
+ final Context context = getContext();
+ if (context == null) return;
+ if (checkSelfPermission(context, WRITE_PERMISSION) == PermissionChecker.PERMISSION_GRANTED) {
+ showDownloadDialog(feedModel);
+ return;
+ }
+ requestPermissions(DownloadUtils.PERMS, STORAGE_PERM_REQUEST_CODE);
+ }
+
+ @Override
+ public void onHashtagClick(final String hashtag) {
+ final NavDirections action = FeedFragmentDirections.actionGlobalHashTagFragment(hashtag);
+ NavHostFragment.findNavController(FeedFragment.this).navigate(action);
+ }
+
+ @Override
+ public void onLocationClick(final FeedModel feedModel) {
+ final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(feedModel.getLocationId());
+ NavHostFragment.findNavController(FeedFragment.this).navigate(action);
+ }
+
+ @Override
+ public void onMentionClick(final String mention) {
+ navigateToProfile(mention.trim());
+ }
+
+ @Override
+ public void onNameClick(final FeedModel feedModel, final View profilePicView) {
+ navigateToProfile("@" + feedModel.getProfileModel().getUsername());
+ }
+
+ @Override
+ public void onProfilePicClick(final FeedModel feedModel, final View profilePicView) {
+ navigateToProfile("@" + feedModel.getProfileModel().getUsername());
+ }
+
+ @Override
+ public void onURLClick(final String url) {
+ Utils.openURL(getContext(), url);
+ }
+
+ @Override
+ public void onEmailClick(final String emailId) {
+ Utils.openEmailAddress(getContext(), emailId);
+ }
+
+ private void openPostDialog(final FeedModel feedModel,
+ final View profilePicView,
+ final View mainPostImage,
+ final int position) {
+ final PostViewV2Fragment.Builder builder = PostViewV2Fragment
+ .builder(feedModel);
+ if (position >= 0) {
+ builder.setPosition(position);
+ }
+ final PostViewV2Fragment fragment = builder
+ .setSharedProfilePicElement(profilePicView)
+ .setSharedMainPostElement(mainPostImage)
+ .build();
+ fragment.show(getChildFragmentManager(), "post_view");
}
- final NavDirections action = FeedFragmentDirections.actionGlobalProfileFragment("@" + text);
- NavHostFragment.findNavController(this).navigate(action);
- };
- private final View.OnClickListener postViewClickListener = v -> {
- // gridLayoutManager.setSpanCount(1);
- // final Object tag = v.getTag();
- // if (!(tag instanceof FeedModel)) return;
- //
- // final FeedModel feedModel = (FeedModel) tag;
- // if (v instanceof RamboTextView) {
- // if (feedModel.isMentionClicked()) feedModel.toggleCaption();
- // feedModel.setMentionClicked(false);
- // if (!FeedItemViewHolder.expandCollapseTextView((RamboTextView) v, feedModel.getPostCaption()))
- // feedModel.toggleCaption();
- // return;
- // }
- //
- // final int id = v.getId();
- // switch (id) {
- // case R.id.btnComments:
- // final NavDirections commentsAction = FeedFragmentDirections.actionGlobalCommentsViewerFragment(
- // feedModel.getShortCode(),
- // feedModel.getPostId(),
- // feedModel.getProfileModel().getId()
- // );
- // NavHostFragment.findNavController(this).navigate(commentsAction);
- // break;
- // // case R.id.viewStoryPost:
- // // final List feedModels = feedViewModel.getList().getValue();
- // // if (feedModels == null || feedModels.size() == 0) return;
- // // if (feedModels.get(0) == null) return;
- // // final String postId = feedModels.get(0).getPostId();
- // // final boolean isId = postId != null;
- // // final String[] idsOrShortCodes = new String[feedModels.size()];
- // // for (int i = 0; i < feedModels.size(); i++) {
- // // idsOrShortCodes[i] = isId ? feedModels.get(i).getPostId()
- // // : feedModels.get(i).getShortCode();
- // // }
- // // final NavDirections action = FeedFragmentDirections.actionGlobalPostViewFragment(
- // // feedModel.getPosition(),
- // // idsOrShortCodes,
- // // isId);
- // // NavHostFragment.findNavController(this).navigate(action);
- // // break;
- // case R.id.btnDownload:
- // ProfileModel profileModel = feedModel.getProfileModel();
- // final String username = profileModel != null ? profileModel.getUsername() : null;
- //
- // final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
- //
- // final Context context = getContext();
- // if (context == null) return;
- // if (feedModel
- // .getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1)
- // DownloadUtils.batchDownload(context,
- // username,
- // DownloadMethod.DOWNLOAD_FEED,
- // Collections.singletonList(feedModel));
- // else {
- // final ArrayList postModels = new ArrayList<>();
- // final DialogInterface.OnClickListener clickListener1 = (dialog, which) -> {
- // postModels.clear();
- //
- // final boolean breakWhenFoundSelected = which == DialogInterface.BUTTON_POSITIVE;
- //
- // for (final ViewerPostModel sliderItem : sliderItems) {
- // if (sliderItem != null) {
- // if (!breakWhenFoundSelected) postModels.add(sliderItem);
- // else if (sliderItem.isSelected()) {
- // postModels.add(sliderItem);
- // break;
- // }
- // }
- // }
- //
- // // shows 0 items on first item of viewpager cause onPageSelected hasn't been called yet
- // if (breakWhenFoundSelected && postModels.size() == 0) {
- // postModels.add(sliderItems[0]);
- // }
- // if (postModels.size() > 0) {
- // DownloadUtils.batchDownload(context,
- // username,
- // DownloadMethod.DOWNLOAD_FEED,
- // postModels);
- // }
- // };
- //
- // new AlertDialog.Builder(context)
- // .setTitle(R.string.post_viewer_download_dialog_title)
- // .setPositiveButton(R.string.post_viewer_download_current, clickListener1)
- // .setNegativeButton(R.string.post_viewer_download_album, clickListener1)
- // .show();
- // }
- // break;
- //
- // case R.id.ivProfilePic:
- // profileModel = feedModel.getProfileModel();
- // if (profileModel != null) mentionClickListener.onClick(null, profileModel.getUsername(), false, false);
- // break;
- // default:
- // break;
- // }
};
+ private void navigateToProfile(final String username) {
+ final NavController navController = NavHostFragment.findNavController(this);
+ final Bundle bundle = new Bundle();
+ bundle.putString("username", username);
+ navController.navigate(R.id.action_global_profileFragment, bundle);
+ }
+
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity();
storiesService = StoriesService.getInstance();
- // feedService = FeedService.getInstance();
- // final TransitionInflater inflater = TransitionInflater.from(getContext());
- // setExitTransition(inflater.inflateTransition(android.R.transition.move));
setHasOptionsMenu(true);
}
@@ -316,74 +210,44 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
@Override
public void onPause() {
super.onPause();
- if (videoAwareRecyclerScroller != null) {
- videoAwareRecyclerScroller.stopPlaying();
- }
+ // if (videoAwareRecyclerScroller != null) {
+ // videoAwareRecyclerScroller.stopPlaying();
+ // }
}
@Override
public void onResume() {
super.onResume();
binding.feedSwipeRefreshLayout.setRefreshing(false);
- if (videoAwareRecyclerScroller != null && shouldAutoPlay) {
- videoAwareRecyclerScroller.startPlaying();
- }
+ // if (videoAwareRecyclerScroller != null && shouldAutoPlay) {
+ // videoAwareRecyclerScroller.startPlaying();
+ // }
}
@Override
public void onRefresh() {
- isPullToRefresh = true;
- feedEndCursor = null;
+ // isPullToRefresh = true;
+ // feedEndCursor = null;
binding.feedRecyclerView.refresh();
fetchStories();
}
private void setupFeed() {
- // feedViewModel = new ViewModelProvider(fragmentActivity).get(FeedViewModel.class);
final Context context = getContext();
if (context == null) return;
- // final PostFetcher.PostFetchService feedPostsFetchService = new PostFetcher.PostFetchService() {
- // @Override
- // public void fetch(final int page, final FetchListener> fetchListener) {
- // new FeedFetcher(feedEndCursor, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- // }
- // };
binding.feedRecyclerView.setViewModelStoreOwner(this)
.setLifeCycleOwner(this)
.setPostFetchService(new FeedPostFetchService())
.setLayoutPreferences(PostsLayoutPreferences.fromJson(settingsHelper.getString(Constants.PREF_POSTS_LAYOUT)))
.addFetchStatusChangeListener(fetching -> updateSwipeRefreshState())
- .setOnPostClickListener((feedModel, profilePicView, mainPostImage) -> {
- final PostViewV2Fragment fragment = PostViewV2Fragment
- .builder(feedModel)
- .setSharedProfilePicElement(profilePicView)
- .setSharedMainPostElement(mainPostImage)
- .build();
- fragment.show(getChildFragmentManager(), "post_view");
- })
+ .setFeedItemCallback(feedItemCallback)
.init();
binding.feedSwipeRefreshLayout.setRefreshing(true);
- // final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
- // binding.feedRecyclerView.setLayoutManager(gridLayoutManager);
- // feedAdapter = new FeedAdapterV2(spanCount[0], postViewClickListener, mentionClickListener, feedModel -> {
- // final ChangeBounds transition = new ChangeBounds();
- // transition.setDuration(200);
- // TransitionManager.beginDelayedTransition(binding.feedRecyclerView, transition);
- // spanCount[0] = spanCount[0] - 1;
- // if (spanCount[0] == 0) {
- // spanCount[0] = 3;
- // }
- // gridLayoutManager.setSpanCount(spanCount[0]);
- // });
// feedAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);
- // binding.feedRecyclerView.setAdapter(feedAdapter);
- // feedViewModel.getList().observe(fragmentActivity, feedAdapter::submitList);
// if (shouldAutoPlay) {
// videoAwareRecyclerScroller = new VideoAwareRecyclerScroller();
// binding.feedRecyclerView.addOnScrollListener(videoAwareRecyclerScroller);
// }
- // fetchFeed();
-
}
private void updateSwipeRefreshState() {
@@ -424,6 +288,48 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
});
}
+ private void showDownloadDialog(final FeedModel feedModel) {
+ final Context context = getContext();
+ if (context == null) return;
+ DownloadUtils.download(context, feedModel);
+ // switch (feedModel.getItemType()) {
+ // case MEDIA_TYPE_IMAGE:
+ // case MEDIA_TYPE_VIDEO:
+ // break;
+ // case MEDIA_TYPE_SLIDER:
+ // break;
+ // }
+ // final List postModelsToDownload = new ArrayList<>();
+ // // if (!session) {
+ // final DialogInterface.OnClickListener clickListener = (dialog, which) -> {
+ // if (which == DialogInterface.BUTTON_NEGATIVE) {
+ // postModelsToDownload.addAll(postModels);
+ // } else if (which == DialogInterface.BUTTON_POSITIVE) {
+ // postModelsToDownload.add(postModels.get(childPosition));
+ // } else {
+ // session = true;
+ // postModelsToDownload.add(postModels.get(childPosition));
+ // }
+ // if (postModelsToDownload.size() > 0) {
+ // DownloadUtils.batchDownload(context,
+ // username,
+ // DownloadMethod.DOWNLOAD_POST_VIEWER,
+ // postModelsToDownload);
+ // }
+ // };
+ // new AlertDialog.Builder(context)
+ // .setTitle(R.string.post_viewer_download_dialog_title)
+ // .setMessage(R.string.post_viewer_download_message)
+ // .setNeutralButton(R.string.post_viewer_download_session, clickListener)
+ // .setPositiveButton(R.string.post_viewer_download_current, clickListener)
+ // .setNegativeButton(R.string.post_viewer_download_album, clickListener).show();
+ // } else {
+ // DownloadUtils.batchDownload(context,
+ // username,
+ // DownloadMethod.DOWNLOAD_POST_VIEWER,
+ // Collections.singletonList(postModels.get(childPosition)));
+ }
+
private void showPostsLayoutPreferences() {
final PostsLayoutPreferencesDialogFragment fragment = new PostsLayoutPreferencesDialogFragment(preferences -> new Handler()
.postDelayed(() -> binding.feedRecyclerView.setLayoutPreferences(preferences), 200));
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
index 3f4d9993..d5fd5b61 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
@@ -420,7 +420,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private void fetchProfileDetails() {
if (TextUtils.isEmpty(username)) return;
- new ProfileFetcher(username.substring(1), profileModel -> {
+ new ProfileFetcher(username.trim().substring(1), profileModel -> {
if (getContext() == null) return;
this.profileModel = profileModel;
// final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
diff --git a/app/src/main/java/awais/instagrabber/models/CommentModel.java b/app/src/main/java/awais/instagrabber/models/CommentModel.java
index 733e1c92..9ce02bb0 100755
--- a/app/src/main/java/awais/instagrabber/models/CommentModel.java
+++ b/app/src/main/java/awais/instagrabber/models/CommentModel.java
@@ -3,23 +3,29 @@ package awais.instagrabber.models;
import androidx.annotation.NonNull;
import java.util.Date;
+import java.util.List;
-import awais.instagrabber.utils.TextUtils;
import awais.instagrabber.utils.Utils;
-public final class CommentModel {
+public class CommentModel {
private final ProfileModel profileModel;
private final String id;
- private final CharSequence text;
- private final long likes, timestamp;
- private CommentModel[] childCommentModels;
- private boolean hasNextPage, liked;
+ private final String text;
+ private final long likes;
+ private final long timestamp;
+ private List childCommentModels;
+ private final boolean liked;
+ private boolean hasNextPage;
private String endCursor;
- public CommentModel(final String id, final String text, final long timestamp, final long likes, final boolean liked,
+ public CommentModel(final String id,
+ final String text,
+ final long timestamp,
+ final long likes,
+ final boolean liked,
final ProfileModel profileModel) {
this.id = id;
- this.text = TextUtils.hasMentions(text) ? TextUtils.getMentionText(text) : text;
+ this.text = text;
this.likes = likes;
this.liked = liked;
this.timestamp = timestamp;
@@ -30,7 +36,7 @@ public final class CommentModel {
return id;
}
- public CharSequence getText() {
+ public String getText() {
return text;
}
@@ -51,11 +57,11 @@ public final class CommentModel {
return profileModel;
}
- public CommentModel[] getChildCommentModels() {
+ public List getChildCommentModels() {
return childCommentModels;
}
- public void setChildCommentModels(final CommentModel[] childCommentModels) {
+ public void setChildCommentModels(final List childCommentModels) {
this.childCommentModels = childCommentModels;
}
@@ -72,21 +78,21 @@ public final class CommentModel {
return endCursor;
}
-// @NonNull
-// @Override
-// public String toString() {
-// try {
-// final JSONObject object = new JSONObject();
-// object.put(Constants.EXTRAS_ID, id);
-// object.put("text", text);
-// object.put(Constants.EXTRAS_NAME, profileModel != null ? profileModel.getUsername() : "");
-// if (childCommentModels != null) object.put("childComments", childCommentModels);
-// return object.toString();
-// } catch (Exception e) {
-// return "{\"id\":\"" + id + "\", \"text\":\"" + text
-// //(text != null ? text.replaceAll("\"", "\\\\\"") : "")
-// + "\", \"name\":\"" + (profileModel != null ? profileModel.getUsername() : "") +
-// (childCommentModels != null ? "\", \"childComments\":" + childCommentModels.length : "\"") + '}';
-// }
-// }
+ // @NonNull
+ // @Override
+ // public String toString() {
+ // try {
+ // final JSONObject object = new JSONObject();
+ // object.put(Constants.EXTRAS_ID, id);
+ // object.put("text", text);
+ // object.put(Constants.EXTRAS_NAME, profileModel != null ? profileModel.getUsername() : "");
+ // if (childCommentModels != null) object.put("childComments", childCommentModels);
+ // return object.toString();
+ // } catch (Exception e) {
+ // return "{\"id\":\"" + id + "\", \"text\":\"" + text
+ // //(text != null ? text.replaceAll("\"", "\\\\\"") : "")
+ // + "\", \"name\":\"" + (profileModel != null ? profileModel.getUsername() : "") +
+ // (childCommentModels != null ? "\", \"childComments\":" + childCommentModels.length : "\"") + '}';
+ // }
+ // }
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java
index d9f11113..2fb1b008 100755
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -5,6 +5,7 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.util.DisplayMetrics;
@@ -158,4 +159,23 @@ public final class Utils {
}
return statusBarHeight;
}
+
+ public static void openURL(final Context context, final String url) {
+ if (context == null || TextUtils.isEmpty(url)) {
+ return;
+ }
+ final Intent i = new Intent(Intent.ACTION_VIEW);
+ i.setData(Uri.parse(url));
+ context.startActivity(i);
+ }
+
+ public static void openEmailAddress(final Context context, final String emailAddress) {
+ if (context == null || TextUtils.isEmpty(emailAddress)) {
+ return;
+ }
+ Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + emailAddress));
+ emailIntent.putExtra(Intent.EXTRA_SUBJECT, "");
+ emailIntent.putExtra(Intent.EXTRA_TEXT, "");
+ context.startActivity(emailIntent);
+ }
}
diff --git a/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewModel.java
new file mode 100644
index 00000000..7b693ea0
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/viewmodels/CommentsViewModel.java
@@ -0,0 +1,19 @@
+package awais.instagrabber.viewmodels;
+
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import java.util.List;
+
+import awais.instagrabber.models.CommentModel;
+
+public class CommentsViewModel extends ViewModel {
+ private MutableLiveData> list;
+
+ public MutableLiveData> getList() {
+ if (list == null) {
+ list = new MutableLiveData<>();
+ }
+ return list;
+ }
+}
diff --git a/app/src/main/java/awais/instagrabber/workers/DownloadWorker.java b/app/src/main/java/awais/instagrabber/workers/DownloadWorker.java
index 5949f420..9785a1ec 100644
--- a/app/src/main/java/awais/instagrabber/workers/DownloadWorker.java
+++ b/app/src/main/java/awais/instagrabber/workers/DownloadWorker.java
@@ -134,34 +134,34 @@ public class DownloadWorker extends Worker {
boolean deletedIPTC = false;
while ((count = bis.read(buffer, 0, 0x2000)) != -1) {
totalRead = totalRead + count;
- if (!deletedIPTC) {
- int iptcStart = -1;
- int fbmdStart = -1;
- int fbmdBytesLen = -1;
- for (int i = 0; i < buffer.length; ++i) {
- if (buffer[i] == (byte) 0xFF && buffer[i + 1] == (byte) 0xED)
- iptcStart = i;
- else if (buffer[i] == (byte) 'F' && buffer[i + 1] == (byte) 'B'
- && buffer[i + 2] == (byte) 'M' && buffer[i + 3] == (byte) 'D') {
- fbmdStart = i;
- fbmdBytesLen = buffer[i - 10] << 24 | (buffer[i - 9] & 0xFF) << 16 |
- (buffer[i - 8] & 0xFF) << 8 | (buffer[i - 7] & 0xFF) |
- (buffer[i - 6] & 0xFF);
- break;
- }
- }
- if (iptcStart != -1 && fbmdStart != -1 && fbmdBytesLen != -1) {
- final int fbmdDataLen = (iptcStart + (fbmdStart - iptcStart) + (fbmdBytesLen - iptcStart)) - 4;
- fos.write(buffer, 0, iptcStart);
- fos.write(buffer, fbmdDataLen + iptcStart, count - fbmdDataLen - iptcStart);
- // setProgressAsync(new Data.Builder().putString(URL, url)
- // .putFloat(PROGRESS, totalRead * 100f / fileSize)
- // .build());
- updateDownloadProgress(notificationId, position, total, totalRead * 100f / fileSize);
- deletedIPTC = true;
- continue;
- }
- }
+ // if (!deletedIPTC) {
+ // int iptcStart = -1;
+ // int fbmdStart = -1;
+ // int fbmdBytesLen = -1;
+ // for (int i = 0; i < buffer.length; ++i) {
+ // if (buffer[i] == (byte) 0xFF && buffer[i + 1] == (byte) 0xED)
+ // iptcStart = i;
+ // else if (buffer[i] == (byte) 'F' && buffer[i + 1] == (byte) 'B'
+ // && buffer[i + 2] == (byte) 'M' && buffer[i + 3] == (byte) 'D') {
+ // fbmdStart = i;
+ // fbmdBytesLen = buffer[i - 10] << 24 | (buffer[i - 9] & 0xFF) << 16 |
+ // (buffer[i - 8] & 0xFF) << 8 | (buffer[i - 7] & 0xFF) |
+ // (buffer[i - 6] & 0xFF);
+ // break;
+ // }
+ // }
+ // if (iptcStart != -1 && fbmdStart != -1 && fbmdBytesLen != -1) {
+ // final int fbmdDataLen = (iptcStart + (fbmdStart - iptcStart) + (fbmdBytesLen - iptcStart)) - 4;
+ // fos.write(buffer, 0, iptcStart);
+ // fos.write(buffer, fbmdDataLen + iptcStart, count - fbmdDataLen - iptcStart);
+ // // setProgressAsync(new Data.Builder().putString(URL, url)
+ // // .putFloat(PROGRESS, totalRead * 100f / fileSize)
+ // // .build());
+ // updateDownloadProgress(notificationId, position, total, totalRead * 100f / fileSize);
+ // deletedIPTC = true;
+ // continue;
+ // }
+ // }
fos.write(buffer, 0, count);
// setProgressAsync(new Data.Builder().putString(URL, url)
// .putFloat(PROGRESS, totalRead * 100f / fileSize)
diff --git a/app/src/main/res/layout/dialog_post_view.xml b/app/src/main/res/layout/dialog_post_view.xml
index 0758bcc2..4f8bce5a 100644
--- a/app/src/main/res/layout/dialog_post_view.xml
+++ b/app/src/main/res/layout/dialog_post_view.xml
@@ -132,7 +132,7 @@
android:layout_height="match_parent"
android:background="@null">
-
+
+
diff --git a/app/src/main/res/layout/fragment_comments.xml b/app/src/main/res/layout/fragment_comments.xml
index 1299c515..4266b9f7 100644
--- a/app/src/main/res/layout/fragment_comments.xml
+++ b/app/src/main/res/layout/fragment_comments.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml
index addaaf72..bf80a5a5 100644
--- a/app/src/main/res/layout/fragment_feed.xml
+++ b/app/src/main/res/layout/fragment_feed.xml
@@ -38,9 +38,9 @@
tools:listitem="@layout/item_feed_photo" />
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml
index ccdd9eee..cb119a13 100755
--- a/app/src/main/res/layout/item_comment.xml
+++ b/app/src/main/res/layout/item_comment.xml
@@ -1,118 +1,117 @@
-
+ android:background="?android:selectableItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:orientation="horizontal"
+ android:padding="8dp">
-
+
+
+ android:ellipsize="marquee"
+ android:paddingStart="4dp"
+ android:paddingTop="2dp"
+ android:paddingEnd="4dp"
+ android:paddingBottom="2dp"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+ android:textColor="?android:textColorPrimary"
+ android:textStyle="bold"
+ app:layout_constraintBottom_toTopOf="@id/tvComment"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/ivProfilePic"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="username" />
-
-
-
-
-
-
-
-
-
-
-
-
+ android:autoLink="web|email"
+ android:ellipsize="end"
+ android:linksClickable="true"
+ android:paddingStart="4dp"
+ android:paddingTop="2dp"
+ android:paddingEnd="4dp"
+ android:paddingBottom="2dp"
+ android:textAppearance="@style/TextAppearance.AppCompat"
+ app:layout_constraintBottom_toTopOf="@id/tvLikes"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toEndOf="@id/ivProfilePic"
+ app:layout_constraintTop_toBottomOf="@id/tvUsername"
+ tools:text="comment comment comment comment comment comment comment comment comment comment comment comment
+ comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment" />
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_comment_small.xml b/app/src/main/res/layout/item_comment_small.xml
index d018b404..9359b1f1 100755
--- a/app/src/main/res/layout/item_comment_small.xml
+++ b/app/src/main/res/layout/item_comment_small.xml
@@ -5,6 +5,9 @@
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:paddingStart="40dp"
+ android:paddingTop="8dp"
+ android:paddingEnd="8dp"
android:paddingBottom="2dp">
+ app:roundAsCircle="true"
+ tools:background="@mipmap/ic_launcher" />
-
+ tools:text="comment comment comment comment comment comment comment comment
+ comment comment comment comment comment comment comment comment comment comment comment comment comment comment
+ comment comment comment comment comment comment " />
-
-
-
-
-
-
+ android:gravity="center_vertical"
+ android:textAppearance="?attr/textAppearanceCaption"
+ tools:text="690000 views" />
+ tools:text="2020-01-01 12:00:00" />
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+ android:layout_height="wrap_content"
+ android:background="?android:selectableItemBackground"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:ellipsize="end"
+ android:focusable="true"
+ android:maxLines="5"
+ android:paddingStart="8dp"
+ android:paddingLeft="8dp"
+ android:paddingEnd="8dp"
+ android:paddingRight="8dp"
+ android:paddingBottom="8dp"
+ android:textAppearance="@style/TextAppearance.AppCompat.Body1"
+ tools:text="Bottom text with hashtags etc." />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_feed_photo.xml b/app/src/main/res/layout/item_feed_photo.xml
index a4312e34..4a4180f8 100644
--- a/app/src/main/res/layout/item_feed_photo.xml
+++ b/app/src/main/res/layout/item_feed_photo.xml
@@ -7,8 +7,7 @@
+ layout="@layout/item_feed_top" />
+ layout="@layout/item_feed_bottom" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_feed_slider.xml b/app/src/main/res/layout/item_feed_slider.xml
index 7b616970..af6cc778 100755
--- a/app/src/main/res/layout/item_feed_slider.xml
+++ b/app/src/main/res/layout/item_feed_slider.xml
@@ -8,8 +8,7 @@
+ layout="@layout/item_feed_top" />
+ layout="@layout/item_feed_bottom" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_feed_top.xml b/app/src/main/res/layout/item_feed_top.xml
index 7306b70d..7aac41b5 100755
--- a/app/src/main/res/layout/item_feed_top.xml
+++ b/app/src/main/res/layout/item_feed_top.xml
@@ -30,7 +30,7 @@
android:paddingRight="8dp"
android:weightSum="2">
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_feed_video.xml b/app/src/main/res/layout/item_feed_video.xml
index ef1d4155..4a806a4b 100755
--- a/app/src/main/res/layout/item_feed_video.xml
+++ b/app/src/main/res/layout/item_feed_video.xml
@@ -7,8 +7,7 @@
+ layout="@layout/item_feed_top" />
+ layout="@layout/item_feed_bottom" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_video_player_with_thumbnail.xml b/app/src/main/res/layout/layout_video_player_with_thumbnail.xml
index 48530c35..c1ee50c3 100644
--- a/app/src/main/res/layout/layout_video_player_with_thumbnail.xml
+++ b/app/src/main/res/layout/layout_video_player_with_thumbnail.xml
@@ -15,7 +15,7 @@
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:actualImageScaleType="fitCenter"
+ app:actualImageScaleType="centerCrop"
app:viewAspectRatio="1" />
-
-
+
#efefef
+ #888888
+
#FFFFFF
#000000
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9ede0933..1103881c 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,8 +9,6 @@
F-Droid
Search username…
Compare
- like
- likes
Error copying text
Copied to clipboard!
Report
@@ -325,6 +323,7 @@
Downloading…
Download item %d of %d
Delete
+ Comment
- %d like
- %d likes