mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-23 05:16:58 +00:00
More updated. Handle clicks. Updated comments viewer, etc
This commit is contained in:
parent
6bf59e83ad
commit
9b83c5e832
6
.idea/compiler.xml
Normal file
6
.idea/compiler.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8" />
|
||||
</component>
|
||||
</project>
|
@ -15,6 +15,7 @@
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
@ -40,7 +40,7 @@
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -1,11 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="app" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
||||
<module name="app" />
|
||||
<module name="InstaGrabber.app" />
|
||||
<option name="DEPLOY" value="true" />
|
||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
||||
<option name="DEPLOY_AS_INSTANT" value="false" />
|
||||
<option name="ARTIFACT_NAME" value="" />
|
||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||
<option name="ALL_USERS" value="false" />
|
||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||
<option name="MODE" value="default_activity" />
|
||||
@ -41,11 +42,16 @@
|
||||
</Native>
|
||||
<Profilers>
|
||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
||||
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
|
||||
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
|
||||
</Profilers>
|
||||
<option name="DEEP_LINK" value="" />
|
||||
<option name="ACTIVITY_CLASS" value="awais.instagrabber.activities.MainActivity" />
|
||||
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
|
||||
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
|
||||
<method v="2">
|
||||
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
|
@ -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'
|
||||
|
@ -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<CommentViewHolder> implements Filterable {
|
||||
public final class CommentsAdapter extends ListAdapter<CommentModel, RecyclerView.ViewHolder> {
|
||||
private static final int TYPE_PARENT = 1;
|
||||
private static final int TYPE_CHILD = 2;
|
||||
|
||||
private CommentModel[] filteredCommentModels;
|
||||
private LayoutInflater layoutInflater;
|
||||
private final Map<Integer, Integer> 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<CommentModel> 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<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;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void publishResults(final CharSequence constraint, @NonNull final FilterResults results) {
|
||||
// if (results.values instanceof List) {
|
||||
// //noinspection unchecked
|
||||
// filteredCommentModels = (List<CommentModel>) results.values;
|
||||
// notifyDataSetChanged();
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
private static final DiffUtil.ItemCallback<CommentModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<CommentModel>() {
|
||||
@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<CommentModel> 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);
|
||||
|
||||
holder.setComment(commentModel.getText());
|
||||
holder.setDate(commentModel.getDateTime());
|
||||
holder.setLiked(commentModel.getLiked());
|
||||
|
||||
final long likes = commentModel.getLikes();
|
||||
holder.setLikes(String.format(LocaleUtils.getCurrentLocale(), "%d %s", likes, quantityStrings[likes == 1 ? 0 : 1]));
|
||||
|
||||
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();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return filteredCommentModels == null ? 0 : filteredCommentModels.length;
|
||||
public void submitList(@Nullable final List<CommentModel> list) {
|
||||
final List<CommentModel> flatList = flattenList(list);
|
||||
super.submitList(flatList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitList(@Nullable final List<CommentModel> list, @Nullable final Runnable commitCallback) {
|
||||
final List<CommentModel> flatList = flattenList(list);
|
||||
super.submitList(flatList, commitCallback);
|
||||
}
|
||||
|
||||
private List<CommentModel> flattenList(final List<CommentModel> list) {
|
||||
if (list == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<CommentModel> flatList = new ArrayList<>();
|
||||
int lastCommentIndex = -1;
|
||||
for (final CommentModel parent : list) {
|
||||
lastCommentIndex++;
|
||||
flatList.add(parent);
|
||||
positionTypeMap.put(lastCommentIndex, TYPE_PARENT);
|
||||
final List<CommentModel> children = parent.getChildCommentModels();
|
||||
for (final CommentModel child : children) {
|
||||
lastCommentIndex++;
|
||||
flatList.add(child);
|
||||
positionTypeMap.put(lastCommentIndex, TYPE_CHILD);
|
||||
}
|
||||
}
|
||||
return flatList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
@ -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<FeedModel, FeedItemViewHolder> {
|
||||
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<FeedModel> diffCallback = new DiffUtil.ItemCallback<FeedModel>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
// 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<FeedModel, FeedItemViewHolder> {
|
||||
// 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<FeedModel> diffCallback = new DiffUtil.ItemCallback<FeedModel>() {
|
||||
// @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();
|
||||
// }
|
||||
// }
|
@ -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<FeedModel, RecyclerView.ViewHolder> {
|
||||
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<FeedModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<FeedModel>() {
|
||||
@ -56,14 +50,10 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie
|
||||
};
|
||||
|
||||
public FeedAdapterV2(@NonNull final PostsLayoutPreferences layoutPreferences,
|
||||
final View.OnClickListener clickListener,
|
||||
final MentionClickListener mentionClickListener,
|
||||
final OnPostClickListener postClickListener) {
|
||||
final FeedItemCallback feedItemCallback) {
|
||||
super(DIFF_CALLBACK);
|
||||
this.layoutPreferences = layoutPreferences;
|
||||
this.clickListener = clickListener;
|
||||
this.mentionClickListener = mentionClickListener;
|
||||
this.postClickListener = postClickListener;
|
||||
this.feedItemCallback = feedItemCallback;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -89,16 +79,16 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie
|
||||
switch (MediaItemType.valueOf(viewType)) {
|
||||
case MEDIA_TYPE_VIDEO: {
|
||||
final ItemFeedVideoBinding binding = ItemFeedVideoBinding.inflate(layoutInflater, parent, false);
|
||||
return new FeedVideoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
|
||||
return new FeedVideoViewHolder(binding, feedItemCallback);
|
||||
}
|
||||
case MEDIA_TYPE_SLIDER: {
|
||||
final ItemFeedSliderBinding binding = ItemFeedSliderBinding.inflate(layoutInflater, parent, false);
|
||||
return new FeedSliderViewHolder(binding, mentionClickListener, clickListener, longClickListener);
|
||||
return new FeedSliderViewHolder(binding, feedItemCallback);
|
||||
}
|
||||
case MEDIA_TYPE_IMAGE:
|
||||
default: {
|
||||
final ItemFeedPhotoBinding binding = ItemFeedPhotoBinding.inflate(layoutInflater, parent, false);
|
||||
return new FeedPhotoViewHolder(binding, mentionClickListener, clickListener, longClickListener);
|
||||
return new FeedPhotoViewHolder(binding, feedItemCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,15 +100,13 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie
|
||||
feedModel.setPosition(position);
|
||||
switch (layoutPreferences.getType()) {
|
||||
case LINEAR:
|
||||
((FeedItemViewHolder) viewHolder).bind(feedModel, postClickListener);
|
||||
((FeedItemViewHolder) viewHolder).bind(feedModel);
|
||||
break;
|
||||
case GRID:
|
||||
case STAGGERED_GRID:
|
||||
default:
|
||||
final boolean animate = position > 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<FeedModel, RecyclerView.Vie
|
||||
return getItem(position).getItemType().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(@NonNull final RecyclerView.ViewHolder viewHolder) {
|
||||
switch (layoutPreferences.getType()) {
|
||||
case LINEAR:
|
||||
((FeedItemViewHolder) viewHolder).clearAnimation();
|
||||
break;
|
||||
case GRID:
|
||||
case STAGGERED_GRID:
|
||||
default:
|
||||
((FeedGridItemViewHolder) viewHolder).clearAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public void setLayoutPreferences(@NonNull final PostsLayoutPreferences layoutPreferences) {
|
||||
this.layoutPreferences = layoutPreferences;
|
||||
}
|
||||
@ -161,9 +136,31 @@ public final class FeedAdapterV2 extends ListAdapter<FeedModel, RecyclerView.Vie
|
||||
// feedSliderViewHolder.stopPlayingVideo();
|
||||
// }
|
||||
|
||||
public interface OnPostClickListener {
|
||||
public interface FeedItemCallback {
|
||||
void onPostClick(final FeedModel feedModel,
|
||||
final View profilePicView,
|
||||
final View mainPostImage);
|
||||
|
||||
void onProfilePicClick(final FeedModel feedModel,
|
||||
final View profilePicView);
|
||||
|
||||
void onNameClick(final FeedModel feedModel,
|
||||
final View profilePicView);
|
||||
|
||||
void onLocationClick(final FeedModel feedModel);
|
||||
|
||||
void onMentionClick(final String mention);
|
||||
|
||||
void onHashtagClick(final String hashtag);
|
||||
|
||||
void onCommentsClick(final FeedModel feedModel);
|
||||
|
||||
void onDownloadClick(final FeedModel feedModel);
|
||||
|
||||
void onEmailClick(final String emailId);
|
||||
|
||||
void onURLClick(final String url);
|
||||
|
||||
void onSliderClick(FeedModel feedModel, int position);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package awais.instagrabber.adapters;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import awais.instagrabber.models.FeedModel;
|
||||
|
||||
public class FeedItemCallbackAdapter implements FeedAdapterV2.FeedItemCallback {
|
||||
@Override
|
||||
public void onPostClick(final FeedModel feedModel, final View profilePicView, final View mainPostImage) {}
|
||||
|
||||
@Override
|
||||
public void onProfilePicClick(final FeedModel feedModel, final View profilePicView) {}
|
||||
|
||||
@Override
|
||||
public void onNameClick(final FeedModel feedModel, final View profilePicView) {}
|
||||
|
||||
@Override
|
||||
public void onLocationClick(final FeedModel feedModel) {}
|
||||
|
||||
@Override
|
||||
public void onMentionClick(final String mention) {}
|
||||
|
||||
@Override
|
||||
public void onHashtagClick(final String hashtag) {}
|
||||
|
||||
@Override
|
||||
public void onCommentsClick(final FeedModel feedModel) {}
|
||||
|
||||
@Override
|
||||
public void onDownloadClick(final FeedModel feedModel) {}
|
||||
|
||||
@Override
|
||||
public void onEmailClick(final String emailId) {}
|
||||
|
||||
@Override
|
||||
public void onURLClick(final String url) {}
|
||||
|
||||
@Override
|
||||
public void onSliderClick(final FeedModel feedModel, final int position) {}
|
||||
}
|
@ -20,6 +20,7 @@ import awais.instagrabber.models.enums.MediaItemType;
|
||||
public final class SliderItemsAdapter extends ListAdapter<PostChild, SliderItemViewHolder> {
|
||||
|
||||
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<PostChild, SliderItemV
|
||||
}
|
||||
};
|
||||
|
||||
public SliderItemsAdapter() {
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
public SliderItemsAdapter(final VerticalDragHelper.OnVerticalDragListener onVerticalDragListener,
|
||||
final LayoutExoCustomControlsBinding controlsBinding,
|
||||
final boolean loadVideoOnItemClick,
|
||||
final SliderCallback sliderCallback) {
|
||||
super(DIFF_CALLBACK);
|
||||
this.onVerticalDragListener = onVerticalDragListener;
|
||||
this.loadVideoOnItemClick = loadVideoOnItemClick;
|
||||
this.sliderCallback = sliderCallback;
|
||||
this.controlsBinding = controlsBinding;
|
||||
}
|
||||
@ -56,7 +55,7 @@ public final class SliderItemsAdapter extends ListAdapter<PostChild, SliderItemV
|
||||
switch (mediaItemType) {
|
||||
case MEDIA_TYPE_VIDEO: {
|
||||
final LayoutVideoPlayerWithThumbnailBinding binding = LayoutVideoPlayerWithThumbnailBinding.inflate(inflater, parent, false);
|
||||
return new SliderVideoViewHolder(binding, onVerticalDragListener, controlsBinding);
|
||||
return new SliderVideoViewHolder(binding, onVerticalDragListener, controlsBinding, loadVideoOnItemClick);
|
||||
}
|
||||
case MEDIA_TYPE_IMAGE:
|
||||
default:
|
||||
|
@ -1,95 +0,0 @@
|
||||
package awais.instagrabber.adapters.viewholder;
|
||||
|
||||
import android.text.Spannable;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.adapters.CommentsAdapter;
|
||||
import awais.instagrabber.customviews.RamboTextView;
|
||||
import awais.instagrabber.interfaces.MentionClickListener;
|
||||
import awais.instagrabber.models.CommentModel;
|
||||
|
||||
public final class CommentViewHolder extends RecyclerView.ViewHolder {
|
||||
private final MentionClickListener mentionClickListener;
|
||||
private final RecyclerView rvChildComments;
|
||||
private final SimpleDraweeView ivProfilePic;
|
||||
private final TextView tvUsername;
|
||||
private final TextView tvDate;
|
||||
private final TextView tvComment;
|
||||
private final TextView tvLikes;
|
||||
private final View container;
|
||||
|
||||
public CommentViewHolder(@NonNull final View itemView,
|
||||
final View.OnClickListener onClickListener,
|
||||
final MentionClickListener mentionClickListener) {
|
||||
super(itemView);
|
||||
|
||||
container = itemView.findViewById(R.id.container);
|
||||
if (onClickListener != null) container.setOnClickListener(onClickListener);
|
||||
|
||||
this.mentionClickListener = mentionClickListener;
|
||||
|
||||
ivProfilePic = itemView.findViewById(R.id.ivProfilePic);
|
||||
tvUsername = itemView.findViewById(R.id.tvUsername);
|
||||
tvDate = itemView.findViewById(R.id.tvDate);
|
||||
tvLikes = itemView.findViewById(R.id.tvLikes);
|
||||
tvComment = itemView.findViewById(R.id.tvComment);
|
||||
|
||||
tvUsername.setSelected(true);
|
||||
tvDate.setSelected(true);
|
||||
|
||||
rvChildComments = itemView.findViewById(R.id.rvChildComments);
|
||||
}
|
||||
|
||||
public final SimpleDraweeView getProfilePicView() {
|
||||
return ivProfilePic;
|
||||
}
|
||||
|
||||
public final boolean isParent() {
|
||||
return rvChildComments != null;
|
||||
}
|
||||
|
||||
public final void setCommentModel(final CommentModel commentModel) {
|
||||
if (container != null) container.setTag(commentModel);
|
||||
}
|
||||
|
||||
public final void setUsername(final String username) {
|
||||
if (tvUsername != null) tvUsername.setText(username);
|
||||
}
|
||||
|
||||
public final void setDate(final String date) {
|
||||
if (tvDate != null) tvDate.setText(date);
|
||||
}
|
||||
|
||||
public final void setLikes(final String likes) {
|
||||
if (tvLikes != null) tvLikes.setText(likes);
|
||||
}
|
||||
|
||||
public final void setLiked(final boolean liked) {
|
||||
if (liked) container.setBackgroundColor(0x40FF69B4);
|
||||
}
|
||||
|
||||
public final void setComment(final CharSequence comment) {
|
||||
if (tvComment != null) {
|
||||
tvComment.setText(comment, comment instanceof Spannable ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL);
|
||||
((RamboTextView) tvComment).setMentionClickListener(mentionClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
public final void setChildAdapter(final CommentsAdapter adapter) {
|
||||
if (isParent()) {
|
||||
rvChildComments.setAdapter(adapter);
|
||||
rvChildComments.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public final void hideChildComments() {
|
||||
if (isParent()) rvChildComments.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
@ -1,11 +1,8 @@
|
||||
package awais.instagrabber.adapters.viewholder;
|
||||
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.net.Uri;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -13,8 +10,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder;
|
||||
import com.facebook.drawee.controller.BaseControllerListener;
|
||||
import com.facebook.imagepipeline.image.ImageInfo;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
|
||||
@ -42,10 +37,9 @@ public class FeedGridItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public void bind(@NonNull final FeedModel feedModel,
|
||||
@NonNull final PostsLayoutPreferences layoutPreferences,
|
||||
final FeedAdapterV2.OnPostClickListener postClickListener,
|
||||
final boolean animate) {
|
||||
if (postClickListener != null) {
|
||||
itemView.setOnClickListener(v -> 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<ImageInfo> imageListener = new BaseControllerListener<ImageInfo>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
@ -22,16 +22,20 @@ 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;
|
||||
this.loadVideoOnItemClick = loadVideoOnItemClick;
|
||||
if (onVerticalDragListener != null) {
|
||||
final VerticalDragHelper thumbnailVerticalDragHelper = new VerticalDragHelper(binding.thumbnailParent);
|
||||
final VerticalDragHelper playerVerticalDragHelper = new VerticalDragHelper(binding.playerView);
|
||||
thumbnailVerticalDragHelper.setOnVerticalDragListener(onVerticalDragListener);
|
||||
@ -51,12 +55,21 @@ public class SliderVideoViewHolder extends SliderItemViewHolder {
|
||||
return playerVerticalDragHelper.onGestureTouchEvent(event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(@NonNull final PostChild model,
|
||||
final int position,
|
||||
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 -> {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
setupComments(feedModel);
|
||||
setupCaption(feedModel);
|
||||
bottomBinding.btnDownload.setOnClickListener(v -> feedItemCallback.onDownloadClick(feedModel));
|
||||
bindItem(feedModel);
|
||||
}
|
||||
|
||||
private void setupComments(final FeedModel feedModel) {
|
||||
final long commentsCount = feedModel.getCommentsCount();
|
||||
bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
|
||||
bottomBinding.commentsCount.setOnClickListener(v -> feedItemCallback.onCommentsClick(feedModel));
|
||||
}
|
||||
|
||||
final String locationName = feedModel.getLocationName();
|
||||
final String locationId = feedModel.getLocationId();
|
||||
setLocation(locationName, locationId);
|
||||
CharSequence postCaption = feedModel.getPostCaption();
|
||||
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) {
|
||||
if (TextUtils.hasMentions(postCaption)) {
|
||||
postCaption = TextUtils.getMentionText(postCaption);
|
||||
feedModel.setPostCaption(postCaption);
|
||||
bottomBinding.viewerCaption.setText(postCaption, TextView.BufferType.SPANNABLE);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
expandCollapseTextView(bottomBinding.viewerCaption, feedModel.getPostCaption());
|
||||
bindItem(feedModel, postClickListener);
|
||||
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 setLocation(final String locationName, final String locationId) {
|
||||
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);
|
||||
}
|
@ -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,19 +40,18 @@ 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;
|
||||
}
|
||||
binding.getRoot().post(() -> {
|
||||
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)
|
||||
// .setLocalThumbnailPreviewsEnabled(true)
|
||||
// .setProgressiveRenderingEnabled(true)
|
||||
.build();
|
||||
binding.imageViewer.setController(Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(requestBuilder)
|
||||
@ -65,63 +61,18 @@ public class FeedPhotoViewHolder extends FeedItemViewHolder {
|
||||
binding.imageViewer.setTapListener(new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
if (postClickListener != null) {
|
||||
postClickListener.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.imageViewer);
|
||||
if (feedItemCallback != null) {
|
||||
feedItemCallback.onPostClick(feedModel, binding.itemFeedTop.ivProfilePic, binding.imageViewer);
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<PostChild> 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();
|
||||
final SliderItemsAdapter adapter = new SliderItemsAdapter(null, null, false, new SliderCallbackAdapter() {
|
||||
@Override
|
||||
public void onItemClicked(final int position) {
|
||||
feedItemCallback.onSliderClick(feedModel, position);
|
||||
}
|
||||
// adapter.setSpanCount(spanCount);
|
||||
});
|
||||
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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Void, Void, CommentModel[]> {
|
||||
private final String shortCode;
|
||||
private final FetchListener<CommentModel[]> fetchListener;
|
||||
public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentModel>> {
|
||||
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<CommentModel[]> fetchListener) {
|
||||
private final String shortCode;
|
||||
private final FetchListener<List<CommentModel>> fetchListener;
|
||||
|
||||
public CommentsFetcher(final String shortCode, final FetchListener<List<CommentModel>> fetchListener) {
|
||||
this.shortCode = shortCode;
|
||||
this.fetchListener = fetchListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected CommentModel[] doInBackground(final Void... voids) {
|
||||
protected List<CommentModel> 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<Void, Void, CommentModel[]>
|
||||
|
||||
https://www.instagram.com/graphql/query/?query_hash=51fdd02b67508306ad4484ff574a0b62&variables={"comment_id":"18100041898085322","first":50,"after":""}
|
||||
*/
|
||||
final ArrayList<CommentModel> commentModels = getParentComments();
|
||||
|
||||
final List<CommentModel> commentModels = getParentComments();
|
||||
for (final CommentModel commentModel : commentModels) {
|
||||
final CommentModel[] childCommentModels = commentModel.getChildCommentModels();
|
||||
final List<CommentModel> 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<CommentModel> 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<Void, Void, CommentModel[]>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final CommentModel[] result) {
|
||||
protected void onPostExecute(final List<CommentModel> result) {
|
||||
if (fetchListener != null) fetchListener.onResult(result);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private synchronized CommentModel[] getChildComments(final String commentId) {
|
||||
final ArrayList<CommentModel> commentModels = new ArrayList<>();
|
||||
|
||||
private synchronized List<CommentModel> getChildComments(final String commentId) {
|
||||
final List<CommentModel> 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<Void, Void, CommentModel[]>
|
||||
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,12 +104,23 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, CommentModel[]>
|
||||
|
||||
if (childComment != null) {
|
||||
final JSONObject owner = childComment.getJSONObject("owner");
|
||||
final ProfileModel profileModel = new ProfileModel(false, false, false,
|
||||
final ProfileModel profileModel = new ProfileModel(false,
|
||||
false,
|
||||
false,
|
||||
owner.getString(Constants.EXTRAS_ID),
|
||||
owner.getString(Constants.EXTRAS_USERNAME),
|
||||
null, null, null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
owner.getString("profile_pic_url"),
|
||||
null, 0, 0, 0, false, false, false, false);
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
|
||||
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
|
||||
|
||||
@ -129,24 +134,24 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, CommentModel[]>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conn.disconnect();
|
||||
} catch (final Exception e) {
|
||||
if (logCollector != null)
|
||||
logCollector.appendException(e, LogCollector.LogFile.ASYNC_COMMENTS_FETCHER, "getChildComments",
|
||||
logCollector.appendException(e,
|
||||
LogCollector.LogFile.ASYNC_COMMENTS_FETCHER,
|
||||
"getChildComments",
|
||||
new Pair<>("commentModels.size", commentModels.size()));
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return commentModels.toArray(new CommentModel[0]);
|
||||
return commentModels;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private synchronized ArrayList<CommentModel> getParentComments() {
|
||||
final ArrayList<CommentModel> commentModelsList = new ArrayList<>();
|
||||
|
||||
private synchronized List<CommentModel> getParentComments() {
|
||||
final List<CommentModel> 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<Void, Void, CommentModel[]>
|
||||
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<Void, Void, CommentModel[]>
|
||||
|
||||
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,
|
||||
final ProfileModel profileModel = new ProfileModel(false,
|
||||
false,
|
||||
owner.optBoolean("is_verified"),
|
||||
owner.getString(Constants.EXTRAS_ID),
|
||||
owner.getString(Constants.EXTRAS_USERNAME),
|
||||
null, null, null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
owner.getString("profile_pic_url"),
|
||||
null, 0, 0, 0, false, false, false, false);
|
||||
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,
|
||||
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<Void, Void, CommentModel[]>
|
||||
hasNextPage = false;
|
||||
}
|
||||
|
||||
final CommentModel[] childCommentModels = new CommentModel[childCommentsLen];
|
||||
final List<CommentModel> 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,
|
||||
final ProfileModel childProfileModel = new ProfileModel(false,
|
||||
false,
|
||||
tempJsonObject.optBoolean("is_verified"),
|
||||
tempJsonObject.getString(Constants.EXTRAS_ID),
|
||||
tempJsonObject.getString(Constants.EXTRAS_USERNAME),
|
||||
null, null, null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
tempJsonObject.getString("profile_pic_url"),
|
||||
null, 0, 0, 0, false, false, false, false);
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
|
||||
tempJsonObject = childComment.optJSONObject("edge_liked_by");
|
||||
childCommentModels[j] = new CommentModel(childComment.getString(Constants.EXTRAS_ID),
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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<List<FeedModel>> fetchListener = new FetchListener<List<FeedModel>>() {
|
||||
@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());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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<OnMentionClickListener> onMentionClickListeners = new ArrayList<>();
|
||||
private final List<OnHashtagClickListener> onHashtagClickListeners = new ArrayList<>();
|
||||
private final List<OnURLClickListener> onURLClickListeners = new ArrayList<>();
|
||||
private final List<OnEmailClickListener> 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
if (loadPlayerOnClick) {
|
||||
loadPlayer();
|
||||
}
|
||||
});
|
||||
setThumbnail();
|
||||
setupControls();
|
||||
@ -262,36 +267,29 @@ public class VideoPlayerViewHelper implements Player.EventListener {
|
||||
speedPopup.setOnMenuItemClickListener(item -> {
|
||||
float nextSpeed;
|
||||
int textResId;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.pt_two_five_x:
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.pt_two_five_x) {
|
||||
nextSpeed = 0.25f;
|
||||
textResId = R.string.pt_two_five_x;
|
||||
break;
|
||||
case R.id.pt_five_x:
|
||||
} else if (itemId == R.id.pt_five_x) {
|
||||
nextSpeed = 0.5f;
|
||||
textResId = R.string.pt_five_x;
|
||||
break;
|
||||
case R.id.pt_seven_five_x:
|
||||
} else if (itemId == R.id.pt_seven_five_x) {
|
||||
nextSpeed = 0.75f;
|
||||
textResId = R.string.pt_seven_five_x;
|
||||
break;
|
||||
case R.id.one_x:
|
||||
} else if (itemId == R.id.one_x) {
|
||||
nextSpeed = 1f;
|
||||
textResId = R.string.one_x;
|
||||
break;
|
||||
case R.id.one_pt_two_five_x:
|
||||
} else if (itemId == 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:
|
||||
} else if (itemId == R.id.one_pt_five_x) {
|
||||
nextSpeed = 1.5f;
|
||||
textResId = R.string.one_pt_five_x;
|
||||
break;
|
||||
case R.id.two_x:
|
||||
} else if (itemId == R.id.two_x) {
|
||||
nextSpeed = 2f;
|
||||
textResId = R.string.two_x;
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
nextSpeed = 1;
|
||||
textResId = R.string.one_x;
|
||||
}
|
||||
|
@ -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:
|
||||
if (checkedId == R.id.layout_linear) {
|
||||
preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.LINEAR);
|
||||
preferencesBuilder.setColCount(1);
|
||||
binding.staggeredOrGridOptions.setVisibility(View.GONE);
|
||||
break;
|
||||
case R.id.layout_staggered:
|
||||
} 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();
|
||||
break;
|
||||
case R.id.layout_grid:
|
||||
default:
|
||||
} else {
|
||||
preferencesBuilder.setType(PostsLayoutPreferences.PostsLayoutType.GRID);
|
||||
if (preferencesBuilder.getColCount() == 1) {
|
||||
preferencesBuilder.setColCount(2);
|
||||
}
|
||||
binding.staggeredOrGridOptions.setVisibility(View.VISIBLE);
|
||||
initStaggeredOrGridOptions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -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:
|
||||
if (checkedId == R.id.col_count_two) {
|
||||
preferencesBuilder.setColCount(2);
|
||||
break;
|
||||
case R.id.col_count_three:
|
||||
default:
|
||||
} else {
|
||||
preferencesBuilder.setColCount(3);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -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:
|
||||
if (checkedId == R.id.avatar_size_tiny) {
|
||||
preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.TINY);
|
||||
break;
|
||||
case R.id.avatar_size_small:
|
||||
} else if (checkedId == R.id.avatar_size_small) {
|
||||
preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.SMALL);
|
||||
break;
|
||||
case R.id.avatar_size_regular:
|
||||
default:
|
||||
} else {
|
||||
preferencesBuilder.setProfilePicSize(PostsLayoutPreferences.ProfilePicSize.REGULAR);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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<Boolean>() {
|
||||
@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,40 +221,68 @@ 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 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());
|
||||
openProfile("@" + profileModel.getUsername());
|
||||
break;
|
||||
case 1: // view profile pic
|
||||
final FragmentManager fragmentManager = getParentFragmentManager();
|
||||
@ -203,31 +297,31 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
|
||||
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);
|
||||
// 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(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
binding.commentText.postDelayed(() -> {
|
||||
imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
|
||||
if (imm == null) return;
|
||||
imm.showSoftInput(binding.commentText, 0);
|
||||
}
|
||||
}, 200);
|
||||
break;
|
||||
case 5: // like/unlike comment
|
||||
case 4: // like/unlike comment
|
||||
if (csrfToken == null) {
|
||||
return;
|
||||
}
|
||||
if (!commentModel.getLiked()) {
|
||||
mediaService.commentLike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback<Boolean>() {
|
||||
mediaService.commentLike(commentModel.getId(), csrfToken, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
commentModel = null;
|
||||
if (!result) {
|
||||
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
@ -243,10 +337,9 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
|
||||
});
|
||||
return;
|
||||
}
|
||||
mediaService.commentUnlike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback<Boolean>() {
|
||||
mediaService.commentUnlike(commentModel.getId(), csrfToken, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
commentModel = null;
|
||||
if (!result) {
|
||||
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
@ -261,15 +354,14 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 6: // delete comment
|
||||
case 5: // delete comment
|
||||
final String userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
if (userId == null) return;
|
||||
mediaService.deleteComment(
|
||||
postId, userId, commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
postId, userId, commentModel.getId(), csrfToken,
|
||||
new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
commentModel = null;
|
||||
if (!result) {
|
||||
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
@ -286,105 +378,15 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private final View.OnClickListener clickListener = v -> {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof CommentModel) {
|
||||
commentModel = (CommentModel) tag;
|
||||
|
||||
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;
|
||||
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<Boolean>() {
|
||||
@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();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
private void openProfile(final String username) {
|
||||
final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment("@" + username);
|
||||
final NavDirections action = CommentsViewerFragmentDirections.actionGlobalProfileFragment(username);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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() {
|
||||
if (!wasPaused && (sharedProfilePicElement != null || sharedMainPostElement != null)) {
|
||||
binding.getRoot().getBackground().mutate().setAlpha(0);
|
||||
// if (getArguments() == null) return;
|
||||
// final PostViewV2FragmentArgs fragmentArgs = PostViewV2FragmentArgs.fromBundle(getArguments());
|
||||
// feedModel = fragmentArgs.getFeedModel();
|
||||
}
|
||||
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)) {
|
||||
binding.caption.addOnHashtagListener(autoLinkItem -> {
|
||||
final NavController navController = NavHostFragment.findNavController(this);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString("hashtag", originalText);
|
||||
final String originalText = autoLinkItem.getOriginalText().trim();
|
||||
bundle.putString(ARG_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.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);
|
||||
}
|
||||
|
@ -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<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() {
|
||||
// @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<FeedModel> currentFeedModelList = feedViewModel.getList().getValue();
|
||||
// final Map<String, FeedModel> thumbToFeedMap = new HashMap<>();
|
||||
// for (final FeedModel feedModel : result) {
|
||||
// thumbToFeedMap.put(feedModel.getThumbnailUrl(), feedModel);
|
||||
// }
|
||||
// final BaseDataSubscriber<Void> subscriber = new BaseDataSubscriber<Void>() {
|
||||
// int success = 0;
|
||||
// int failed = 0;
|
||||
//
|
||||
// @Override
|
||||
// protected void onNewResultImpl(@NonNull final DataSource<Void> dataSource) {
|
||||
// final Map<String, Object> 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<Void> dataSource) {
|
||||
// failed++;
|
||||
// updateAdapter();
|
||||
// }
|
||||
//
|
||||
// public void updateAdapter() {
|
||||
// if (failed + success != result.length) return;
|
||||
//
|
||||
// }
|
||||
// };
|
||||
// for (final FeedModel feedModel : result) {
|
||||
// final DataSource<Void> ds = Fresco.getImagePipeline()
|
||||
// .prefetchToBitmapCache(ImageRequest.fromUri(feedModel.getThumbnailUrl()), null);
|
||||
// ds.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
|
||||
// }
|
||||
// List<FeedModel> finalList = currentFeedModelList == null || currentFeedModelList.isEmpty()
|
||||
// ? new ArrayList<>()
|
||||
// : new ArrayList<>(currentFeedModelList);
|
||||
// final List<FeedModel> 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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
if (isLocation) {
|
||||
final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
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<FeedModel> 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<BasePostModel> 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<List<FeedModel>> 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<ViewerPostModel> 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));
|
||||
|
@ -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);
|
||||
|
@ -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<CommentModel> 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<CommentModel> getChildCommentModels() {
|
||||
return childCommentModels;
|
||||
}
|
||||
|
||||
public void setChildCommentModels(final CommentModel[] childCommentModels) {
|
||||
public void setChildCommentModels(final List<CommentModel> childCommentModels) {
|
||||
this.childCommentModels = childCommentModels;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<CommentModel>> list;
|
||||
|
||||
public MutableLiveData<List<CommentModel>> getList() {
|
||||
if (list == null) {
|
||||
list = new MutableLiveData<>();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -132,7 +132,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="@null">
|
||||
|
||||
<io.github.armcha.autolink.AutoLinkTextView
|
||||
<awais.instagrabber.customviews.RamboTextViewV2
|
||||
android:id="@+id/caption"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -253,12 +253,32 @@
|
||||
app:iconSize="16dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/player_controls_toggle"
|
||||
app:layout_constraintEnd_toStartOf="@id/comment"
|
||||
app:layout_constraintStart_toEndOf="@id/caption_toggle"
|
||||
app:layout_constraintTop_toTopOf="@id/caption_toggle"
|
||||
app:rippleColor="@color/grey_300"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/comment"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/comment"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textColor="@color/white"
|
||||
android:visibility="visible"
|
||||
app:icon="@drawable/ic_outline_comments_24"
|
||||
app:iconGravity="top"
|
||||
app:iconSize="16dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/player_controls_toggle"
|
||||
app:layout_constraintStart_toEndOf="@id/like"
|
||||
app:layout_constraintTop_toTopOf="@id/caption_toggle"
|
||||
app:rippleColor="@color/grey_300"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_controls_toggle"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
@ -274,7 +294,7 @@
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/save"
|
||||
app:layout_constraintStart_toEndOf="@id/like"
|
||||
app:layout_constraintStart_toEndOf="@id/comment"
|
||||
app:layout_constraintTop_toTopOf="@id/caption_toggle"
|
||||
app:rippleColor="@color/grey_300"
|
||||
tools:visibility="visible" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
@ -17,13 +17,11 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
tools:listitem="@layout/item_comment" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/commentField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
@ -45,4 +43,4 @@
|
||||
android:scrollHorizontally="false" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
@ -38,9 +38,9 @@
|
||||
tools:listitem="@layout/item_feed_photo" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/frag_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
<!--<androidx.fragment.app.FragmentContainerView-->
|
||||
<!-- android:id="@+id/frag_container"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- app:layout_behavior="@string/appbar_scrolling_view_behavior" />-->
|
||||
</awais.instagrabber.customviews.helpers.NestedCoordinatorLayout>
|
@ -1,18 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:orientation="horizontal">
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/ivProfilePic"
|
||||
@ -22,7 +19,8 @@
|
||||
app:actualImageScaleType="centerCrop"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:roundAsCircle="true" />
|
||||
app:roundAsCircle="true"
|
||||
tools:background="@mipmap/ic_launcher" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvUsername"
|
||||
@ -43,7 +41,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="username" />
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
<awais.instagrabber.customviews.RamboTextViewV2
|
||||
android:id="@+id/tvComment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@ -60,7 +58,8 @@
|
||||
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 " />
|
||||
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" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvLikes"
|
||||
@ -72,6 +71,7 @@
|
||||
android:paddingTop="2dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@ -97,22 +97,21 @@
|
||||
tools:text="long date................................" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvChildComments"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginLeft="40dp"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
tools:itemCount="5"
|
||||
tools:listitem="@layout/item_comment_small" />
|
||||
<!--<androidx.recyclerview.widget.RecyclerView-->
|
||||
<!-- android:id="@+id/rvChildComments"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginStart="40dp"-->
|
||||
<!-- android:layout_marginLeft="40dp"-->
|
||||
<!-- app:layoutManager="LinearLayoutManager"-->
|
||||
<!-- tools:itemCount="5"-->
|
||||
<!-- tools:listitem="@layout/item_comment_small" />-->
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:background="#32888888" />
|
||||
</LinearLayout>
|
||||
<!--<View-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="1dp"-->
|
||||
<!-- android:layout_gravity="bottom"-->
|
||||
<!-- android:layout_marginStart="4dp"-->
|
||||
<!-- android:layout_marginEnd="4dp"-->
|
||||
<!-- android:layout_marginBottom="4dp"-->
|
||||
<!-- android:background="#32888888" />-->
|
@ -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">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
@ -15,7 +18,8 @@
|
||||
app:layout_constraintEnd_toStartOf="@id/tvUsername"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:roundAsCircle="true" />
|
||||
app:roundAsCircle="true"
|
||||
tools:background="@mipmap/ic_launcher" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvUsername"
|
||||
@ -36,7 +40,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="username" />
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
<awais.instagrabber.customviews.RamboTextViewV2
|
||||
android:id="@+id/tvComment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@ -55,17 +59,20 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
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 " />
|
||||
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 " />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvLikes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:singleLine="true"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:scrollbars="none"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/tvDate"
|
||||
|
@ -37,29 +37,13 @@
|
||||
tools:text="690000" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/videoViewsContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp"
|
||||
app:srcCompat="@drawable/ic_outline_views_24"
|
||||
app:tint="?android:textColorPrimary" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvVideoViews"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="?attr/textAppearanceButton"
|
||||
tools:text="690000" />
|
||||
</LinearLayout>
|
||||
android:textAppearance="?attr/textAppearanceCaption"
|
||||
tools:text="690000 views" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvPostDate"
|
||||
@ -70,17 +54,18 @@
|
||||
android:maxLines="1"
|
||||
android:padding="8dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:text="690000" />
|
||||
tools:text="2020-01-01 12:00:00" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/btnMute"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:padding="4dp"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_volume_up_24"
|
||||
app:tint="?android:textColorPrimary" />
|
||||
<!--<androidx.appcompat.widget.AppCompatImageView-->
|
||||
<!-- android:id="@+id/btnMute"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:background="?selectableItemBackgroundBorderless"-->
|
||||
<!-- android:padding="4dp"-->
|
||||
<!-- android:visibility="gone"-->
|
||||
<!-- app:srcCompat="@drawable/ic_volume_up_24"-->
|
||||
<!-- app:tint="?android:textColorPrimary"-->
|
||||
<!-- tools:visibility="visible" />-->
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/btnDownload"
|
||||
@ -92,34 +77,21 @@
|
||||
app:tint="?android:textColorPrimary" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:isScrollContainer="true"
|
||||
android:scrollbars="vertical"
|
||||
android:scrollHorizontally="false">
|
||||
|
||||
<FrameLayout
|
||||
<awais.instagrabber.customviews.RamboTextViewV2
|
||||
android:id="@+id/viewerCaption"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
android:id="@+id/viewerCaption"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:selectableItemBackground"
|
||||
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" />
|
||||
</FrameLayout>
|
||||
</ScrollView>
|
||||
tools:text="Bottom text with hashtags etc." />
|
||||
</LinearLayout>
|
@ -7,8 +7,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_top"
|
||||
layout="@layout/item_feed_top"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_top" />
|
||||
|
||||
<awais.instagrabber.customviews.drawee.ZoomableDraweeView
|
||||
android:id="@+id/imageViewer"
|
||||
@ -22,6 +21,5 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_bottom"
|
||||
layout="@layout/item_feed_bottom"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_bottom" />
|
||||
</LinearLayout>
|
@ -8,8 +8,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_top"
|
||||
layout="@layout/item_feed_top"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_top" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -42,6 +41,5 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_bottom"
|
||||
layout="@layout/item_feed_bottom"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_bottom" />
|
||||
</LinearLayout>
|
@ -30,7 +30,7 @@
|
||||
android:paddingRight="8dp"
|
||||
android:weightSum="2">
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -38,7 +38,7 @@
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
tools:text="username" />
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -50,12 +50,12 @@
|
||||
tools:text="location" />
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/viewStoryPost"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
app:srcCompat="@drawable/ic_open_in_new_24"
|
||||
app:tint="?android:textColorPrimary" />
|
||||
<!--<androidx.appcompat.widget.AppCompatImageView-->
|
||||
<!-- android:id="@+id/viewStoryPost"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:layout_gravity="center"-->
|
||||
<!-- android:background="?selectableItemBackgroundBorderless"-->
|
||||
<!-- app:srcCompat="@drawable/ic_open_in_new_24"-->
|
||||
<!-- app:tint="?android:textColorPrimary" />-->
|
||||
</LinearLayout>
|
@ -7,8 +7,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_top"
|
||||
layout="@layout/item_feed_top"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_top" />
|
||||
|
||||
<include
|
||||
android:id="@+id/video_post"
|
||||
@ -16,6 +15,5 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/item_feed_bottom"
|
||||
layout="@layout/item_feed_bottom"
|
||||
android:visibility="gone" />
|
||||
layout="@layout/item_feed_bottom" />
|
||||
</LinearLayout>
|
@ -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" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
|
@ -27,7 +27,7 @@
|
||||
app:nullable="true" />
|
||||
</action>
|
||||
|
||||
<fragment
|
||||
<dialog
|
||||
android:id="@+id/commentsViewerFragment"
|
||||
android:name="awais.instagrabber.fragments.CommentsViewerFragment"
|
||||
android:label="Comments"
|
||||
@ -44,7 +44,7 @@
|
||||
android:name="postUserId"
|
||||
app:argType="string"
|
||||
app:nullable="false" />
|
||||
</fragment>
|
||||
</dialog>
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_commentsViewerFragment"
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
<color name="dm_profile_button_color">#efefef</color>
|
||||
|
||||
<color name="comment_selected">#888888</color>
|
||||
|
||||
<color name="white">#FFFFFF</color>
|
||||
|
||||
<color name="black">#000000</color>
|
||||
|
@ -9,8 +9,6 @@
|
||||
<string name="action_fdroid" translatable="false">F-Droid</string>
|
||||
<string name="action_search">Search username…</string>
|
||||
<string name="action_compare">Compare</string>
|
||||
<string name="single_like">like</string>
|
||||
<string name="multiple_likes">likes</string>
|
||||
<string name="clipboard_error">Error copying text</string>
|
||||
<string name="clipboard_copied">Copied to clipboard!</string>
|
||||
<string name="report">Report</string>
|
||||
@ -325,6 +323,7 @@
|
||||
<string name="downloading">Downloading…</string>
|
||||
<string name="downloader_downloading_child">Download item %d of %d</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="comment">Comment</string>
|
||||
<plurals name="likes_count">
|
||||
<item quantity="one">%d like</item>
|
||||
<item quantity="other">%d likes</item>
|
||||
|
Loading…
Reference in New Issue
Block a user