1
0
mirror of https://github.com/KokaKiwi/BarInsta synced 2024-12-23 13:26:59 +00:00

Added post viewer fragment. Updated almost all places to use this

Remaining places are SavedViewer and DirectMessageThreadFragment
This commit is contained in:
Ammar Githam 2020-09-03 02:02:31 +09:00
parent ded09ab237
commit 13cacf43f9
56 changed files with 2991 additions and 745 deletions

View File

@ -88,8 +88,8 @@ import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.IntentModelType;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox;
import awais.instagrabber.utils.Utils;
@ -149,7 +149,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(
mainActivity.profileModel != null ? mainActivity.profileModel.getId()
: (mainActivity.hashtagModel != null ? mainActivity.userQuery : mainActivity.locationModel.getId()), endCursor, this)
: (mainActivity.hashtagModel != null
? mainActivity.userQuery
: mainActivity.locationModel.getId()),
false,
endCursor,
this)
.setUsername((isLocation || isHashtag) ? null : mainActivity.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
@ -168,7 +173,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() {
@Override
public void doBefore() {
mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.post(() -> mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true));
mainActivity.mainBinding.feedView.feedSwipeRefreshLayout
.post(() -> mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true));
}
@Override
@ -232,7 +238,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
feedAdapter.submitList(mainActivity.feedItems);
feedAdapter.notifyItemRangeInserted(oldSize, result.length);
mainActivity.mainBinding.feedView.feedPosts.post(() -> mainActivity.mainBinding.feedView.feedPosts.setNestedScrollingEnabled(true));
mainActivity.mainBinding.feedView.feedPosts
.post(() -> mainActivity.mainBinding.feedView.feedPosts.setNestedScrollingEnabled(true));
final PostModel feedPostModel = result[result.length - 1];
if (feedPostModel != null) {
@ -308,7 +315,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
private final MentionClickListener mentionClickListener = new MentionClickListener() {
@Override
public void onClick(final RamboTextView view, final String text, final boolean isHashtag, final boolean isLocation) {
new AlertDialog.Builder(mainActivity).setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
new AlertDialog.Builder(mainActivity)
.setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
.setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> {
if (MainActivityBackup.scanHack != null) MainActivityBackup.scanHack.onResult(text);
}).show();
@ -433,7 +441,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} else {
// this changes toolbar title
mainActivity.mainBinding.toolbar.toolbar.setTitle(slideOffset >= 0.466 ? titleDiscover :
(mainActivity.userQuery == null ? resources.getString(R.string.app_name) : mainActivity.userQuery));
(mainActivity.userQuery == null
? resources.getString(R.string.app_name)
: mainActivity.userQuery));
imageTintList = ImageViewCompat.getImageTintList(iconFeed);
alpha = imageTintList != null ? (imageTintList.getDefaultColor() & 0xFF_000000) >> 24 : 0;
@ -482,7 +492,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
collapsingToolbar = mainActivity.mainBinding.profileView.appBarLayout.getChildAt(0);
mainActivity.mainBinding.profileView.mainPosts.setNestedScrollingEnabled(false);
mainActivity.mainBinding.profileView.highlightsList.setLayoutManager(new LinearLayoutManager(mainActivity, LinearLayoutManager.HORIZONTAL, false));
mainActivity.mainBinding.profileView.highlightsList
.setLayoutManager(new LinearLayoutManager(mainActivity, LinearLayoutManager.HORIZONTAL, false));
mainActivity.mainBinding.profileView.highlightsList.setAdapter(mainActivity.highlightsAdapter);
// int color = -1;
@ -554,7 +565,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(mainActivity.profileModel != null ? mainActivity.profileModel.getId()
: (mainActivity.hashtagModel != null ? mainActivity.userQuery : mainActivity.locationModel.getId()), endCursor, postsFetchListener)
: (mainActivity.hashtagModel != null
? mainActivity.userQuery
: mainActivity.locationModel.getId()),
false,
endCursor,
postsFetchListener)
.setUsername((isHashtag || isLocation) ? null : mainActivity.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null;
@ -594,7 +610,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
mainActivity.startActivity(new Intent(mainActivity, PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
.putExtra(Constants.EXTRAS_TYPE, PostItemType.FEED));
break;
case R.id.btnDownload:
@ -656,7 +672,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
mainActivity.mainBinding.feedView.feedPosts.setHasFixedSize(true);
mainActivity.mainBinding.feedView.feedPosts.setLayoutManager(layoutManager);
mainActivity.mainBinding.feedView.feedPosts.setAdapter(feedAdapter = new FeedAdapter(clickListener, (view, text, isHashtag, isLocation) ->
new AlertDialog.Builder(mainActivity).setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
new AlertDialog.Builder(mainActivity)
.setMessage(isHashtag ? R.string.comment_view_mention_hash_search : R.string.comment_view_mention_user_search)
.setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> {
if (MainActivityBackup.scanHack != null) {
mainActivity.mainBinding.drawerLayout.closeDrawers();
@ -673,7 +690,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
new FeedFetcher(feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
});
mainActivity.mainBinding.feedView.feedPosts.addOnScrollListener(feedLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
mainActivity.mainBinding.feedView.feedPosts
.addOnScrollListener(feedLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (feedHasNextPage) {
mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true);
new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -753,10 +771,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
// return true;
// }));
mainActivity.mainBinding.discoverPosts.addOnScrollListener(discoverLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
mainActivity.mainBinding.discoverPosts
.addOnScrollListener(discoverLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (discoverHasMore) {
mainActivity.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true);
new DiscoverFetcher(topic, discoverEndMaxId, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new DiscoverFetcher(topic, discoverEndMaxId, rankToken, discoverFetchListener, false)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
discoverEndMaxId = null;
}
}));
@ -1096,7 +1116,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
mainActivity.mainBinding.profileView.mainFollowing.setText(span);
mainActivity.mainBinding.profileView.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
mainActivity.mainBinding.profileView.mainFullName
.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
CharSequence biography = profileModel.getBiography();
mainActivity.mainBinding.profileView.mainBiography.setCaptionIsExpandable(true);
@ -1127,9 +1148,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> mainActivity.startActivity(new Intent(mainActivity, FollowViewer.class)
.putExtra(Constants.EXTRAS_FOLLOWERS, v == mainActivity.mainBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
.putExtra(Constants.EXTRAS_FOLLOWERS,
v == mainActivity.mainBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID,
profileId));
mainActivity.mainBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
mainActivity.mainBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
@ -1372,18 +1396,23 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
@Override
public void onClick(final View v) {
final String userIdFromCookie = Utils.getUserIdFromCookie(MainHelper.this.cookie);
final boolean isSelf = (isLoggedIn && mainActivity.profileModel != null) && userIdFromCookie != null && userIdFromCookie.equals(mainActivity.profileModel.getId());
final boolean isSelf = (isLoggedIn && mainActivity.profileModel != null) && userIdFromCookie != null && userIdFromCookie
.equals(mainActivity.profileModel.getId());
if (!isLoggedIn
&& Utils.dataBox.getFavorite(mainActivity.userQuery) != null
&& v == mainActivity.mainBinding.profileView.btnFollow) {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery,
Long.parseLong(Utils.dataBox.getFavorite(mainActivity.userQuery).split("/")[1]),
mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", "")));
mainActivity.locationModel != null
? mainActivity.locationModel.getName()
: mainActivity.userQuery.replaceAll("^@", "")));
onRefresh();
} else if (!isLoggedIn
&& (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, System.currentTimeMillis(),
mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", "")));
mainActivity.locationModel != null
? mainActivity.locationModel.getName()
: mainActivity.userQuery.replaceAll("^@", "")));
onRefresh();
} else if (v == mainActivity.mainBinding.profileView.btnFollow) {
new ProfileAction().execute("follow");
@ -1418,12 +1447,31 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
protected Void doInBackground(String... rawAction) {
action = rawAction[0];
final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null ? "tags/" + (mainActivity.hashtagModel.getFollowing() ? "unfollow/" : "follow/") + mainActivity.hashtagModel.getName() + "/" : (action.equals("restrict") && mainActivity.profileModel != null ? "restrict_action" : "friendships/" + mainActivity.profileModel.getId()) + "/" + (action.equals("follow") ?
mainActivity.profileModel.getFollowing() || mainActivity.profileModel.getRequested()
? "unfollow/" : "follow/" :
action.equals("restrict") ?
mainActivity.profileModel.getRestricted() ? "unrestrict/" : "restrict/" :
mainActivity.profileModel.getBlocked() ? "unblock/" : "block/"));
final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null
? "tags/" + (mainActivity.hashtagModel.getFollowing()
? "unfollow/"
: "follow/") + mainActivity.hashtagModel.getName() + "/"
: (action.equals("restrict") && mainActivity.profileModel != null
? "restrict_action"
: "friendships/" + mainActivity.profileModel.getId()) + "/" + (action.equals(
"follow") ?
mainActivity.profileModel
.getFollowing() || mainActivity.profileModel
.getRequested()
? "unfollow/"
: "follow/" :
action.equals(
"restrict")
?
mainActivity.profileModel
.getRestricted()
? "unrestrict/"
: "restrict/"
:
mainActivity.profileModel
.getBlocked()
? "unblock/"
: "block/"));
try {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST");

View File

@ -57,7 +57,7 @@ import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.SuggestionModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.models.enums.SuggestionType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox;
@ -148,9 +148,9 @@ public final class MainActivityBackup extends BaseLanguageActivity {
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
itemGetter = itemGetType -> {
if (itemGetType == ItemGetType.MAIN_ITEMS) return allItems;
if (itemGetType == ItemGetType.DISCOVER_ITEMS) return discoverItems;
if (itemGetType == ItemGetType.FEED_ITEMS) return feedItems;
if (itemGetType == PostItemType.MAIN) return allItems;
if (itemGetType == PostItemType.DISCOVER) return discoverItems;
if (itemGetType == PostItemType.FEED) return feedItems;
return null;
};

View File

@ -6,7 +6,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Animatable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -32,20 +32,17 @@ import androidx.core.view.GestureDetectorCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@ -60,7 +57,7 @@ import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.i.iPostFetcher;
import awais.instagrabber.customviews.CommentMentionClickSpan;
import awais.instagrabber.customviews.helpers.SwipeGestureListener;
import awais.instagrabber.databinding.ActivityViewerBinding;
import awais.instagrabber.databinding.ItemFullPostViewBkBinding;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.SwipeEvent;
import awais.instagrabber.models.BasePostModel;
@ -68,16 +65,17 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import static awais.instagrabber.utils.Utils.settingsHelper;
@Deprecated
public final class PostViewer extends BaseLanguageActivity {
private ActivityViewerBinding viewerBinding;
private String url, prevUsername, commentsEndCursor;
private ItemFullPostViewBkBinding viewerBinding;
private String url, prevUsername;
private ProfileModel profileModel;
private BasePostModel postModel;
private ViewerPostModel viewerPostModel;
@ -90,7 +88,7 @@ public final class PostViewer extends BaseLanguageActivity {
private Resources resources;
private boolean session = false, isFromShare, liked, saved, ok = false;
private int slidePos = 0, lastSlidePos = 0;
private ItemGetType itemGetType;
private PostItemType postItemType;
@SuppressLint("ClickableViewAccessibility")
final View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
private float startX;
@ -117,7 +115,7 @@ public final class PostViewer extends BaseLanguageActivity {
}
};
private final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
final String username = viewerPostModel.getUsername();
final String username = viewerPostModel.getProfileModel().getUsername();
if (which == 0) {
searchUsername(username);
@ -131,7 +129,8 @@ public final class PostViewer extends BaseLanguageActivity {
public void onClick(final View v) {
if (v == viewerBinding.topPanel.ivProfilePic) {
new AlertDialog.Builder(PostViewer.this).setAdapter(profileDialogAdapter, profileDialogListener)
.setNeutralButton(R.string.cancel, null).setTitle(viewerPostModel.getUsername()).show();
.setNeutralButton(R.string.cancel, null)
.setTitle(viewerPostModel.getProfileModel().getUsername()).show();
} else if (v == viewerBinding.ivToggleFullScreen) {
toggleFullscreen();
@ -185,7 +184,6 @@ public final class PostViewer extends BaseLanguageActivity {
ActivityCompat.requestPermissions(this, Utils.PERMS, 8020);
};
private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
private RequestManager glideRequestManager;
private LinearLayout.LayoutParams containerLayoutParams;
private final FetchListener<ViewerPostModel[]> pfl = result -> {
if (result == null || result.length < 1) {
@ -208,15 +206,15 @@ public final class PostViewer extends BaseLanguageActivity {
viewerCaptionParent.setOnTouchListener(gestureTouchListener);
viewerBinding.playerView.setOnTouchListener(gestureTouchListener);
viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
final float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
&& Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
swipeEvent.onSwipe(diffX > 0);
return true;
}
return false;
});
// viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
// final float diffX = e2.getX() - e1.getX();
// if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
// && Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
// swipeEvent.onSwipe(diffX > 0);
// return true;
// }
// return false;
// });
final long commentsCount = viewerPostModel.getCommentsCount();
viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
@ -224,9 +222,12 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
startActivityForResult(new Intent(this, CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
.putExtra(Constants.EXTRAS_USER, postUserId), 6969));
.putExtra(Constants.EXTRAS_SHORTCODE,
postModel.getShortCode())
.putExtra(Constants.EXTRAS_POST,
viewerPostModel.getPostId())
.putExtra(Constants.EXTRAS_USER, postUserId),
6969));
viewerBinding.bottomPanel.btnComments.setClickable(true);
viewerBinding.bottomPanel.btnComments.setEnabled(true);
@ -241,7 +242,7 @@ public final class PostViewer extends BaseLanguageActivity {
}
}
setupPostInfoBar("@" + viewerPostModel.getUsername(), viewerPostModel.getItemType(),
setupPostInfoBar("@" + viewerPostModel.getProfileModel().getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocationName(), viewerPostModel.getLocation());
postCaption = postModel.getPostCaption();
@ -255,11 +256,9 @@ public final class PostViewer extends BaseLanguageActivity {
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewerBinding = ActivityViewerBinding.inflate(getLayoutInflater());
viewerBinding = ItemFullPostViewBkBinding.inflate(getLayoutInflater());
setContentView(viewerBinding.getRoot());
glideRequestManager = Glide.with(this);
final Intent intent = getIntent();
if (intent == null || !intent.hasExtra(Constants.EXTRAS_POST)
|| (postModel = (PostModel) intent.getSerializableExtra(Constants.EXTRAS_POST)) == null) {
@ -270,7 +269,7 @@ public final class PostViewer extends BaseLanguageActivity {
containerLayoutParams = (LinearLayout.LayoutParams) viewerBinding.container.getLayoutParams();
if (intent.hasExtra(Constants.EXTRAS_TYPE))
itemGetType = (ItemGetType) intent.getSerializableExtra(Constants.EXTRAS_TYPE);
postItemType = (PostItemType) intent.getSerializableExtra(Constants.EXTRAS_TYPE);
resources = getResources();
@ -314,17 +313,17 @@ public final class PostViewer extends BaseLanguageActivity {
swipeEvent = isRight -> {
final List<? extends BasePostModel> itemGetterItems;
final boolean isMainSwipe;
final boolean isSwipeable;
if (itemGetType == ItemGetType.SAVED_ITEMS && SavedViewer.itemGetter != null) {
itemGetterItems = SavedViewer.itemGetter.get(itemGetType);
isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.SAVED_ITEMS && isFromShare);
} else if (itemGetType != null && MainActivityBackup.itemGetter != null) {
itemGetterItems = MainActivityBackup.itemGetter.get(itemGetType);
isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.MAIN_ITEMS && isFromShare);
if (postItemType == PostItemType.SAVED && SavedViewer.itemGetter != null) {
itemGetterItems = SavedViewer.itemGetter.get(postItemType);
isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.SAVED && isFromShare);
} else if (postItemType != null && MainActivityBackup.itemGetter != null) {
itemGetterItems = MainActivityBackup.itemGetter.get(postItemType);
isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.MAIN && isFromShare);
} else {
itemGetterItems = null;
isMainSwipe = false;
isSwipeable = false;
}
final BasePostModel[] basePostModels = mediaAdapter.getPostModels();
@ -334,7 +333,7 @@ public final class PostViewer extends BaseLanguageActivity {
if (isRight) {
--slidePos;
if (!isMainSwipe && slidePos < 0) slidePos = 0;
if (!isSwipeable && slidePos < 0) slidePos = 0;
if (slides > 0 && slidePos >= 0) {
if (basePostModels[slidePos] instanceof ViewerPostModel) {
viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
@ -342,10 +341,10 @@ public final class PostViewer extends BaseLanguageActivity {
refreshPost();
return;
}
if (isMainSwipe && --position < 0) position = itemGetterItems.size() - 1;
if (isSwipeable && --position < 0) position = itemGetterItems.size() - 1;
} else {
++slidePos;
if (!isMainSwipe && slidePos >= slides) slidePos = slides - 1;
if (!isSwipeable && slidePos >= slides) slidePos = slides - 1;
if (slides > 0 && slidePos < slides) {
if (basePostModels[slidePos] instanceof ViewerPostModel) {
viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
@ -353,10 +352,10 @@ public final class PostViewer extends BaseLanguageActivity {
refreshPost();
return;
}
if (isMainSwipe && ++position >= itemGetterItems.size()) position = 0;
if (isSwipeable && ++position >= itemGetterItems.size()) position = 0;
}
if (isMainSwipe) {
if (isSwipeable) {
slidePos = 0;
ok = false;
Log.d("AWAISKING_APP", "swipe left <<< post[" + position + "]: " + postModel + " -- " + slides);
@ -386,8 +385,7 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.playerView.setVisibility(View.GONE);
viewerBinding.playerView.setPlayer(null);
viewerBinding.imageViewer.setImageResource(0);
viewerBinding.imageViewer.setImageDrawable(null);
viewerBinding.imageViewer.setController(null);
if (postModel.getShortCode() != null)
new PostFetcher(postModel.getShortCode(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -408,7 +406,7 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.btnMute.setVisibility(View.VISIBLE);
viewerBinding.progressView.setVisibility(View.GONE);
viewerBinding.imageViewer.setVisibility(View.GONE);
viewerBinding.imageViewer.setImageDrawable(null);
viewerBinding.imageViewer.setController(null);
if (viewerPostModel.getVideoViews() > -1) {
viewsContainer.setVisibility(View.VISIBLE);
@ -426,22 +424,36 @@ public final class PostViewer extends BaseLanguageActivity {
.createMediaSource(Uri.parse(url));
mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
@Override
public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadCompleted(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
viewerBinding.progressView.setVisibility(View.GONE);
}
@Override
public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadStarted(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
viewerBinding.progressView.setVisibility(View.VISIBLE);
}
@Override
public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadCanceled(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
viewerBinding.progressView.setVisibility(View.GONE);
}
@Override
public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
public void onLoadError(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData,
final IOException error,
final boolean wasCanceled) {
viewerBinding.progressView.setVisibility(View.GONE);
}
});
@ -459,26 +471,31 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.progressView.setVisibility(View.VISIBLE);
viewerBinding.bottomPanel.btnMute.setVisibility(View.GONE);
viewerBinding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
viewerBinding.imageViewer.setImageDrawable(null);
viewerBinding.imageViewer.setVisibility(View.VISIBLE);
viewerBinding.imageViewer.setZoomable(true);
viewerBinding.imageViewer.setZoomTransitionDuration(420);
viewerBinding.imageViewer.setMaximumScale(7.2f);
glideRequestManager.load(url).listener(new RequestListener<Drawable>() {
final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
.setLocalThumbnailPreviewsEnabled(true)
.setProgressiveRenderingEnabled(true)
.build();
viewerBinding.imageViewer.setController(
Fresco.newDraweeControllerBuilder()
.setImageRequest(requestBuilder)
.setOldController(viewerBinding.imageViewer.getController())
.setLowResImageRequest(ImageRequest.fromUri(url))
.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override
public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target<Drawable> target, final boolean isFirstResource) {
public void onFailure(final String id, final Throwable throwable) {
viewerBinding.progressView.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(final Drawable resource, final Object model, final Target<Drawable> target, final DataSource dataSource, final boolean isFirstResource) {
public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
viewerBinding.progressView.setVisibility(View.GONE);
return false;
}
}).into(viewerBinding.imageViewer);
})
.build()
);
}
private void showDownloadDialog() {
@ -502,15 +519,17 @@ public final class PostViewer extends BaseLanguageActivity {
}
if (postModels.size() > 0)
Utils.batchDownload(this, viewerPostModel.getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER, postModels);
Utils.batchDownload(this, viewerPostModel.getProfileModel().getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER, postModels);
};
new AlertDialog.Builder(this).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)
.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 {
Utils.batchDownload(this, viewerPostModel.getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER, Collections.singletonList(viewerPostModel));
Utils.batchDownload(this, viewerPostModel.getProfileModel().getUsername(), DownloadMethod.DOWNLOAD_POST_VIEWER,
Collections.singletonList(viewerPostModel));
}
}
@ -583,7 +602,7 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.viewerCaption.setText(postCaption);
}
setupPostInfoBar("@" + viewerPostModel.getUsername(), viewerPostModel.getItemType(),
setupPostInfoBar("@" + viewerPostModel.getProfileModel().getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocationName(), viewerPostModel.getLocation());
if (postModel instanceof PostModel) {
@ -682,7 +701,9 @@ public final class PostViewer extends BaseLanguageActivity {
sharingIntent.setType("text/plain");
sharingIntent.putExtra(Intent.EXTRA_TEXT, "https://instagram.com/p/" + postShortCode);
startActivity(Intent.createChooser(sharingIntent,
(result.isPrivate()) ? getString(R.string.share_private_post) : getString(R.string.share_public_post)));
(result.isPrivate())
? getString(R.string.share_private_post)
: getString(R.string.share_public_post)));
});
}
}

View File

@ -109,7 +109,10 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(
profileModel != null ? profileModel.getId()
: (hashtagModel != null ? ("#" + hashtagModel.getName()) : locationModel.getId()), endCursor, this)
: (hashtagModel != null ? ("#" + hashtagModel.getName()) : locationModel.getId()),
false,
endCursor,
this)
.setUsername((isLocation || isHashtag) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
@ -185,7 +188,9 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
final Intent newintent;
if (which == 0 || storyModels == null || storyModels.length < 1) {
newintent = new Intent(this, ProfilePicViewer.class).putExtra(
((hashtagModel != null) ? Constants.EXTRAS_HASHTAG : (locationModel != null ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_PROFILE)),
((hashtagModel != null)
? Constants.EXTRAS_HASHTAG
: (locationModel != null ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_PROFILE)),
((hashtagModel != null) ? hashtagModel : (locationModel != null ? locationModel : profileModel)));
}
// else
@ -239,7 +244,11 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(profileModel != null ? profileModel.getId()
: (hashtagModel != null ? ("#" + hashtagModel.getName()) : locationModel.getId()), endCursor, postsFetchListener)
: (hashtagModel != null
? ("#" + hashtagModel.getName())
: locationModel.getId()),
isHashtag,
endCursor, postsFetchListener)
.setUsername((isHashtag || isLocation) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null;
@ -555,7 +564,8 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
profileBinding.profileView.mainFollowing.setText(span);
profileBinding.profileView.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
profileBinding.profileView.mainFullName
.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
CharSequence biography = profileModel.getBiography();
profileBinding.profileView.mainBiography.setCaptionIsExpandable(true);
@ -586,8 +596,10 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent(ProfileViewer.this, FollowViewer.class)
.putExtra(Constants.EXTRAS_FOLLOWERS, v == profileBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
.putExtra(Constants.EXTRAS_FOLLOWERS,
v == profileBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
profileBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
@ -749,12 +761,16 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
favouriteAction.setOnMenuItemClickListener(item -> {
if (Utils.dataBox.getFavorite(userQuery) == null) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
favouriteAction.setIcon(R.drawable.ic_like);
} else {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
favouriteAction.setIcon(R.drawable.ic_not_liked);
}
return true;
@ -835,11 +851,15 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (!isLoggedIn && Utils.dataBox.getFavorite(userQuery) != null && v == profileBinding.profileView.btnFollow) {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
onRefresh();
} else if (!isLoggedIn && (v == profileBinding.profileView.btnFollow || v == profileBinding.profileView.btnFollowTag)) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", "")));
locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
onRefresh();
} else if (v == profileBinding.profileView.btnFollow) {
new ProfileAction().execute("follow");
@ -877,7 +897,9 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
final String url = "https://www.instagram.com/web/" +
((action.equals("followtag") && hashtagModel != null) ? ("tags/" +
(hashtagModel.getFollowing() ? "unfollow/" : "follow/") + hashtagModel.getName() + "/") : (
((action.equals("restrict") && profileModel != null) ? "restrict_action" : ("friendships/" + profileModel.getId())) + "/" +
((action.equals("restrict") && profileModel != null)
? "restrict_action"
: ("friendships/" + profileModel.getId())) + "/" +
((action.equals("follow") && profileModel != null) ?
((profileModel.getFollowing() ||
(!profileModel.getFollowing() && profileModel.getRequested()))

View File

@ -38,7 +38,7 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.ItemGetter;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@ -123,7 +123,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(action, endCursor, this)
currentlyExecuting = new PostsFetcher(action, false, endCursor, this)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
savedBinding.swipeRefreshLayout.setRefreshing(false);
@ -173,7 +173,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, username)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.SAVED_ITEMS));
.putExtra(Constants.EXTRAS_TYPE, PostItemType.SAVED));
}, (model, position) -> {
if (!postsAdapter.isSelecting()) {
@ -203,14 +203,15 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
currentlyExecuting = action.charAt(0) == '^'
? new iLikedFetcher(endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
: new PostsFetcher(action, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
: new PostsFetcher(action, false, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null;
}
});
savedBinding.mainPosts.addOnScrollListener(lazyLoader);
itemGetter = itemGetType -> {
if (itemGetType == ItemGetType.SAVED_ITEMS)
if (itemGetType == PostItemType.SAVED)
return postsViewModel.getList().getValue();
return null;
};

View File

@ -0,0 +1,77 @@
package awais.instagrabber.adapters;
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 java.util.Arrays;
import awais.instagrabber.adapters.viewholder.PostViewerViewHolder;
import awais.instagrabber.databinding.ItemFullPostViewBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.ViewerPostModelWrapper;
public class PostViewAdapter extends ListAdapter<ViewerPostModelWrapper, PostViewerViewHolder> {
private final OnPostViewChildViewClickListener clickListener;
private final OnPostCaptionLongClickListener longClickListener;
private final MentionClickListener mentionClickListener;
private static final DiffUtil.ItemCallback<ViewerPostModelWrapper> diffCallback = new DiffUtil.ItemCallback<ViewerPostModelWrapper>() {
@Override
public boolean areItemsTheSame(@NonNull final ViewerPostModelWrapper oldItem,
@NonNull final ViewerPostModelWrapper newItem) {
return oldItem.getPosition() == newItem.getPosition();
}
@Override
public boolean areContentsTheSame(@NonNull final ViewerPostModelWrapper oldItem,
@NonNull final ViewerPostModelWrapper newItem) {
return Arrays.equals(oldItem.getViewerPostModels(), newItem.getViewerPostModels());
}
};
public PostViewAdapter(final OnPostViewChildViewClickListener clickListener,
final OnPostCaptionLongClickListener longClickListener,
final MentionClickListener mentionClickListener) {
super(diffCallback);
this.clickListener = clickListener;
this.longClickListener = longClickListener;
this.mentionClickListener = mentionClickListener;
}
@Override
public void onViewDetachedFromWindow(@NonNull final PostViewerViewHolder holder) {
holder.stopPlayingVideo();
}
@NonNull
@Override
public PostViewerViewHolder onCreateViewHolder(@NonNull final ViewGroup parent,
final int viewType) {
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
final ItemFullPostViewBinding binding = ItemFullPostViewBinding
.inflate(layoutInflater, parent, false);
return new PostViewerViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final PostViewerViewHolder holder, final int position) {
final ViewerPostModelWrapper item = getItem(position);
holder.bind(item, position, clickListener, longClickListener, mentionClickListener);
}
public interface OnPostViewChildViewClickListener {
void onClick(View v,
ViewerPostModelWrapper viewerPostModelWrapper,
int postPosition,
int childPosition);
}
public interface OnPostCaptionLongClickListener {
void onLongClick(String text);
}
}

View File

@ -0,0 +1,203 @@
package awais.instagrabber.adapters;
import android.net.Uri;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import awais.instagrabber.customviews.drawee.ZoomableDraweeView;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
public class PostViewerChildAdapter extends ListAdapter<ViewerPostModel, PostViewerChildAdapter.ChildViewHolder> {
private static final DiffUtil.ItemCallback<ViewerPostModel> diffCallback = new DiffUtil.ItemCallback<ViewerPostModel>() {
@Override
public boolean areItemsTheSame(@NonNull final ViewerPostModel oldItem, @NonNull final ViewerPostModel newItem) {
return oldItem.getPostId().equals(newItem.getPostId()) && oldItem.getShortCode().equals(newItem.getShortCode());
}
@Override
public boolean areContentsTheSame(@NonNull final ViewerPostModel oldItem, @NonNull final ViewerPostModel newItem) {
return oldItem.getPostId().equals(newItem.getPostId()) && oldItem.getShortCode().equals(newItem.getShortCode());
}
};
public PostViewerChildAdapter() {
super(diffCallback);
}
@NonNull
@Override
public ChildViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
// final AppCompatTextView textView = new AppCompatTextView(parent.getContext());
// textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// return new ChildViewHolder(textView);
final MediaItemType mediaItemType = MediaItemType.valueOf(viewType);
if (mediaItemType == null) return getPlaceholder(parent);
switch (mediaItemType) {
case MEDIA_TYPE_IMAGE:
return getImageViewHolder(parent);
case MEDIA_TYPE_VIDEO:
return getVideoViewHolder(parent);
default:
return getPlaceholder(parent);
}
}
private ChildViewHolder getImageViewHolder(final ViewGroup parent) {
final ZoomableDraweeView view = new ZoomableDraweeView(parent.getContext());
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return new ChildViewHolder(view);
}
private ChildViewHolder getVideoViewHolder(final ViewGroup parent) {
final PlayerView view = new PlayerView(parent.getContext());
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return new ChildViewHolder(view);
}
private ChildViewHolder getPlaceholder(final ViewGroup parent) {
final AppCompatTextView textView = new AppCompatTextView(parent.getContext());
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
textView.setGravity(Gravity.CENTER);
textView.setText("Placeholder");
return new ChildViewHolder(textView);
}
@Override
public void onBindViewHolder(@NonNull final ChildViewHolder holder, final int position) {
holder.bind(getItem(position));
}
@Override
public int getItemViewType(final int position) {
final ViewerPostModel item = getItem(position);
return item.getItemType().getId();
}
@Override
public void onViewDetachedFromWindow(@NonNull final ChildViewHolder holder) {
if (holder.itemView instanceof PlayerView) {
final Player player = ((PlayerView) holder.itemView).getPlayer();
if (player != null) {
player.setPlayWhenReady(false);
}
}
}
@Override
public void onViewRecycled(@NonNull final ChildViewHolder holder) {
if (holder.itemView instanceof PlayerView) {
final Player player = ((PlayerView) holder.itemView).getPlayer();
if (player != null) {
player.release();
}
return;
}
if (holder.itemView instanceof ZoomableDraweeView) {
((ZoomableDraweeView) holder.itemView).setController(null);
}
}
public static class ChildViewHolder extends RecyclerView.ViewHolder {
public ChildViewHolder(@NonNull final View itemView) {
super(itemView);
}
public void bind(final ViewerPostModel item) {
final MediaItemType mediaItemType = item.getItemType();
switch (mediaItemType) {
case MEDIA_TYPE_IMAGE:
bindImage(item);
break;
case MEDIA_TYPE_VIDEO:
bindVideo(item);
break;
default:
}
}
private void bindImage(final ViewerPostModel item) {
final ZoomableDraweeView imageView = (ZoomableDraweeView) itemView;
imageView.setController(null);
final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(item.getDisplayUrl()))
.setLocalThumbnailPreviewsEnabled(true)
.setProgressiveRenderingEnabled(true)
.build();
final DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(requestBuilder)
.setOldController(imageView.getController())
// .setControllerListener(new BaseControllerListener<ImageInfo>() {
//
// @Override
// public void onFailure(final String id, final Throwable throwable) {
// // viewerBinding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
// // viewerBinding.progressView.setVisibility(View.GONE);
// }
// })
.build();
imageView.setController(controller);
}
private void bindVideo(final ViewerPostModel item) {
final SimpleExoPlayer player = new SimpleExoPlayer.Builder(itemView.getContext()).build();
final PlayerView playerView = (PlayerView) itemView;
playerView.setPlayer(player);
float vol = Utils.settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
player.setVolume(vol);
player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(itemView.getContext(), "instagram"))
.createMediaSource(Uri.parse(item.getDisplayUrl()));
// mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
// @Override
// public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// viewerBinding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// viewerBinding.progressView.setVisibility(View.VISIBLE);
// }
//
// @Override
// public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// viewerBinding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
// viewerBinding.progressView.setVisibility(View.GONE);
// }
// });
player.prepare(mediaSource);
player.setVolume(vol);
// viewerBinding.bottomPanel.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
// viewerBinding.bottomPanel.btnMute.setOnClickListener(onClickListener);
}
}
}

View File

@ -0,0 +1,199 @@
package awais.instagrabber.adapters.viewholder;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ui.PlayerView;
import java.util.ArrayList;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.adapters.PostViewAdapter.OnPostCaptionLongClickListener;
import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
import awais.instagrabber.adapters.PostViewerChildAdapter;
import awais.instagrabber.databinding.ItemFullPostViewBinding;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.ViewerPostModelWrapper;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Utils;
public class PostViewerViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "PostViewerViewHolder";
private final ItemFullPostViewBinding binding;
private int currentChildPosition;
public PostViewerViewHolder(@NonNull final ItemFullPostViewBinding binding) {
super(binding.getRoot());
this.binding = binding;
binding.topPanel.viewStoryPost.setVisibility(View.GONE);
}
public void bind(final ViewerPostModelWrapper wrapper,
final int position,
final OnPostViewChildViewClickListener clickListener,
final OnPostCaptionLongClickListener longClickListener,
final MentionClickListener mentionClickListener) {
if (wrapper == null) return;
final ViewerPostModel[] items = wrapper.getViewerPostModels();
if (items == null || items.length <= 0) return;
if (items[0] == null) return;
final PostViewerChildAdapter adapter = new PostViewerChildAdapter();
binding.mediaViewPager.setAdapter(adapter);
final ViewerPostModel firstPost = items[0];
setPostInfo(firstPost, mentionClickListener);
setMediaItems(items, adapter);
setupListeners(wrapper,
position,
clickListener,
longClickListener,
mentionClickListener,
firstPost.getLocation());
}
private void setPostInfo(final ViewerPostModel firstPost,
final MentionClickListener mentionClickListener) {
final ProfileModel profileModel = firstPost.getProfileModel();
if (profileModel == null) return;
binding.topPanel.title.setText(profileModel.getUsername());
final String locationName = firstPost.getLocationName();
if (!Utils.isEmpty(locationName)) {
binding.topPanel.location.setVisibility(View.VISIBLE);
binding.topPanel.location.setText(locationName);
} else binding.topPanel.location.setVisibility(View.GONE);
binding.topPanel.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
binding.bottomPanel.commentsCount.setText(String.valueOf(firstPost.getCommentsCount()));
final CharSequence postCaption = firstPost.getPostCaption();
if (Utils.hasMentions(postCaption)) {
binding.bottomPanel.viewerCaption
.setText(Utils.getMentionText(postCaption), TextView.BufferType.SPANNABLE);
binding.bottomPanel.viewerCaption.setMentionClickListener(mentionClickListener);
} else {
binding.bottomPanel.viewerCaption.setMentionClickListener(null);
binding.bottomPanel.viewerCaption.setText(postCaption);
}
binding.bottomPanel.tvPostDate.setText(firstPost.getPostDate());
}
private void setupListeners(final ViewerPostModelWrapper wrapper,
final int position,
final OnPostViewChildViewClickListener clickListener,
final OnPostCaptionLongClickListener longClickListener,
final MentionClickListener mentionClickListener,
final String location) {
final View.OnClickListener onClickListener = v -> clickListener
.onClick(v, wrapper, position, currentChildPosition);
binding.bottomPanel.btnComments.setOnClickListener(onClickListener);
binding.topPanel.title.setOnClickListener(onClickListener);
binding.topPanel.ivProfilePic.setOnClickListener(onClickListener);
binding.bottomPanel.btnDownload.setOnClickListener(onClickListener);
binding.bottomPanel.viewerCaption.setOnClickListener(onClickListener);
binding.bottomPanel.viewerCaption.setOnLongClickListener(v -> {
longClickListener.onLongClick(binding.bottomPanel.viewerCaption.getText().toString());
return true;
});
if (!Utils.isEmpty(location)) {
binding.topPanel.location.setOnClickListener(v -> mentionClickListener
.onClick(binding.topPanel.location, location, false, true));
}
}
private void setMediaItems(final ViewerPostModel[] items,
final PostViewerChildAdapter adapter) {
final List<ViewerPostModel> filteredList = new ArrayList<>();
for (final ViewerPostModel model : items) {
final MediaItemType itemType = model.getItemType();
if (itemType == MediaItemType.MEDIA_TYPE_VIDEO || itemType == MediaItemType.MEDIA_TYPE_IMAGE) {
filteredList.add(model);
}
}
binding.mediaCounter.setVisibility(filteredList.size() > 1 ? View.VISIBLE : View.GONE);
final String counter = "1/" + filteredList.size();
binding.mediaCounter.setText(counter);
adapter.submitList(filteredList);
binding.mediaViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(final int position) {
if (filteredList.size() <= 0 || position >= filteredList.size()) return;
currentChildPosition = position;
final String counter = (position + 1) + "/" + filteredList.size();
binding.mediaCounter.setText(counter);
final ViewerPostModel viewerPostModel = filteredList.get(position);
if (viewerPostModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) {
setVideoDetails(viewerPostModel);
setVolumeListener(position);
return;
}
setImageDetails();
}
});
}
private void setVolumeListener(final int position) {
binding.bottomPanel.btnMute.setOnClickListener(v -> {
try {
final RecyclerView.ViewHolder viewHolder = ((RecyclerView) binding.mediaViewPager
.getChildAt(0)).findViewHolderForAdapterPosition(position);
if (viewHolder != null) {
final View itemView = viewHolder.itemView;
if (itemView instanceof PlayerView) {
final SimpleExoPlayer player = (SimpleExoPlayer) ((PlayerView) itemView)
.getPlayer();
if (player == null) return;
final float vol = player.getVolume() == 0f ? 1f : 0f;
player.setVolume(vol);
binding.bottomPanel.btnMute
.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
Utils.sessionVolumeFull = vol == 1f;
}
}
} catch (Exception e) {
Log.e(TAG, "Error", e);
}
});
}
private void setImageDetails() {
binding.bottomPanel.btnMute.setVisibility(View.GONE);
binding.bottomPanel.videoViewsContainer.setVisibility(View.GONE);
}
private void setVideoDetails(final ViewerPostModel viewerPostModel) {
binding.bottomPanel.btnMute.setVisibility(View.VISIBLE);
final long videoViews = viewerPostModel.getVideoViews();
if (videoViews < 0) {
binding.bottomPanel.videoViewsContainer.setVisibility(View.GONE);
return;
}
binding.bottomPanel.tvVideoViews.setText(String.valueOf(videoViews));
binding.bottomPanel.videoViewsContainer.setVisibility(View.VISIBLE);
}
public void stopPlayingVideo() {
try {
final RecyclerView.ViewHolder viewHolder = ((RecyclerView) binding.mediaViewPager
.getChildAt(0)).findViewHolderForAdapterPosition(currentChildPosition);
if (viewHolder != null) {
final View itemView = viewHolder.itemView;
if (itemView instanceof PlayerView) {
final Player player = ((PlayerView) itemView).getPlayer();
if (player != null) {
player.setPlayWhenReady(false);
}
}
}
} catch (Exception e) {
Log.e(TAG, "Error", e);
}
}
}

View File

@ -2,7 +2,6 @@ package awais.instagrabber.adapters.viewholder.feed;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -10,8 +9,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONObject;
import awais.instagrabber.customviews.CommentMentionClickSpan;
import awais.instagrabber.customviews.RamboTextView;
import awais.instagrabber.databinding.ItemFeedBottomBinding;
@ -37,7 +34,7 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
this.topBinding = topBinding;
this.bottomBinding = bottomBinding;
this.mentionClickListener = mentionClickListener;
topBinding.title.setMovementMethod(new LinkMovementMethod());
// topBinding.title.setMovementMethod(new LinkMovementMethod());
bottomBinding.btnComments.setOnClickListener(clickListener);
topBinding.viewStoryPost.setOnClickListener(clickListener);
topBinding.ivProfilePic.setOnClickListener(clickListener);
@ -63,14 +60,16 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
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));
topBinding.title.setMentionClickListener(
(view, text, isHashtag, isLocation) -> mentionClickListener.onClick(null, profileModel.getUsername(), false, false));
}
bottomBinding.tvPostDate.setText(feedModel.getPostDate());
final long commentsCount = feedModel.getCommentsCount();
bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
final JSONObject location = feedModel.getLocation();
setLocation(location);
final String locationName = feedModel.getLocationName();
final String locationId = feedModel.getLocationId();
setLocation(locationName, locationId);
CharSequence postCaption = feedModel.getPostCaption();
final boolean captionEmpty = Utils.isEmpty(postCaption);
bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
@ -87,22 +86,19 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
bindItem(feedModel);
}
private void setLocation(final JSONObject location) {
if (location == null) {
private void setLocation(final String locationName, final String locationId) {
if (Utils.isEmpty(locationName)) {
topBinding.location.setVisibility(View.GONE);
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
));
} else {
topBinding.location.setVisibility(View.VISIBLE);
topBinding.location.setText(location.optString("name"));
topBinding.location.setText(locationName);
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
));
topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location,
location.optString("id") + "/" + location.optString("slug"),
false,
true));
topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location, locationId, false, true));
}
}

View File

@ -67,7 +67,7 @@ public final class DiscoverFetcher extends AsyncTask<Void, Void, DiscoverItemMod
private ArrayList<DiscoverItemModel> fetchItems(ArrayList<DiscoverItemModel> discoverItemModels, final String maxId) {
try {
final String url = "https://www.instagram.com/explore/grid/?is_prefetch=false&omit_cover_media=true&module=explore_popular" +
"&use_sectional_payload=false&cluster_id="+cluster+"&include_fixed_destinations=true&session_id="+rankToken+maxId;
"&use_sectional_payload=false&cluster_id=" + cluster + "&include_fixed_destinations=true&session_id=" + rankToken + maxId;
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
@ -163,19 +163,21 @@ public final class DiscoverFetcher extends AsyncTask<Void, Void, DiscoverItemMod
final MediaItemType mediaType = Utils.getMediaItemType(media.getInt("media_type"));
final DiscoverItemModel model = new DiscoverItemModel(mediaType,
media.getString(Constants.EXTRAS_ID),
media.getString("pk"),
media.getString("code"),
Utils.getThumbnailUrl(media, mediaType));
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/" + username) : ""));
// to check if file exists
File customDir = null;
if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = settingsHelper.getString(FOLDER_PATH);
if (!Utils.isEmpty(customPath)) customDir = new File(customPath +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER)
? ("/" + username)
: ""));
}
Utils.checkExistence(downloadDir, customDir, mediaType == MediaItemType.MEDIA_TYPE_SLIDER, model);

View File

@ -64,7 +64,7 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
final String json = Utils.readFromConnection(urlConnection);
Log.d(TAG, json);
// Log.d(TAG, json);
final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data")
.getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline");
@ -104,15 +104,24 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
ProfileModel profileModel = null;
if (feedItem.has("owner")) {
final JSONObject owner = feedItem.getJSONObject("owner");
profileModel = new ProfileModel(owner.optBoolean("is_private"),
profileModel = new ProfileModel(
owner.optBoolean("is_private"),
false, // if you can see it then you def follow
owner.optBoolean("is_verified"),
owner.getString(Constants.EXTRAS_ID),
owner.getString(Constants.EXTRAS_USERNAME),
owner.optString("full_name"),
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);
}
JSONObject tempJsonObject = feedItem.optJSONObject("edge_media_preview_comment");
@ -128,7 +137,21 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
captionText = tempJsonObject.getString("text");
}
final FeedModel feedModel = new FeedModel(profileModel,
final JSONObject location = feedItem.optJSONObject("location");
// Log.d(TAG, "location: " + (location == null ? null : location.toString()));
String locationId = null;
String locationName = null;
if (location != null) {
locationName = location.optString("name");
if (location.has("id")) {
locationId = location.getString("id");
} else if (location.has("pk")) {
locationId = location.getString("pk");
}
// Log.d(TAG, "locationId: " + locationId);
}
final FeedModel feedModel = new FeedModel(
profileModel,
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
videoViews,
feedItem.getString(Constants.EXTRAS_ID),
@ -141,7 +164,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
feedItem.getBoolean("viewer_has_liked"),
feedItem.getBoolean("viewer_has_saved"),
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
feedItem.optJSONObject("location"));
locationName,
locationId);
final boolean isSlider = "GraphSidecar".equals(mediaType) && feedItem.has("edge_sidecar_to_children");
@ -161,13 +185,16 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
node.getString(Constants.EXTRAS_ID),
isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
null, null, null,
node.optLong("video_view_count", -1), -1, false, false,
null,
null,
null,
node.optLong("video_view_count", -1),
-1,
false,
false,
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
feedItem.isNull("location") ? null : feedItem.getJSONObject("location").optString("name"),
feedItem.isNull("location") ? null :
(feedItem.getJSONObject("location").optString("id") + "/" +
feedItem.getJSONObject("location").optString("slug")));
locationName,
locationId);
sliderItems[j].setSliderDisplayUrl(node.getString("display_url"));
}
@ -193,7 +220,9 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_FEED_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}
}
return result;

View File

@ -5,7 +5,6 @@ import android.util.Log;
import androidx.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONObject;
import java.math.BigDecimal;
@ -22,12 +21,14 @@ import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel> {
private final FetchListener<LocationModel> fetchListener;
private final String idSlug;
private static final String TAG = "LocationFetcher";
public LocationFetcher(String idSlug, FetchListener<LocationModel> fetchListener) {
private final FetchListener<LocationModel> fetchListener;
private final String id;
public LocationFetcher(final String id, final FetchListener<LocationModel> fetchListener) {
// idSlug = id + "/" + slug UPDATE: slug can be ignored tbh
this.idSlug = idSlug;
this.id = id;
this.fetchListener = fetchListener;
}
@ -37,27 +38,29 @@ public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel>
LocationModel result = null;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/locations/" + idSlug + "/?__a=1").openConnection();
final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/locations/" + id + "/?__a=1")
.openConnection();
conn.setUseCaches(true);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject user = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_LOCATION);
final JSONObject timelineMedia = user.getJSONObject("edge_location_to_media");
if (timelineMedia.has("edges")) {
final JSONArray edges = timelineMedia.getJSONArray("edges");
}
final JSONObject location = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql")
.getJSONObject(Constants.EXTRAS_LOCATION);
final JSONObject timelineMedia = location.getJSONObject("edge_location_to_media");
// if (timelineMedia.has("edges")) {
// final JSONArray edges = timelineMedia.getJSONArray("edges");
// }
result = new LocationModel(
user.getString(Constants.EXTRAS_ID) + "/" + user.getString("slug"),
user.getString("name"),
user.getString("blurb"),
user.getString("website"),
user.getString("profile_pic_url"),
location.getString(Constants.EXTRAS_ID),
location.getString("slug"),
location.getString("name"),
location.getString("blurb"),
location.getString("website"),
location.getString("profile_pic_url"),
timelineMedia.getLong("count"),
BigDecimal.valueOf(user.optDouble("lat", 0d)).toString(),
BigDecimal.valueOf(user.optDouble("lng", 0d)).toString()
BigDecimal.valueOf(location.optDouble("lat", 0d)).toString(),
BigDecimal.valueOf(location.optDouble("lng", 0d)).toString()
);
}
@ -65,9 +68,10 @@ public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel>
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_LOCATION_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}
}
return result;
}

View File

@ -13,6 +13,7 @@ import java.net.URL;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
@ -85,13 +86,14 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
if (commentObject != null && (commentObject = commentObject.optJSONObject("page_info")) != null)
endCursor = commentObject.optString("end_cursor");
final ProfileModel profileModel = ProfileModel.getDefaultProfileModel(null, username);
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
media.getString(Constants.EXTRAS_ID),
isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media),
shortCode,
Utils.isEmpty(postCaption) ? null : postCaption,
username,
profileModel,
isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),
@ -119,7 +121,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
node.getString(Constants.EXTRAS_SHORTCODE),
postCaption,
username,
profileModel,
isChildVideo && node.has("video_view_count") ? node.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),

View File

@ -26,6 +26,7 @@ import static awais.instagrabber.utils.Utils.logCollector;
public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
private static final String TAG = "PostsFetcher";
private boolean isLocation;
private final String endCursor;
private final String id;
private final FetchListener<PostModel[]> fetchListener;
@ -37,8 +38,12 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
this.fetchListener = fetchListener;
}
public PostsFetcher(final String id, final String endCursor, final FetchListener<PostModel[]> fetchListener) {
public PostsFetcher(final String id,
final boolean isLocation,
final String endCursor,
final FetchListener<PostModel[]> fetchListener) {
this.id = id;
this.isLocation = isLocation;
this.endCursor = endCursor == null ? "" : endCursor;
this.fetchListener = fetchListener;
}
@ -53,15 +58,15 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
final boolean isHashTag = id.charAt(0) == '#';
final boolean isSaved = id.charAt(0) == '$';
final boolean isTagged = id.charAt(0) == '%';
final boolean isLocation = id.contains("/");
// final boolean isLocation = id.contains("/");
final String url;
if (isHashTag)
url = "https://www.instagram.com/graphql/query/?query_hash=ded47faa9a1aaded10161a2ff32abb6b&variables=" +
url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" +
"{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isLocation)
url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" +
"{\"id\":\"" + id.split("/")[0] + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
"{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isSaved)
url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" +
"{\"id\":\"" + id.substring(1) + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
@ -84,7 +89,9 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/" + username) : ""));
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER)
? ("/" + username)
: ""));
if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
}

View File

@ -43,7 +43,7 @@ public class DirectThreadBroadcaster extends AsyncTask<DirectThreadBroadcaster.B
final String cookie = settingsHelper.getString(Constants.COOKIE);
final String cc = UUID.randomUUID().toString();
final Map<String, String> form = new HashMap<>();
form.put("_csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
form.put("_csrftoken", Utils.getCsrfTokenFromCookie(cookie));
form.put("_uid", Utils.getUserIdFromCookie(cookie));
form.put("__uuid", settingsHelper.getString(Constants.DEVICE_UUID));
form.put("client_context", cc);

View File

@ -13,6 +13,7 @@ import java.net.URL;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
@ -25,6 +26,8 @@ import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
import static awais.instagrabber.utils.Utils.logCollector;
public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]> {
private static final String TAG = "iPostFetcher";
private final String id;
private final FetchListener<ViewerPostModel[]> fetchListener;
@ -43,18 +46,54 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject media = new JSONObject(Utils.readFromConnection(conn)).getJSONArray("items").getJSONObject(0);
final String username = media.has("user") ? media.getJSONObject("user").getString(Constants.EXTRAS_USERNAME) : null;
final JSONObject media = new JSONObject(Utils.readFromConnection(conn))
.getJSONArray("items")
.getJSONObject(0);
ProfileModel profileModel = null;
if (media.has("user")) {
final JSONObject user = media.getJSONObject("user");
final JSONObject friendshipStatus = user.optJSONObject("friendship_status");
boolean following = false;
boolean isRestricted = false;
boolean outgoingRequest = false;
if (friendshipStatus != null) {
following = friendshipStatus.optBoolean("following");
isRestricted = friendshipStatus.optBoolean("is_restricted");
outgoingRequest = friendshipStatus.optBoolean("outgoing_request");
}
profileModel = new ProfileModel(
user.optBoolean("is_private"),
user.optBoolean("is_private"),
user.optBoolean("is_verified"),
null,
user.getString(Constants.EXTRAS_USERNAME),
user.optString("fullname"),
null,
null,
user.getString("profile_pic_url"),
null,
-1,
-1,
-1,
following,
isRestricted,
false,
outgoingRequest
);
}
if (profileModel == null) {
return new ViewerPostModel[]{};
}
// to check if file exists
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
final boolean shouldDownloadToUserFolder = Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER);
final File downloadDir = new File(
Environment.getExternalStorageDirectory(),
"Download" + (shouldDownloadToUserFolder ? "/" + profileModel.getUsername() : ""));
File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH)
+ (shouldDownloadToUserFolder ? "/" + profileModel.getUsername() : "");
if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
}
@ -75,22 +114,33 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
final long commentsCount = media.optLong("comment_count");
final JSONObject location = media.optJSONObject("location");
String locationId = null;
String locationName = null;
if (location != null) {
locationName = location.optString("name");
if (location.has("id")) {
locationId = location.getString("id");
} else if (location.has("pk")) {
locationId = location.getString("pk");
}
}
// final String locationString = location.optString("id") + "/" + location.optString("slug");
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
final ViewerPostModel postModel = new ViewerPostModel(
mediaItemType,
media.getString(Constants.EXTRAS_ID),
isVideo
? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false)
isVideo ? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false)
: Utils.getHighQualityImage(media),
media.getString("code"),
Utils.isEmpty(postCaption) ? null : postCaption,
username,
profileModel,
isVideo && media.has("view_count") ? media.getLong("view_count") : -1,
timestamp, media.optBoolean("has_liked"), media.optBoolean("has_viewer_saved"),
timestamp, media.optBoolean("has_liked"),
media.optBoolean("has_viewer_saved"),
media.getLong("like_count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"),
media.isNull("location") ? null :
(media.getJSONObject("location").optString("id") + "/" +
media.getJSONObject("location").optString("slug")));
locationName,
locationId);
postModel.setCommentsCount(commentsCount);
@ -106,23 +156,22 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
final JSONObject node = children.getJSONObject(i);
final boolean isChildVideo = node.has("video_duration");
postModels[i] = new ViewerPostModel(isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
postModels[i] = new ViewerPostModel(
isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO
: MediaItemType.MEDIA_TYPE_IMAGE,
media.getString(Constants.EXTRAS_ID),
isChildVideo
? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false)
isChildVideo ? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false)
: Utils.getHighQualityImage(node),
media.getString("code"),
postCaption,
username,
profileModel,
-1,
timestamp, media.optBoolean("has_liked"), media.optBoolean("has_viewer_saved"),
timestamp, media.optBoolean("has_liked"),
media.optBoolean("has_viewer_saved"),
media.getLong("like_count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"),
media.isNull("location") ? null :
(media.getJSONObject("location").optString("id") + "/" +
media.getJSONObject("location").optString("slug")));
locationName,
locationId);
postModels[i].setSliderDisplayUrl(Utils.getHighQualityImage(node));
Utils.checkExistence(downloadDir, customDir, true, postModels[i]);
}
@ -135,7 +184,9 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
} catch (Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground (i)");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}
}
return result;
}

View File

@ -0,0 +1,112 @@
package awais.instagrabber.customviews.helpers;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager2.widget.ViewPager2;
import static androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL;
public class NestedScrollableHost extends FrameLayout {
private int touchSlop;
private float initialX = 0f;
private float initialY = 0f;
public NestedScrollableHost(@NonNull final Context context) {
this(context, null);
}
public NestedScrollableHost(@NonNull final Context context, @Nullable final AttributeSet attrs) {
super(context, attrs);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
handleInterceptTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
}
private void handleInterceptTouchEvent(final MotionEvent e) {
if (getParentViewPager() == null) return;
final int orientation = getParentViewPager().getOrientation();
// Early return if child can't scroll in same direction as parent
if (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) return;
if (e.getAction() == MotionEvent.ACTION_DOWN) {
initialX = e.getX();
initialY = e.getY();
getParent().requestDisallowInterceptTouchEvent(true);
} else if (e.getAction() == MotionEvent.ACTION_MOVE) {
final float dx = e.getX() - initialX;
final float dy = e.getY() - initialY;
final boolean isVpHorizontal = orientation == ORIENTATION_HORIZONTAL;
// assuming ViewPager2 touch-slop is 2x touch-slop of child
final float scaledDx = Math.abs(dx) * (isVpHorizontal ? .5f : 1f);
final float scaledDy = Math.abs(dy) * (isVpHorizontal ? 1f : .5f);
if (scaledDx > touchSlop || scaledDy > touchSlop) {
if (isVpHorizontal == (scaledDy > scaledDx)) {
// Gesture is perpendicular, allow all parents to intercept
getParent().requestDisallowInterceptTouchEvent(false);
} else {
// Gesture is parallel, query child if movement in that direction is possible
if (canChildScroll(orientation, (isVpHorizontal ? dx : dy))) {
// Child can scroll, disallow all parents to intercept
getParent().requestDisallowInterceptTouchEvent(true);
} else {
// Child cannot scroll, allow all parents to intercept
getParent().requestDisallowInterceptTouchEvent(false);
}
}
}
}
}
private boolean canChildScroll(final int orientation, final float delta) {
final int direction = -(int) Math.signum(delta);
final View child = getChild();
if (child == null) return false;
ViewPager2 viewPagerChild = null;
if (child instanceof ViewPager2) {
viewPagerChild = (ViewPager2) child;
}
boolean canScroll;
switch (orientation) {
case 0:
canScroll = child.canScrollHorizontally(direction);
break;
case 1:
canScroll = child.canScrollVertically(direction);
break;
default:
throw new IllegalArgumentException();
}
if (!canScroll || viewPagerChild == null || viewPagerChild.getAdapter() == null)
return canScroll;
// check if viewpager has reached its limits and decide accordingly
return (direction < 0 && viewPagerChild.getCurrentItem() > 0)
|| (direction > 0 && viewPagerChild.getCurrentItem() < viewPagerChild.getAdapter().getItemCount() - 1);
}
public ViewPager2 getParentViewPager() {
View v = (View) getParent();
while (v != null && !(v instanceof ViewPager2)) {
v = (View) v.getParent();
}
return (ViewPager2) v;
}
public View getChild() {
return getChildCount() > 0 ? getChildAt(0) : null;
}
}

View File

@ -17,9 +17,13 @@ public final class RecyclerLazyLoader extends RecyclerView.OnScrollListener {
private final LazyLoadListener lazyLoadListener;
private final RecyclerView.LayoutManager layoutManager;
public RecyclerLazyLoader(@NonNull final RecyclerView.LayoutManager layoutManager, final LazyLoadListener lazyLoadListener) {
public RecyclerLazyLoader(@NonNull final RecyclerView.LayoutManager layoutManager, final LazyLoadListener lazyLoadListener, final int threshold) {
this.layoutManager = layoutManager;
this.lazyLoadListener = lazyLoadListener;
if (threshold > 0) {
this.visibleThreshold = threshold;
return;
}
if (layoutManager instanceof GridLayoutManager) {
this.visibleThreshold = 5 * Math.max(3, ((GridLayoutManager) layoutManager).getSpanCount());
} else if (layoutManager instanceof LinearLayoutManager) {
@ -29,6 +33,10 @@ public final class RecyclerLazyLoader extends RecyclerView.OnScrollListener {
}
}
public RecyclerLazyLoader(@NonNull final RecyclerView.LayoutManager layoutManager, final LazyLoadListener lazyLoadListener) {
this(layoutManager, lazyLoadListener, -1);
}
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
final int totalItemCount = layoutManager.getItemCount();
@ -54,7 +62,8 @@ public final class RecyclerLazyLoader extends RecyclerView.OnScrollListener {
}
if (!loading && lastVisibleItemPosition + visibleThreshold > totalItemCount) {
if (lazyLoadListener != null) lazyLoadListener.onLoadMore(++currentPage, totalItemCount);
if (lazyLoadListener != null)
lazyLoadListener.onLoadMore(++currentPage, totalItemCount);
loading = true;
}
}

View File

@ -136,7 +136,7 @@ public final class DirectDownload extends Activity {
if (notificationManager != null) notificationManager.cancel(1900000000);
if (result != null) {
if (result.length == 1) {
Utils.batchDownload(context, result[0].getUsername(), DownloadMethod.DOWNLOAD_DIRECT,
Utils.batchDownload(context, result[0].getProfileModel().getUsername(), DownloadMethod.DOWNLOAD_DIRECT,
Arrays.asList(result));
} else if (result.length > 1) {
context.startActivity(new Intent(context, MultiDirectDialog.class)

View File

@ -47,7 +47,7 @@ public final class MultiDirectDialog extends BaseLanguageActivity {
return;
}
username = postModels[0].getUsername();
username = postModels[0].getProfileModel().getUsername();
toolbar.setTitle(username);
toolbar.setSubtitle(postModels[0].getShortCode());

View File

@ -1,6 +1,5 @@
package awais.instagrabber.fragments;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.AsyncTask;
@ -25,6 +24,8 @@ import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList;
import java.util.Arrays;
@ -33,7 +34,6 @@ import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HashtagFetcher;
import awais.instagrabber.asyncs.PostsFetcher;
@ -50,7 +50,6 @@ import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@ -191,11 +190,26 @@ public class HashTagFragment extends Fragment {
return;
}
if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, hashtag)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, position)
// .putExtra(Constants.EXTRAS_POST, postModel)
// .putExtra(Constants.EXTRAS_USER, hashtag)
// .putExtra(Constants.EXTRAS_TYPE, PostItemType.MAIN));
final List<PostModel> postModels = postsViewModel.getList().getValue();
if (postModels == null || postModels.size() == 0) return;
if (postModels.get(0) == null) return;
final String postId = postModels.get(0).getPostId();
final boolean isId = postId != null;
final String[] idsOrShortCodes = new String[postModels.size()];
for (int i = 0; i < postModels.size(); i++) {
idsOrShortCodes[i] = isId ? postModels.get(i).getPostId()
: postModels.get(i).getShortCode();
}
final NavDirections action = HashTagFragmentDirections.actionGlobalPostViewFragment(
position,
idsOrShortCodes,
isId);
NavHostFragment.findNavController(this).navigate(action);
}, (model, position) -> {
if (!postsAdapter.isSelecting()) {
@ -242,7 +256,7 @@ public class HashTagFragment extends Fragment {
stopCurrentExecutor();
binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new PostsFetcher(hashtag, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
currentlyExecuting = new PostsFetcher(hashtag, false, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (isLoggedIn) {
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
storyModels = stories;

View File

@ -24,6 +24,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList;
import java.util.Arrays;
@ -32,7 +34,6 @@ import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.LocationFetcher;
import awais.instagrabber.asyncs.PostsFetcher;
@ -49,7 +50,6 @@ import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@ -64,7 +64,7 @@ public class LocationFragment extends Fragment {
private FragmentLocationBinding binding;
private NestedCoordinatorLayout root;
private boolean shouldRefresh = true;
private String location;
private String locationId;
private LocationModel locationModel;
private PostsViewModel postsViewModel;
private PostsAdapter postsAdapter;
@ -89,21 +89,21 @@ public class LocationFragment extends Fragment {
}
};
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
R.menu.multi_select_download_menu,
new PrimaryActionModeCallback.CallbacksHelper() {
R.menu.multi_select_download_menu, new PrimaryActionModeCallback.CallbacksHelper() {
@Override
public void onDestroy(final ActionMode mode) {
onBackPressedCallback.handleOnBackPressed();
}
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
public boolean onActionItemClicked(final ActionMode mode,
final MenuItem item) {
if (item.getItemId() == R.id.action_download) {
if (postsAdapter == null || location == null) {
if (postsAdapter == null || locationId == null) {
return false;
}
Utils.batchDownload(requireContext(),
location,
locationId,
DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels());
checkAndResetAction();
@ -119,7 +119,8 @@ public class LocationFragment extends Fragment {
if (result == null) return;
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
final List<PostModel> postModels = postsViewModel.getList().getValue();
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>()
: new ArrayList<>(postModels);
finalList.addAll(Arrays.asList(result));
postsViewModel.getList().postValue(finalList);
PostModel model = null;
@ -141,7 +142,9 @@ public class LocationFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
public View onCreateView(@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
return root;
@ -171,7 +174,7 @@ public class LocationFragment extends Fragment {
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments());
location = fragmentArgs.getLocation();
locationId = fragmentArgs.getLocationId();
setTitle();
setupPosts();
fetchLocationModel();
@ -190,11 +193,26 @@ public class LocationFragment extends Fragment {
return;
}
if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, location)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
final List<PostModel> postModels = postsViewModel.getList().getValue();
if (postModels == null || postModels.size() == 0) return;
if (postModels.get(0) == null) return;
final String postId = postModels.get(0).getPostId();
final boolean isId = postId != null;
final String[] idsOrShortCodes = new String[postModels.size()];
for (int i = 0; i < postModels.size(); i++) {
idsOrShortCodes[i] = isId ? postModels.get(i).getPostId()
: postModels.get(i).getShortCode();
}
final NavDirections action = LocationFragmentDirections.actionGlobalPostViewFragment(
position,
idsOrShortCodes,
isId);
NavHostFragment.findNavController(this).navigate(action);
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, position)
// .putExtra(Constants.EXTRAS_POST, postModel)
// .putExtra(Constants.EXTRAS_USER, locationId)
// .putExtra(Constants.EXTRAS_TYPE, PostItemType.MAIN));
}, (model, position) -> {
if (!postsAdapter.isSelecting()) {
@ -204,7 +222,8 @@ public class LocationFragment extends Fragment {
if (onBackPressedCallback.isEnabled()) {
return true;
}
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
onBackPressedCallback.setEnabled(true);
actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1);
@ -226,7 +245,7 @@ public class LocationFragment extends Fragment {
private void fetchLocationModel() {
stopCurrentExecutor();
binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new LocationFetcher(location.split("/")[0], result -> {
currentlyExecuting = new LocationFetcher(locationId, result -> {
locationModel = result;
binding.swipeRefreshLayout.setRefreshing(false);
if (locationModel == null) {
@ -243,7 +262,14 @@ public class LocationFragment extends Fragment {
final String locationId = locationModel.getId();
binding.swipeRefreshLayout.setRefreshing(true);
if (isLoggedIn) {
new iStoryStatusFetcher(locationId.split("/")[0], null, true, false, false, false, stories -> {
new iStoryStatusFetcher(
locationId,
null,
true,
false,
false,
false,
stories -> {
storyModels = stories;
if (stories != null && stories.length > 0) {
binding.mainLocationImage.setStoriesBorder();
@ -252,7 +278,8 @@ public class LocationFragment extends Fragment {
}
binding.mainLocationImage.setImageURI(locationModel.getSdProfilePic());
final String postCount = String.valueOf(locationModel.getPostCount());
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count, postCount));
final SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count,
postCount));
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
binding.mainLocPostCount.setText(span);
@ -301,7 +328,7 @@ public class LocationFragment extends Fragment {
private void fetchPosts() {
stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(locationModel.getId(), endCursor, postsFetchListener)
currentlyExecuting = new PostsFetcher(locationModel.getId(), true, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -310,8 +337,8 @@ public class LocationFragment extends Fragment {
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
if (logCollector != null) logCollector.appendException(
e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e);
}
}

View File

@ -0,0 +1,287 @@
package awais.instagrabber.fragments;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.viewpager2.widget.ViewPager2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.adapters.PostViewAdapter;
import awais.instagrabber.adapters.PostViewAdapter.OnPostViewChildViewClickListener;
import awais.instagrabber.asyncs.PostFetcher;
import awais.instagrabber.asyncs.i.iPostFetcher;
import awais.instagrabber.databinding.FragmentPostViewBinding;
import awais.instagrabber.fragments.main.viewmodels.ViewerPostViewModel;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.ViewerPostModelWrapper;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import static androidx.core.content.ContextCompat.checkSelfPermission;
import static awais.instagrabber.utils.Utils.settingsHelper;
public class PostViewFragment extends Fragment {
private static final String TAG = "PostViewFragment";
private FragmentActivity fragmentActivity;
private FragmentPostViewBinding binding;
private ViewPager2 root;
private boolean shouldRefresh = true;
private ViewerPostViewModel viewerPostViewModel;
private boolean isId;
private int currentPostIndex;
private List<String> idOrCodeList;
private boolean hasInitialResult = false;
private PostViewAdapter adapter;
private boolean session;
private FetchListener<ViewerPostModel[]> pfl = result -> {
if (result == null) return;
if (result.length <= 0) return;
final List<ViewerPostModelWrapper> viewerPostModels = viewerPostViewModel.getList()
.getValue();
final List<ViewerPostModelWrapper> temp = viewerPostModels == null ? new ArrayList<>(
idOrCodeList.size()) : new ArrayList<>(viewerPostModels);
final ViewerPostModel firstPost = result[0];
if (firstPost == null) return;
String idOrCode = isId ? firstPost.getPostId() : firstPost.getShortCode();
if (idOrCode == null) return;
// some values are appended to the post/short code with `_`
idOrCode = idOrCode.substring(0, idOrCode.indexOf('_'));
final int index = idOrCodeList.indexOf(idOrCode);
if (index < 0) return;
final ViewerPostModelWrapper viewerPostModelWrapper = temp.get(index);
viewerPostModelWrapper.setViewerPostModels(result);
temp.set(index, viewerPostModelWrapper);
viewerPostViewModel.getList().setValue(temp);
adapter.notifyItemChanged(index);
if (!hasInitialResult) {
Log.d(TAG, "setting delayed position to: " + currentPostIndex);
binding.getRoot()
.postDelayed(() -> binding.getRoot().setCurrentItem(currentPostIndex), 200);
}
hasInitialResult = true;
};
private MentionClickListener mentionListener = (view, text, isHashtag, isLocation) -> {
if (isHashtag) {
final NavDirections action = PostViewFragmentDirections
.actionGlobalHashTagFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return;
}
if (isLocation) {
final NavDirections action = PostViewFragmentDirections
.actionGlobalLocationFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return;
}
final NavDirections action = PostViewFragmentDirections
.actionGlobalProfileFragment("@" + text);
NavHostFragment.findNavController(this).navigate(action);
};
private OnPostViewChildViewClickListener clickListener = (v, wrapper, postPosition, childPosition) -> {
// final FeedModel feedModel = (FeedModel) tag;
// if (v.getId() == ) {
// if (feedModel.isMentionClicked())
// feedModel.toggleCaption();
// feedModel.setMentionClicked(false);
// if (!FeedItemViewHolder.expandCollapseTextView((RamboTextView) v, feedModel.getPostCaption()))
// feedModel.toggleCaption();
// return;
// }
final ViewerPostModel postModel = wrapper.getViewerPostModels()[0];
final String username = postModel.getProfileModel().getUsername();
final int id = v.getId();
switch (id) {
case R.id.viewerCaption:
break;
case R.id.btnComments:
startActivity(new Intent(requireContext(), CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE,
postModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, postModel.getPostId())
.putExtra(Constants.EXTRAS_USER,
Utils.getUserIdFromCookie(settingsHelper.getString(
Constants.COOKIE))));
break;
case R.id.btnDownload:
if (checkSelfPermission(requireContext(),
Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
showDownloadDialog(Arrays.asList(wrapper.getViewerPostModels()),
childPosition,
username);
return;
}
requestPermissions(Utils.PERMS, 8020);
break;
case R.id.ivProfilePic:
case R.id.title:
mentionListener.onClick(null, username, false, false);
break;
}
};
private PostViewAdapter.OnPostCaptionLongClickListener captionLongClickListener = text -> Utils
.copyText(requireContext(), text);
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentActivity = getActivity();
}
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
return root;
}
binding = FragmentPostViewBinding.inflate(inflater, container, false);
root = binding.getRoot();
setupViewPager();
return root;
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init();
}
private void setupViewPager() {
viewerPostViewModel = new ViewModelProvider(fragmentActivity)
.get(ViewerPostViewModel.class);
adapter = new PostViewAdapter(clickListener, captionLongClickListener, mentionListener);
root.setAdapter(adapter);
root.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(final int position) {
// Log.d(TAG, "onPageSelected: " + position + ", hasInitialResult: " + hasInitialResult);
if (!hasInitialResult) {
return;
}
currentPostIndex = position;
fetchPost();
}
});
viewerPostViewModel.getList().observe(fragmentActivity, list -> adapter.submitList(list));
}
private void init() {
if (getArguments() == null) return;
final PostViewFragmentArgs fragmentArgs = PostViewFragmentArgs.fromBundle(getArguments());
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();
// binding.getRoot().postDelayed(() -> binding.getRoot().setCurrentItem(currentPostIndex), 500);
fetchPost();
// binding.getRoot().setCurrentItem(currentPostIndex);
}
private List<ViewerPostModelWrapper> createPlaceholderModels(final int size) {
final List<ViewerPostModelWrapper> viewerPostModels = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
// viewerPostModels.add(new ViewerPostModel[]{ViewerPostModel.getDefaultModel(-i, "")});
viewerPostModels.add(new ViewerPostModelWrapper(i, null));
}
return viewerPostModels;
}
private void fetchPost() {
// Log.d(TAG, "fetchPost, currentPostIndex: " + currentPostIndex);
final List<ViewerPostModelWrapper> list = viewerPostViewModel.getList().getValue();
if (list != null) {
final ViewerPostModelWrapper viewerPostModels = list.get(currentPostIndex);
if (viewerPostModels != null && viewerPostModels
.getViewerPostModels() != null && viewerPostModels
.getViewerPostModels().length > 0) {
// final ViewerPostModel viewerPostModel = viewerPostModels[0];
// if (viewerPostModel != null) {
// final String postId = viewerPostModel.getPostId();
// try {
// if (postId != null && Integer.parseInt(postId) > 0) {
// // already fetched, don't fetch again
// Log.d(TAG, "returning without fetching");
// return;
// }
// } catch (NumberFormatException ignored) {}
// }
Log.d(TAG, "returning without fetching");
return;
}
}
final String idOrShortCode = idOrCodeList.get(currentPostIndex);
if (isId) {
new iPostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return;
}
new PostFetcher(idOrShortCode, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void showDownloadDialog(final List<ViewerPostModel> postModels,
final int childPosition,
final String username) {
final List<ViewerPostModel> postModelsToDownload = new ArrayList<>();
if (!session && postModels.size() > 1) {
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) {
Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_POST_VIEWER,
postModelsToDownload);
}
};
new AlertDialog.Builder(requireContext())
.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 {
Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_POST_VIEWER,
Collections.singletonList(postModels.get(childPosition)));
}
}
}

View File

@ -0,0 +1,574 @@
// package awais.instagrabber.fragments;
//
// import android.content.Context;
// import android.content.Intent;
// import android.graphics.drawable.Animatable;
// import android.net.Uri;
// import android.os.AsyncTask;
// import android.os.Bundle;
// import android.os.Handler;
// import android.text.SpannableString;
// import android.view.LayoutInflater;
// import android.view.View;
// import android.view.ViewGroup;
// import android.widget.LinearLayout;
// import android.widget.RelativeLayout;
// import android.widget.TextView;
// import android.widget.Toast;
//
// import androidx.annotation.NonNull;
// import androidx.annotation.Nullable;
// import androidx.appcompat.app.AppCompatActivity;
// import androidx.core.view.GestureDetectorCompat;
// import androidx.fragment.app.Fragment;
// import androidx.lifecycle.ViewModelProvider;
// import androidx.recyclerview.widget.LinearLayoutManager;
// import androidx.recyclerview.widget.RecyclerView;
//
// import com.facebook.drawee.backends.pipeline.Fresco;
// import com.facebook.drawee.controller.BaseControllerListener;
// import com.facebook.imagepipeline.image.ImageInfo;
// import com.facebook.imagepipeline.request.ImageRequest;
// import com.facebook.imagepipeline.request.ImageRequestBuilder;
// import com.google.android.exoplayer2.SimpleExoPlayer;
// import com.google.android.exoplayer2.source.MediaSource;
// import com.google.android.exoplayer2.source.MediaSourceEventListener;
// import com.google.android.exoplayer2.source.ProgressiveMediaSource;
// import com.google.android.exoplayer2.upstream.DataSource;
// import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
// import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
// import com.google.android.exoplayer2.upstream.cache.SimpleCache;
//
// import java.io.IOException;
// import java.util.List;
//
// import awais.instagrabber.R;
// import awais.instagrabber.adapters.PostsMediaAdapter;
// import awais.instagrabber.asyncs.PostFetcher;
// import awais.instagrabber.asyncs.ProfileFetcher;
// import awais.instagrabber.asyncs.i.iPostFetcher;
// import awais.instagrabber.customviews.CommentMentionClickSpan;
// import awais.instagrabber.customviews.helpers.SwipeGestureListener;
// import awais.instagrabber.databinding.FragmentPostViewBinding;
// import awais.instagrabber.fragments.main.viewmodels.BasePostViewModel;
// import awais.instagrabber.fragments.main.viewmodels.DiscoverItemViewModel;
// import awais.instagrabber.fragments.main.viewmodels.FeedViewModel;
// import awais.instagrabber.interfaces.FetchListener;
// import awais.instagrabber.interfaces.SwipeEvent;
// import awais.instagrabber.models.BasePostModel;
// import awais.instagrabber.models.PostModel;
// import awais.instagrabber.models.ProfileModel;
// import awais.instagrabber.models.ViewerPostModel;
// import awais.instagrabber.models.enums.MediaItemType;
// import awais.instagrabber.models.enums.PostItemType;
// import awais.instagrabber.utils.Constants;
// import awais.instagrabber.utils.Utils;
//
// import static awais.instagrabber.utils.Utils.settingsHelper;
//
// public class PostViewFragmentBackup extends Fragment {
//
// private FragmentPostViewBinding binding;
// private LinearLayout root;
// private AppCompatActivity fragmentActivity;
// private PostItemType postType;
// private int postIndex;
// private String postId;
// private SimpleExoPlayer player;
// private String postShortCode;
// private BasePostViewModel<?> postViewModel;
// private ViewerPostModel currentPost;
// private List<? extends BasePostModel> postList;
// private LinearLayout.LayoutParams containerLayoutParams;
// private BasePostModel basePostModel;
// private String prevUsername;
// private ProfileModel profileModel;
// private String postUserId;
// private CharSequence postCaption;
//
// private final View.OnClickListener onClickListener = new View.OnClickListener() {
// @Override
// public void onClick(final View v) {
// // if (v == binding.topPanel.ivProfilePic) {
// // new AlertDialog.Builder(requireContext()).setAdapter(profileDialogAdapter, profileDialogListener)
// //.setNeutralButton(R.string.cancel, null).setTitle(viewerPostModel.getUsername()).show();
// // return;
// // }
// if (v == binding.ivToggleFullScreen) {
// // toggleFullscreen();
//
// final LinearLayout topPanelRoot = binding.topPanel.getRoot();
// final int iconRes;
//
// if (containerLayoutParams.weight != 3.3f) {
// containerLayoutParams.weight = 3.3f;
// iconRes = R.drawable.ic_fullscreen_exit;
// topPanelRoot.setVisibility(View.GONE);
// binding.btnDownload.setVisibility(View.VISIBLE);
// binding.bottomPanel.tvPostDate.setVisibility(View.GONE);
// } else {
// containerLayoutParams.weight = (binding.mediaList.getVisibility() == View.VISIBLE) ? 1.35f : 1.9f;
// containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
// iconRes = R.drawable.ic_fullscreen;
// topPanelRoot.setVisibility(View.VISIBLE);
// binding.btnDownload.setVisibility(View.GONE);
// binding.bottomPanel.tvPostDate.setVisibility(View.VISIBLE);
// }
//
// binding.ivToggleFullScreen.setImageResource(iconRes);
// binding.container.setLayoutParams(containerLayoutParams);
//
// } else if (v == binding.bottomPanel.btnMute) {
// if (player != null) {
// final float intVol = player.getVolume() == 0f ? 1f : 0f;
// player.setVolume(intVol);
// binding.bottomPanel.btnMute.setImageResource(intVol == 0f ? R.drawable.ic_volume_off_24 : R.drawable.ic_volume_up_24);
// Utils.sessionVolumeFull = intVol == 1f;
// }
// } else if (v == binding.btnLike) {
// // new PostViewer.PostAction().execute("likes");
// } else if (v == binding.btnBookmark) {
// // new PostViewer.PostAction().execute("save");
// } else {
// // final Object tag = v.getTag();
// // if (tag instanceof ViewerPostModel) {
// // viewerPostModel = (ViewerPostModel) tag;
// // slidePos = Math.max(0, viewerPostModel.getPosition());
// // refreshPost();
// // }
// }
// }
// };
// private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
// private final FetchListener<ViewerPostModel[]> pfl = result -> {
// final Context context = getContext();
// if (result == null || result.length < 1 && context != null) {
// Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
// return;
// }
// currentPost = result[0];
// mediaAdapter.setData(result);
// if (result.length > 1) {
// binding.mediaList.setLayoutParams(new LinearLayout.LayoutParams(
// LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.55f
// ));
// containerLayoutParams.weight = 1.35f;
// containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
// binding.container.setLayoutParams(containerLayoutParams);
// binding.mediaList.setVisibility(View.VISIBLE);
// }
//
// // viewerCaptionParent.setOnTouchListener(gestureTouchListener);
// // binding.playerView.setOnTouchListener(gestureTouchListener);
// // binding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
// // final float diffX = e2.getX() - e1.getX();
// // if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
// // && Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
// // swipeEvent.onSwipe(diffX > 0);
// // return true;
// // }
// // return false;
// // });
//
// final long commentsCount = currentPost.getCommentsCount();
// binding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
// binding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
//
// // binding.bottomPanel.btnComments.setOnClickListener(v -> startActivityForResult(
// // new Intent(requireContext(), CommentsViewer.class)
// // .putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode())
// // .putExtra(Constants.EXTRAS_POST, currentPost.getPostId())
// // .putExtra(Constants.EXTRAS_USER, postUserId), 6969)
// binding.bottomPanel.btnComments.setClickable(true);
// binding.bottomPanel.btnComments.setEnabled(true);
//
// if (basePostModel instanceof PostModel) {
// final PostModel postModel = (PostModel) basePostModel;
// postModel.setPostId(currentPost.getPostId());
// postModel.setTimestamp(currentPost.getTimestamp());
// postModel.setPostCaption(currentPost.getPostCaption());
// // if (!ok) {
// // liked = currentPost.getLike();
// // saved = currentPost.getBookmark();
// // }
// }
// showCurrentPost();
// // refreshPost();
// };
// private int lastSlidePos;
// private int slidePos;
// private String url;
// private SwipeEvent swipeEvent;
// private GestureDetectorCompat gestureDetector;
//
// @Override
// public void onCreate(@Nullable final Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// fragmentActivity = (AppCompatActivity) requireActivity();
// if (fragmentActivity.getSupportActionBar() != null) {
// fragmentActivity.getSupportActionBar().setTitle("");
// }
// setHasOptionsMenu(true);
// }
//
// @Nullable
// @Override
// public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
// if (root != null) {
// return root;
// }
// binding = FragmentPostViewBinding.inflate(inflater, container, false);
// root = binding.getRoot();
// binding.mediaList.setLayoutManager(new LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false));
// binding.mediaList.setAdapter(mediaAdapter);
// binding.mediaList.setVisibility(View.GONE);
// return root;
// }
//
// @Override
// public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
// containerLayoutParams = (LinearLayout.LayoutParams) binding.container.getLayoutParams();
// init();
// }
//
// @Override
// public void onDestroy() {
// super.onDestroy();
// }
//
// private void init() {
// final Bundle arguments = getArguments();
// if (arguments == null) return;
// final PostViewFragmentArgs fragmentArgs = PostViewFragmentArgs.fromBundle(arguments);
// postType = fragmentArgs.getPostType() == null ? null : PostItemType.valueOf(fragmentArgs.getPostType());
// postIndex = fragmentArgs.getPostIndex();
// postId = fragmentArgs.getPostId();
// postShortCode = fragmentArgs.getPostShortCode();
// setupSwipe();
// if (postType != null && postIndex >= 0) {
// basePostModel = getBasePostFromViewModel();
// if (basePostModel != null) {
// if (basePostModel.getShortCode() != null) {
// fetchPostFromShortCode(basePostModel.getShortCode());
// return;
// }
// fetchPostFromPostId(basePostModel.getPostId());
// return;
// }
// }
// // getStartPost();
// // showCurrentPost();
// // setupTop();
// // setupPost();
// // setupBottom();
// }
//
// private void setupSwipe() {
// swipeEvent = isRight -> {
// // final List<? extends BasePostModel> itemGetterItems;
// // final boolean isMainSwipe;
// //
// // if (postType == PostItemType.SAVED && SavedViewer.itemGetter != null) {
// // itemGetterItems = SavedViewer.itemGetter.get(postType);
// // isMainSwipe = !(itemGetterItems.size() < 1 || postType == PostItemType.SAVED && isFromShare);
// // } else if (postType != null && MainActivityBackup.itemGetter != null) {
// // itemGetterItems = MainActivityBackup.itemGetter.get(postType);
// // isMainSwipe = !(itemGetterItems.size() < 1 || postType == PostItemType.MAIN && isFromShare);
// // } else {
// // itemGetterItems = null;
// // isMainSwipe = false;
// // }
// //
// // final BasePostModel[] basePostModels = mediaAdapter.getPostModels();
// // final int slides = basePostModels.length;
// //
// // int position = basePostModel.getPosition();
// //
// // if (isRight) {
// // --slidePos;
// // if (!isMainSwipe && slidePos < 0) slidePos = 0;
// // if (slides > 0 && slidePos >= 0) {
// // if (basePostModels[slidePos] instanceof ViewerPostModel) {
// // currentPost = (ViewerPostModel) basePostModels[slidePos];
// // }
// // showCurrentPost();
// // return;
// // }
// // if (isMainSwipe && --position < 0) position = itemGetterItems.size() - 1;
// // } else {
// // ++slidePos;
// // if (!isMainSwipe && slidePos >= slides) slidePos = slides - 1;
// // if (slides > 0 && slidePos < slides) {
// // if (basePostModels[slidePos] instanceof ViewerPostModel) {
// // currentPost = (ViewerPostModel) basePostModels[slidePos];
// // }
// // showCurrentPost();
// // return;
// // }
// // if (isMainSwipe && ++position >= itemGetterItems.size()) position = 0;
// // }
// //
// // if (isMainSwipe) {
// // slidePos = 0;
// // ok = false;
// // Log.d("AWAISKING_APP", "swipe left <<< post[" + position + "]: " + basePostModel + " -- " + slides);
// // basePostModel = itemGetterItems.get(position);
// // basePostModel.setPosition(position);
// // showCurrentPost();
// // }
// };
// gestureDetector = new GestureDetectorCompat(requireContext(), new SwipeGestureListener(swipeEvent));
// }
//
// private void fetchPostFromPostId(final String postId) {
// new iPostFetcher(postId, pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// }
//
// private void fetchPostFromShortCode(final String shortCode) {
// new PostFetcher(shortCode, pfl)
// .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// }
//
// private BasePostModel getBasePostFromViewModel() {
// switch (postType) {
// case FEED:
// postViewModel = new ViewModelProvider(fragmentActivity).get(FeedViewModel.class);
// break;
// case MAIN:
// // ???
// break;
// case SAVED:
// // ???
// break;
// case DISCOVER:
// postViewModel = new ViewModelProvider(fragmentActivity).get(DiscoverItemViewModel.class);
// }
// if (postViewModel == null) return null;
// postList = postViewModel.getList().getValue();
// if (postList == null) return null;
// return postList.get(postIndex);
// }
//
// private void showCurrentPost() {
// setupPostInfoBar("@" + currentPost.getUsername(),
// currentPost.getItemType(),
// currentPost.getLocationName(),
// currentPost.getLocation());
// // postCaption = basePostModel.getPostCaption();
// ((View) binding.bottomPanel.viewerCaption.getParent()).setVisibility(View.VISIBLE);
// // binding.bottomPanel.btnDownload.setOnClickListener(downloadClickListener);
// if (containerLayoutParams.weight != 3.3f) {
// containerLayoutParams.weight = (binding.mediaList.getVisibility() == View.VISIBLE) ? 1.35f : 1.9f;
// binding.container.setLayoutParams(containerLayoutParams);
// }
// if (binding.mediaList.getVisibility() == View.VISIBLE) {
// ViewerPostModel item = mediaAdapter.getItemAt(lastSlidePos);
// if (item != null) {
// item.setCurrentSlide(false);
// mediaAdapter.notifyItemChanged(lastSlidePos, item);
// }
//
// item = mediaAdapter.getItemAt(slidePos);
// if (item != null) {
// item.setCurrentSlide(true);
// mediaAdapter.notifyItemChanged(slidePos, item);
// }
// }
// lastSlidePos = slidePos;
// postCaption = currentPost.getPostCaption();
//
// if (Utils.hasMentions(postCaption)) {
// binding.bottomPanel.viewerCaption.setText(Utils.getMentionText(postCaption), TextView.BufferType.SPANNABLE);
// // binding.bottomPanel.viewerCaption.setMentionClickListener((view, text, isHashtag, isLocation) -> searchUsername(text));
// } else {
// binding.bottomPanel.viewerCaption.setMentionClickListener(null);
// binding.bottomPanel.viewerCaption.setText(postCaption);
// }
//
// // setupPostInfoBar("@" + viewerPostModel.getUsername(), viewerPostModel.getItemType(),
// // viewerPostModel.getLocationName(), viewerPostModel.getLocation());
//
// // if (postModel instanceof PostModel) {
// // final PostModel postModel = (PostModel) this.postModel;
// // postModel.setPostId(viewerPostModel.getPostId());
// // postModel.setTimestamp(viewerPostModel.getTimestamp());
// // postModel.setPostCaption(viewerPostModel.getPostCaption());
// // if (liked == true) {
// // binding.btnLike.setText(resources.getString(R.string.unlike, viewerPostModel.getLikes()
// // + ((ok && viewerPostModel.getLike() != liked) ? (liked ? 1L : -1L) : 0L)));
// // binding.btnLike.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
// // getApplicationContext(), R.color.btn_pink_background)));
// // } else {
// // binding.btnLike.setText(resources.getString(R.string.like, viewerPostModel.getLikes()
// // + ((ok && viewerPostModel.getLike() != liked) ? (liked ? 1L : -1L) : 0L)));
// // binding.btnLike.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
// // getApplicationContext(), R.color.btn_lightpink_background)));
// // }
// // if (saved == true) {
// // binding.btnBookmark.setText(R.string.unbookmark);
// // binding.btnBookmark.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
// // getApplicationContext(), R.color.btn_orange_background)));
// // } else {
// // binding.btnBookmark.setText(R.string.bookmark);
// // binding.btnBookmark.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
// // getApplicationContext(), R.color.btn_lightorange_background)));
// // }
// // }
//
// binding.bottomPanel.tvPostDate.setText(currentPost.getPostDate());
// binding.bottomPanel.tvPostDate.setVisibility(containerLayoutParams.weight != 3.3f ? View.VISIBLE : View.GONE);
// binding.bottomPanel.tvPostDate.setSelected(true);
//
// url = currentPost.getDisplayUrl();
// // releasePlayer();
//
// binding.btnDownload.setVisibility(containerLayoutParams.weight == 3.3f ? View.VISIBLE : View.GONE);
// if (currentPost.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO) setupVideo();
// else setupImage();
// }
//
// private void setupPostInfoBar(final String username,
// final MediaItemType itemType,
// final String locationName,
// final String location) {
// if (prevUsername == null || !prevUsername.equals(username)) {
// binding.topPanel.ivProfilePic.setImageRequest(null);
// if (!Utils.isEmpty(username) && username.charAt(0) == '@') {
// new ProfileFetcher(username.substring(1), result -> {
// profileModel = result;
//
// if (result != null) {
// // final String hdProfilePic = result.getHdProfilePic();
// // final String sdProfilePic = result.getSdProfilePic();
// postUserId = result.getId();
// // final boolean hdPicEmpty = Utils.isEmpty(hdProfilePic);
// binding.topPanel.ivProfilePic.setImageURI(profileModel.getSdProfilePic());
// binding.topPanel.viewStoryPost.setOnClickListener(v -> {
// if (result.isPrivate()) {
// Toast.makeText(requireContext(), R.string.share_private_post, Toast.LENGTH_LONG).show();
// }
// Intent sharingIntent = new Intent(Intent.ACTION_SEND);
// sharingIntent.setType("text/plain");
// sharingIntent.putExtra(Intent.EXTRA_TEXT, "https://instagram.com/p/" + postShortCode);
// startActivity(Intent.createChooser(sharingIntent, result.isPrivate()
// ? getString(R.string.share_private_post)
// : getString(R.string.share_public_post)));
// });
// }
// }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// }
// prevUsername = username;
// }
//
// final String titlePrefix = getString(itemType == MediaItemType.MEDIA_TYPE_VIDEO ? R.string.post_viewer_video_post : R.string.post_viewer_image_post);
// if (Utils.isEmpty(username)) binding.topPanel.title.setText(titlePrefix);
// else {
// final int titleLen = username.length();
// final SpannableString spannableString = new SpannableString(username);
// spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
// binding.topPanel.title.setText(spannableString);
// }
//
// if (location == null) {
// binding.topPanel.location.setVisibility(View.GONE);
// binding.topPanel.title.setLayoutParams(new RelativeLayout.LayoutParams(
// RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
// } else {
// binding.topPanel.location.setVisibility(View.VISIBLE);
// binding.topPanel.location.setText(locationName);
// // binding.topPanel.location.setOnClickListener(v -> searchUsername(location));
// binding.topPanel.title.setLayoutParams(new RelativeLayout.LayoutParams(
// RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
// ));
// }
// }
//
// private void setupVideo() {
// binding.playerView.setVisibility(View.VISIBLE);
// binding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
// binding.bottomPanel.btnMute.setVisibility(View.VISIBLE);
// binding.progressView.setVisibility(View.GONE);
// binding.imageViewer.setVisibility(View.GONE);
// binding.imageViewer.setController(null);
//
// if (currentPost.getVideoViews() > -1) {
// binding.bottomPanel.videoViewsContainer.setVisibility(View.VISIBLE);
// binding.bottomPanel.tvVideoViews.setText(String.valueOf(currentPost.getVideoViews()));
// }
//
// player = new SimpleExoPlayer.Builder(requireContext()).build();
// binding.playerView.setPlayer(player);
// float vol = Utils.settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f;
// if (vol == 0f && Utils.sessionVolumeFull) vol = 1f;
//
// player.setVolume(vol);
// player.setPlayWhenReady(Utils.settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS));
// final Context context = requireContext();
// final DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context, "instagram");
// final SimpleCache simpleCache = Utils.getSimpleCacheInstance(context);
// CacheDataSourceFactory cacheDataSourceFactory = null;
// if (simpleCache != null) {
// cacheDataSourceFactory = new CacheDataSourceFactory(simpleCache, dataSourceFactory);
// }
// final DataSource.Factory factory = cacheDataSourceFactory != null ? cacheDataSourceFactory : dataSourceFactory;
// final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url));
// mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
// @Override
// public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// binding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// binding.progressView.setVisibility(View.VISIBLE);
// }
//
// @Override
// public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
// binding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
// binding.progressView.setVisibility(View.GONE);
// }
// });
// player.prepare(mediaSource);
// player.setVolume(vol);
// binding.bottomPanel.btnMute.setImageResource(vol == 0f ? R.drawable.ic_volume_up_24 : R.drawable.ic_volume_off_24);
// binding.bottomPanel.btnMute.setOnClickListener(onClickListener);
// }
//
// private void setupImage() {
// binding.bottomPanel.videoViewsContainer.setVisibility(View.GONE);
// binding.playerView.setVisibility(View.GONE);
// binding.progressView.setVisibility(View.VISIBLE);
// binding.bottomPanel.btnMute.setVisibility(View.GONE);
// binding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
// binding.imageViewer.setVisibility(View.VISIBLE);
//
// final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
// .setLocalThumbnailPreviewsEnabled(true)
// .setProgressiveRenderingEnabled(true)
// .build();
// binding.imageViewer.setController(
// Fresco.newDraweeControllerBuilder()
// .setImageRequest(requestBuilder)
// .setOldController(binding.imageViewer.getController())
// .setLowResImageRequest(ImageRequest.fromUri(url))
// .setControllerListener(new BaseControllerListener<ImageInfo>() {
//
// @Override
// public void onFailure(final String id, final Throwable throwable) {
// binding.progressView.setVisibility(View.GONE);
// }
//
// @Override
// public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
// binding.progressView.setVisibility(View.GONE);
// }
// })
// .build()
// );
// }
// }

View File

@ -33,6 +33,8 @@ import androidx.core.content.ContextCompat;
import androidx.core.view.GestureDetectorCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.facebook.drawee.backends.pipeline.Fresco;
@ -57,7 +59,6 @@ import java.util.List;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.StoriesAdapter;
import awais.instagrabber.asyncs.CommentAction;
import awais.instagrabber.asyncs.DownloadAsync;
@ -72,7 +73,6 @@ import awais.instagrabber.fragments.main.viewmodels.FeedStoriesViewModel;
import awais.instagrabber.fragments.main.viewmodels.StoriesViewModel;
import awais.instagrabber.interfaces.SwipeEvent;
import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.stickers.PollModel;
@ -121,6 +121,7 @@ public class StoryViewerFragment extends Fragment {
private int currentFeedStoryIndex;
private StoriesViewModel storiesViewModel;
private String currentStoryMediaId;
private boolean shouldRefresh = true;
private final String cookie = settingsHelper.getString(Constants.COOKIE);
private StoryViewerFragmentArgs fragmentArgs;
@ -137,6 +138,7 @@ public class StoryViewerFragment extends Fragment {
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
return root;
}
binding = ActivityStoryViewerBinding.inflate(inflater, container, false);
@ -146,6 +148,7 @@ public class StoryViewerFragment extends Fragment {
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init();
}
@ -342,9 +345,17 @@ public class StoryViewerFragment extends Fragment {
});
binding.viewStoryPost.setOnClickListener(v -> {
final Object tag = v.getTag();
if (tag instanceof CharSequence)
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString(), tag.toString().matches("^[\\d]+$"))));
if (!(tag instanceof CharSequence)) return;
final String postId = tag.toString();
final boolean isId = tag.toString().matches("^[\\d]+$");
final String[] idsOrShortCodes = new String[]{postId};
final NavDirections action = HashTagFragmentDirections.actionGlobalPostViewFragment(
0,
idsOrShortCodes,
isId);
NavHostFragment.findNavController(this).navigate(action);
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_POST, new PostModel(, ));
});
final View.OnClickListener storyActionListener = v -> {
final Object tag = v.getTag();
@ -352,9 +363,14 @@ public class StoryViewerFragment extends Fragment {
poll = (PollModel) tag;
if (poll.getMyChoice() > -1) {
new AlertDialog.Builder(requireContext()).setTitle(R.string.voted_story_poll)
.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, new String[]{
(poll.getMyChoice() == 0 ? "" : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")",
(poll.getMyChoice() == 1 ? "" : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")"
.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1,
new String[]{
(poll.getMyChoice() == 0 ? "" : "") + poll
.getLeftChoice() + " (" + poll
.getLeftCount() + ")",
(poll.getMyChoice() == 1 ? "" : "") + poll
.getRightChoice() + " (" + poll
.getRightCount() + ")"
}), null)
.setPositiveButton(R.string.ok, null)
.show();
@ -567,7 +583,9 @@ public class StoryViewerFragment extends Fragment {
dir = new File(dir, currentStoryUsername);
if (dir.exists() || dir.mkdirs()) {
final String storyUrl = currentStory.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO ? currentStory.getVideoUrl() : currentStory.getStoryUrl();
final String storyUrl = currentStory.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO
? currentStory.getVideoUrl()
: currentStory.getStoryUrl();
final File saveFile = new File(dir, currentStory.getStoryMediaId() + "_" + currentStory.getTimestamp()
+ Utils.getExtensionFromModel(storyUrl, currentStory));
@ -598,8 +616,16 @@ public class StoryViewerFragment extends Fragment {
.setImageRequest(requestBuilder)
.setOldController(binding.imageViewer.getController())
.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
public void onFailure(final String id, final Throwable throwable) {
binding.progressView.setVisibility(View.GONE);
}
@Override
public void onFinalImageSet(final String id,
final ImageInfo imageInfo,
final Animatable animatable) {
if (menuDownload != null) {
menuDownload.setVisible(true);
}
@ -627,7 +653,10 @@ public class StoryViewerFragment extends Fragment {
.createMediaSource(Uri.parse(url));
mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
@Override
public void onLoadCompleted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadCompleted(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
if (menuDownload != null) menuDownload.setVisible(true);
if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie))
menuDm.setVisible(true);
@ -635,7 +664,10 @@ public class StoryViewerFragment extends Fragment {
}
@Override
public void onLoadStarted(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadStarted(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
if (menuDownload != null) menuDownload.setVisible(true);
if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie))
menuDm.setVisible(true);
@ -643,12 +675,20 @@ public class StoryViewerFragment extends Fragment {
}
@Override
public void onLoadCanceled(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) {
public void onLoadCanceled(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData) {
binding.progressView.setVisibility(View.GONE);
}
@Override
public void onLoadError(final int windowIndex, @Nullable final MediaSource.MediaPeriodId mediaPeriodId, final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, final IOException error, final boolean wasCanceled) {
public void onLoadError(final int windowIndex,
@Nullable final MediaSource.MediaPeriodId mediaPeriodId,
final LoadEventInfo loadEventInfo,
final MediaLoadData mediaLoadData,
final IOException error,
final boolean wasCanceled) {
if (menuDownload != null) menuDownload.setVisible(false);
if (menuDm != null) menuDm.setVisible(false);
binding.progressView.setVisibility(View.GONE);

View File

@ -48,6 +48,7 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
private AsyncTask<Void, Void, InboxModel> currentlyRunning;
private InboxThreadModelListViewModel listViewModel;
public static boolean refreshPlease = false;
private boolean shouldRefresh = true;
private final FetchListener<InboxModel> fetchListener = new FetchListener<InboxModel>() {
@Override
@ -89,6 +90,7 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
final ViewGroup container,
final Bundle savedInstanceState) {
if (root != null) {
shouldRefresh = false;
return root;
}
binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false);
@ -99,16 +101,22 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
layoutManager = new LinearLayoutManager(requireContext());
inboxList.setLayoutManager(layoutManager);
final DirectMessageInboxAdapter inboxAdapter = new DirectMessageInboxAdapter(inboxThreadModel -> {
final NavDirections action = DirectMessageInboxFragmentDirections.actionDMInboxFragmentToDMThreadFragment(inboxThreadModel.getThreadId(), inboxThreadModel.getThreadTitle());
final NavDirections action = DirectMessageInboxFragmentDirections
.actionDMInboxFragmentToDMThreadFragment(inboxThreadModel.getThreadId(), inboxThreadModel.getThreadTitle());
NavHostFragment.findNavController(this).navigate(action);
});
inboxList.setAdapter(inboxAdapter);
listViewModel = new ViewModelProvider(this).get(InboxThreadModelListViewModel.class);
listViewModel.getList().observe(fragmentActivity, inboxAdapter::submitList);
initData();
return root;
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
initData();
}
@Override
public void onRefresh() {
endCursor = null;
@ -130,8 +138,10 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
@Override
public void onDestroy() {
super.onDestroy();
if (listViewModel != null) {
listViewModel.getList().postValue(Collections.emptyList());
}
}
private void initData() {
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {

View File

@ -210,8 +210,10 @@ public class DirectMessageThreadFragment extends Fragment {
switch (itemType) {
case MEDIA_SHARE:
case CLIP:
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_POST, new PostModel(directItemModel.getMediaModel().getCode(), false)));
final long postId = directItemModel.getMediaModel().getPk();
final boolean isId = true;
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_POST, new PostModel(postId, false)));
break;
case LINK:
Intent linkIntent = new Intent(Intent.ACTION_VIEW);

View File

@ -1,6 +1,5 @@
package awais.instagrabber.fragments.main;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.ActionMode;
@ -19,6 +18,8 @@ import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList;
import java.util.Arrays;
@ -27,7 +28,6 @@ import java.util.List;
import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.DiscoverAdapter;
import awais.instagrabber.asyncs.DiscoverFetcher;
import awais.instagrabber.asyncs.i.iTopicFetcher;
@ -40,10 +40,7 @@ import awais.instagrabber.fragments.main.viewmodels.DiscoverItemViewModel;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.DiscoverItemModel;
import awais.instagrabber.models.DiscoverTopicModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
public class DiscoverFragment extends Fragment {
@ -183,7 +180,8 @@ public class DiscoverFragment extends Fragment {
binding.discoverSwipeRefreshLayout.setRefreshing(true);
if (lazyLoader != null) lazyLoader.resetState();
discoverItemViewModel.getList().postValue(Collections.emptyList());
new DiscoverFetcher(currentTopic, null, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new DiscoverFetcher(currentTopic, null, rankToken, discoverFetchListener, false)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@ -205,10 +203,25 @@ public class DiscoverFragment extends Fragment {
return;
}
if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.DISCOVER_ITEMS)
.putExtra(Constants.EXTRAS_POST, new PostModel(model.getShortCode(), false)));
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, position)
// .putExtra(Constants.EXTRAS_TYPE, PostItemType.DISCOVER)
// .putExtra(Constants.EXTRAS_POST, new PostModel(model.getShortCode(), false)));
final List<DiscoverItemModel> discoverItemModels = discoverItemViewModel.getList().getValue();
if (discoverItemModels == null || discoverItemModels.size() == 0) return;
if (discoverItemModels.get(0) == null) return;
final String postId = discoverItemModels.get(0).getPostId();
final boolean isId = postId != null;
final String[] idsOrShortCodes = new String[discoverItemModels.size()];
for (int i = 0; i < discoverItemModels.size(); i++) {
idsOrShortCodes[i] = isId ? discoverItemModels.get(i).getPostId()
: discoverItemModels.get(i).getShortCode();
}
final NavDirections action = DiscoverFragmentDirections.actionGlobalPostViewFragment(
position,
idsOrShortCodes,
isId);
NavHostFragment.findNavController(this).navigate(action);
}, (model, position) -> {
if (!discoverAdapter.isSelecting()) {
checkAndResetAction();
@ -229,7 +242,8 @@ public class DiscoverFragment extends Fragment {
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (discoverHasMore) {
binding.discoverSwipeRefreshLayout.setRefreshing(true);
new DiscoverFetcher(currentTopic, discoverEndMaxId, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new DiscoverFetcher(currentTopic, discoverEndMaxId, rankToken, discoverFetchListener, false)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
discoverEndMaxId = null;
}
});

View File

@ -37,7 +37,6 @@ import java.util.Map;
import awais.instagrabber.R;
import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.FeedAdapter;
import awais.instagrabber.adapters.FeedStoriesAdapter;
import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder;
@ -57,7 +56,6 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.services.ServiceCallback;
import awais.instagrabber.services.StoriesService;
@ -70,7 +68,7 @@ public class FeedFragment extends Fragment {
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);
public static final boolean SHOULD_AUTO_PLAY = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
private static final boolean SHOULD_AUTO_PLAY = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS);
private MainActivity fragmentActivity;
private CoordinatorLayout root;
@ -112,12 +110,16 @@ public class FeedFragment extends Fragment {
final FeedModel feedModel = thumbToFeedMap.get(thumbUri.toString());
if (feedModel == null) return;
int requiredWidth = Utils.displayMetrics.widthPixels;
int resultingHeight = Utils.getResultingHeight(requiredWidth, encodedHeight, encodedWidth);
if (feedModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO && resultingHeight >= MAX_VIDEO_HEIGHT) {
int resultingHeight = Utils
.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 = Utils.getResultingWidth(RESIZED_VIDEO_HEIGHT, resultingHeight, requiredWidth);
requiredWidth = Utils.getResultingWidth(RESIZED_VIDEO_HEIGHT,
resultingHeight,
requiredWidth);
}
feedModel.setImageWidth(requiredWidth);
feedModel.setImageHeight(resultingHeight);
@ -133,7 +135,9 @@ public class FeedFragment extends Fragment {
public void updateAdapter() {
if (failed + success != result.length) return;
final List<FeedModel> finalList = currentFeedModelList == null || currentFeedModelList.isEmpty() ? new ArrayList<>() : new ArrayList<>(currentFeedModelList);
final List<FeedModel> finalList = currentFeedModelList == null || currentFeedModelList.isEmpty()
? new ArrayList<>()
: new ArrayList<>(currentFeedModelList);
finalList.addAll(Arrays.asList(result));
feedViewModel.getList().postValue(finalList);
final PostModel feedPostModel = result[result.length - 1];
@ -147,7 +151,8 @@ public class FeedFragment extends Fragment {
};
for (final FeedModel feedModel : result) {
final DataSource<Void> ds = Fresco.getImagePipeline().prefetchToBitmapCache(ImageRequest.fromUri(feedModel.getThumbnailUrl()), null);
final DataSource<Void> ds = Fresco.getImagePipeline()
.prefetchToBitmapCache(ImageRequest.fromUri(feedModel.getThumbnailUrl()), null);
ds.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
}
}
@ -159,7 +164,7 @@ public class FeedFragment extends Fragment {
return;
}
if (isLocation) {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToLocationFragment(text);
final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return;
}
@ -172,8 +177,7 @@ public class FeedFragment extends Fragment {
final FeedModel feedModel = (FeedModel) tag;
if (v instanceof RamboTextView) {
if (feedModel.isMentionClicked())
feedModel.toggleCaption();
if (feedModel.isMentionClicked()) feedModel.toggleCaption();
feedModel.setMentionClicked(false);
if (!FeedItemViewHolder.expandCollapseTextView((RamboTextView) v, feedModel.getPostCaption()))
feedModel.toggleCaption();
@ -190,10 +194,25 @@ public class FeedFragment extends Fragment {
break;
case R.id.viewStoryPost:
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
// .putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
// .putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
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:
@ -202,8 +221,12 @@ public class FeedFragment extends Fragment {
final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
if (feedModel.getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1)
Utils.batchDownload(requireContext(), username, DownloadMethod.DOWNLOAD_FEED, Collections.singletonList(feedModel));
if (feedModel
.getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1)
Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_FEED,
Collections.singletonList(feedModel));
else {
final ArrayList<BasePostModel> postModels = new ArrayList<>();
final DialogInterface.OnClickListener clickListener1 = (dialog, which) -> {
@ -213,8 +236,7 @@ public class FeedFragment extends Fragment {
for (final ViewerPostModel sliderItem : sliderItems) {
if (sliderItem != null) {
if (!breakWhenFoundSelected)
postModels.add(sliderItem);
if (!breakWhenFoundSelected) postModels.add(sliderItem);
else if (sliderItem.isSelected()) {
postModels.add(sliderItem);
break;
@ -223,16 +245,21 @@ public class FeedFragment extends Fragment {
}
// shows 0 items on first item of viewpager cause onPageSelected hasn't been called yet
if (breakWhenFoundSelected && postModels.size() == 0)
if (breakWhenFoundSelected && postModels.size() == 0) {
postModels.add(sliderItems[0]);
if (postModels.size() > 0)
Utils.batchDownload(requireContext(), username, DownloadMethod.DOWNLOAD_FEED, postModels);
}
if (postModels.size() > 0) {
Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_FEED,
postModels);
}
};
new AlertDialog.Builder(requireContext())
.setTitle(R.string.post_viewer_download_dialog_title)
.setPositiveButton(R.string.post_viewer_download_current, clickListener1)
.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();
}
@ -240,8 +267,7 @@ public class FeedFragment extends Fragment {
case R.id.ivProfilePic:
profileModel = feedModel.getProfileModel();
if (profileModel != null)
mentionClickListener.onClick(null, profileModel.getUsername(), false, false);
if (profileModel != null) mentionClickListener.onClick(null, profileModel.getUsername(), false, false);
break;
}
};
@ -251,6 +277,7 @@ public class FeedFragment extends Fragment {
super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity();
storiesService = StoriesService.getInstance();
// feedService = FeedService.getInstance();
}
@Override
@ -273,6 +300,7 @@ public class FeedFragment extends Fragment {
setupFeedStories();
setupFeed();
shouldRefresh = false;
// feedService.getFeed(11, null);
}
@Override
@ -315,17 +343,15 @@ public class FeedFragment extends Fragment {
private void fetchFeed() {
binding.feedSwipeRefreshLayout.setRefreshing(true);
new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new FeedFetcher(feedEndCursor, feedFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
feedEndCursor = null;
}
private void setupFeedStories() {
final FeedStoriesViewModel feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter((model, position) -> {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment(
position,
null,
false);
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment(position, null, false);
NavHostFragment.findNavController(this).navigate(action);
});
binding.feedStoriesRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false));

View File

@ -37,10 +37,10 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import awais.instagrabber.ProfileNavGraphDirections;
import awais.instagrabber.R;
import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HighlightsFetcher;
@ -61,7 +61,6 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse;
import awais.instagrabber.services.FriendshipService;
@ -97,8 +96,10 @@ public class ProfileFragment extends Fragment {
;
private final Runnable usernameSettingRunnable = () -> {
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(username.substring(1));
if (actionBar != null && !Utils.isEmpty(username)) {
final String finalUsername = username.startsWith("@") ? username.substring(1)
: username;
actionBar.setTitle(finalUsername);
}
};
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
@ -112,22 +113,29 @@ public class ProfileFragment extends Fragment {
remove();
}
};
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(R.menu.multi_select_download_menu, new CallbacksHelper() {
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(R.menu.multi_select_download_menu,
new CallbacksHelper() {
@Override
public void onDestroy(final ActionMode mode) {
onBackPressedCallback.handleOnBackPressed();
public void onDestroy(
final ActionMode mode) {
onBackPressedCallback
.handleOnBackPressed();
}
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
public boolean onActionItemClicked(
final ActionMode mode,
final MenuItem item) {
if (item.getItemId() == R.id.action_download) {
if (postsAdapter == null || username == null) {
return false;
}
Utils.batchDownload(requireContext(),
Utils.batchDownload(
requireContext(),
username,
DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels());
postsAdapter
.getSelectedModels());
checkAndResetAction();
return true;
}
@ -142,7 +150,8 @@ public class ProfileFragment extends Fragment {
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
// final int oldSize = mainActivity.allItems.size();
final List<PostModel> postModels = postsViewModel.getList().getValue();
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
final List<PostModel> finalList = postModels == null || postModels
.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
finalList.addAll(Arrays.asList(result));
postsViewModel.getList().postValue(finalList);
PostModel model = null;
@ -163,16 +172,19 @@ public class ProfileFragment extends Fragment {
private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
Log.d(TAG, "action...");
if (isHashtag) {
final NavDirections action = ProfileFragmentDirections.actionGlobalHashTagFragment(text);
final NavDirections action = ProfileFragmentDirections
.actionGlobalHashTagFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return;
}
if (isLocation) {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToLocationFragment(text);
final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
NavHostFragment.findNavController(this).navigate(action);
return;
}
final NavDirections action = ProfileFragmentDirections.actionGlobalProfileFragment("@" + text);
final ProfileNavGraphDirections.ActionGlobalProfileFragment action = ProfileFragmentDirections
.actionGlobalProfileFragment();
action.setUsername("@" + text);
NavHostFragment.findNavController(this).navigate(action);
};
@ -189,7 +201,8 @@ public class ProfileFragment extends Fragment {
final Bundle savedInstanceState) {
if (root != null) {
if (getArguments() != null) {
final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments());
final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs
.fromBundle(getArguments());
if (!fragmentArgs.getUsername().equals(username)) {
shouldRefresh = true;
return root;
@ -243,7 +256,7 @@ public class ProfileFragment extends Fragment {
private void fetchUsername() {
final String uid = Utils.getUserIdFromCookie(cookie);
if (username == null && uid != null) {
if (Utils.isEmpty(username) && uid != null) {
final FetchListener<String> fetchListener = username -> {
if (Utils.isEmpty(username)) return;
this.username = username;
@ -251,21 +264,23 @@ public class ProfileFragment extends Fragment {
fetchProfileDetails();
// adds cookies to database for quick access
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils.isEmpty(cookieModel.getUsername()))
if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils
.isEmpty(cookieModel.getUsername()))
Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
};
boolean found = false;
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
if (cookieModel != null) {
final String username = cookieModel.getUsername();
if (username != null) {
if (!Utils.isEmpty(username)) {
found = true;
fetchListener.onResult("@" + username);
}
}
if (!found) {
// if not in database, fetch info from instagram
new UsernameFetcher(uid, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new UsernameFetcher(uid, fetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
return;
}
@ -283,14 +298,14 @@ public class ProfileFragment extends Fragment {
private void setProfileDetails() {
if (profileModel == null) {
binding.swipeRefreshLayout.setRefreshing(false);
Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT)
.show();
return;
}
binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
final String profileId = profileModel.getId();
if (settingsHelper.getBoolean(Constants.STORIESIG)) {
new iStoryStatusFetcher(
profileId,
new iStoryStatusFetcher(profileId,
profileModel.getUsername(),
false,
false,
@ -303,12 +318,13 @@ public class ProfileFragment extends Fragment {
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> {
new HighlightsFetcher(profileId,
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
result -> {
if (result != null && result.length > 0) {
binding.highlightsList.setVisibility(View.VISIBLE);
// highlightsAdapter.setData(result);
} else
binding.highlightsList.setVisibility(View.GONE);
} else binding.highlightsList.setVisibility(View.GONE);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -319,9 +335,10 @@ public class ProfileFragment extends Fragment {
binding.btnSaved.setVisibility(View.VISIBLE);
binding.btnLiked.setVisibility(View.VISIBLE);
binding.btnSaved.setText(R.string.saved);
ViewCompat.setBackgroundTintList(
binding.btnSaved,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background)));
ViewCompat.setBackgroundTintList(binding.btnSaved,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_orange_background)));
} else {
binding.btnTagged.setVisibility(View.GONE);
binding.btnSaved.setVisibility(View.GONE);
@ -329,65 +346,75 @@ public class ProfileFragment extends Fragment {
binding.btnFollow.setVisibility(View.VISIBLE);
if (profileModel.getFollowing()) {
binding.btnFollow.setText(R.string.unfollow);
ViewCompat.setBackgroundTintList(
binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
ViewCompat.setBackgroundTintList(binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_purple_background)));
} else if (profileModel.getRequested()) {
binding.btnFollow.setText(R.string.cancel);
ViewCompat.setBackgroundTintList(
binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
ViewCompat.setBackgroundTintList(binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_purple_background)));
} else {
binding.btnFollow.setText(R.string.follow);
ViewCompat.setBackgroundTintList(
binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background)));
ViewCompat.setBackgroundTintList(binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_pink_background)));
}
binding.btnRestrict.setVisibility(View.VISIBLE);
if (profileModel.getRestricted()) {
binding.btnRestrict.setText(R.string.unrestrict);
ViewCompat.setBackgroundTintList(
binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background)));
ViewCompat.setBackgroundTintList(binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_green_background)));
} else {
binding.btnRestrict.setText(R.string.restrict);
ViewCompat.setBackgroundTintList(
binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background)));
ViewCompat.setBackgroundTintList(binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_orange_background)));
}
binding.btnBlock.setVisibility(View.VISIBLE);
binding.btnTagged.setVisibility(View.VISIBLE);
if (profileModel.getBlocked()) {
binding.btnBlock.setText(R.string.unblock);
ViewCompat.setBackgroundTintList(
binding.btnBlock,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background)));
ViewCompat.setBackgroundTintList(binding.btnBlock,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_green_background)));
} else {
binding.btnBlock.setText(R.string.block);
ViewCompat.setBackgroundTintList(
binding.btnBlock,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_red_background)));
ViewCompat.setBackgroundTintList(binding.btnBlock,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_red_background)));
}
}
} else {
if (Utils.dataBox.getFavorite(username) != null) {
binding.btnFollow.setText(R.string.unfavorite_short);
ViewCompat.setBackgroundTintList(
binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
ViewCompat.setBackgroundTintList(binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_purple_background)));
} else {
binding.btnFollow.setText(R.string.favorite_short);
ViewCompat.setBackgroundTintList(
binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background)));
ViewCompat.setBackgroundTintList(binding.btnFollow,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_pink_background)));
}
binding.btnFollow.setVisibility(View.VISIBLE);
if (!profileModel.isReallyPrivate()) {
binding.btnRestrict.setVisibility(View.VISIBLE);
binding.btnRestrict.setText(R.string.tagged);
ViewCompat.setBackgroundTintList(
binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_blue_background)));
ViewCompat.setBackgroundTintList(binding.btnRestrict,
ColorStateList.valueOf(ContextCompat.getColor(
requireContext(),
R.color.btn_blue_background)));
}
}
@ -398,26 +425,30 @@ public class ProfileFragment extends Fragment {
final String postCount = String.valueOf(profileModel.getPostCount());
SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count, postCount));
SpannableStringBuilder span = new SpannableStringBuilder(getString(R.string.main_posts_count,
postCount));
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
binding.mainPostCount.setText(span);
final String followersCountStr = String.valueOf(followersCount);
final int followersCountStrLen = followersCountStr.length();
span = new SpannableStringBuilder(getString(R.string.main_posts_followers, followersCountStr));
span = new SpannableStringBuilder(getString(R.string.main_posts_followers,
followersCountStr));
span.setSpan(new RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
binding.mainFollowers.setText(span);
final String followingCountStr = String.valueOf(followingCount);
final int followingCountStrLen = followingCountStr.length();
span = new SpannableStringBuilder(getString(R.string.main_posts_following, followingCountStr));
span = new SpannableStringBuilder(getString(R.string.main_posts_following,
followingCountStr));
span.setSpan(new RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
binding.mainFollowing.setText(span);
binding.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() : profileModel.getName());
binding.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel
.getUsername() : profileModel.getName());
CharSequence biography = profileModel.getBiography();
binding.mainBiography.setCaptionIsExpandable(true);
@ -447,13 +478,18 @@ public class ProfileFragment extends Fragment {
binding.mainFollowers.setClickable(true);
if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent(requireContext(), FollowViewer.class)
.putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
final View.OnClickListener followClickListener = v -> startActivity(new Intent(
requireContext(),
FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS,
v == binding.mainFollowers)
.putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
binding.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
binding.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
binding.mainFollowers
.setOnClickListener(followersCount > 0 ? followClickListener : null);
binding.mainFollowing
.setOnClickListener(followingCount > 0 ? followClickListener : null);
}
if (profileModel.getPostCount() == 0) {
@ -481,32 +517,29 @@ public class ProfileFragment extends Fragment {
private void setupCommonListeners() {
final String userIdFromCookie = Utils.getUserIdFromCookie(cookie);
final boolean isSelf = isLoggedIn
&& profileModel != null
&& userIdFromCookie != null
&& userIdFromCookie.equals(profileModel.getId());
final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null && userIdFromCookie
.equals(profileModel.getId());
final String favorite = Utils.dataBox.getFavorite(username);
binding.btnFollow.setOnClickListener(v -> {
if (!isLoggedIn) {
if (favorite != null && v == binding.btnFollow) {
Utils.dataBox.delFavorite(
new DataBox.FavoriteModel(username,
Long.parseLong(favorite.split("/")[1]),
username.replaceAll("^@", "")
)
);
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(username,
Long.parseLong(favorite.split(
"/")[1]),
username.replaceAll("^@",
"")));
} else if (v == binding.btnFollow) {
Utils.dataBox.addFavorite(
new DataBox.FavoriteModel(username, System.currentTimeMillis(),
username.replaceAll("^@", "")));
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(username,
System.currentTimeMillis(),
username.replaceAll("^@",
"")));
}
fetchProfileDetails();
return;
}
if (profileModel.getFollowing() || profileModel.getRequested()) {
friendshipService.unfollow(
userIdFromCookie,
friendshipService.unfollow(userIdFromCookie,
profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -522,8 +555,7 @@ public class ProfileFragment extends Fragment {
}
});
} else {
friendshipService.follow(
userIdFromCookie,
friendshipService.follow(userIdFromCookie,
profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -544,8 +576,7 @@ public class ProfileFragment extends Fragment {
binding.btnRestrict.setOnClickListener(v -> {
if (!isLoggedIn) return;
final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict";
friendshipService.toggleRestrict(
profileModel.getId(),
friendshipService.toggleRestrict(profileModel.getId(),
!profileModel.getRestricted(),
Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoRestrictRootResponse>() {
@ -557,15 +588,16 @@ public class ProfileFragment extends Fragment {
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "Error while performing " + action, t);
Log.e(TAG,
"Error while performing " + action,
t);
}
});
});
binding.btnBlock.setOnClickListener(v -> {
if (!isLoggedIn) return;
if (profileModel.getBlocked()) {
friendshipService.unblock(
userIdFromCookie,
friendshipService.unblock(userIdFromCookie,
profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -582,8 +614,7 @@ public class ProfileFragment extends Fragment {
});
return;
}
friendshipService.block(
userIdFromCookie,
friendshipService.block(userIdFromCookie,
profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -599,19 +630,31 @@ public class ProfileFragment extends Fragment {
}
});
});
binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
));
binding.btnLiked.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
));
binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(),
SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX,
"$" + profileModel
.getId())
.putExtra(Constants.EXTRAS_USER,
"@" + profileModel
.getUsername())));
binding.btnLiked.setOnClickListener(v -> startActivity(new Intent(requireContext(),
SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX,
"^" + profileModel
.getId())
.putExtra(Constants.EXTRAS_USER,
"@" + profileModel
.getUsername())));
binding.btnTagged.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
));
binding.btnTagged.setOnClickListener(v -> startActivity(new Intent(requireContext(),
SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX,
"%" + profileModel
.getId())
.putExtra(Constants.EXTRAS_USER,
"@" + profileModel
.getUsername())));
}
private void setUsernameDelayed() {
@ -623,29 +666,48 @@ public class ProfileFragment extends Fragment {
private void setupPosts() {
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(),
Utils.convertDpToPx(
110));
binding.mainPosts.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
postsAdapter = new PostsAdapter((postModel, position) -> {
if (postsAdapter.isSelecting()) {
if (actionMode == null) return;
final String title = getString(R.string.number_selected, postsAdapter.getSelectedModels().size());
final String title = getString(R.string.number_selected,
postsAdapter.getSelectedModels().size());
actionMode.setTitle(title);
return;
}
if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, username)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS));
// startActivity(new Intent(requireContext(), PostViewer.class)
// .putExtra(Constants.EXTRAS_INDEX, position)
// .putExtra(Constants.EXTRAS_POST, postModel)
// .putExtra(Constants.EXTRAS_USER, username)
// .putExtra(Constants.EXTRAS_TYPE, PostItemType.MAIN));
final List<PostModel> postModels = postsViewModel.getList().getValue();
if (postModels == null || postModels.size() == 0) return;
if (postModels.get(0) == null) return;
final String postId = postModels.get(0).getPostId();
final boolean isId = postId != null;
final String[] idsOrShortCodes = new String[postModels.size()];
for (int i = 0; i < postModels.size(); i++) {
idsOrShortCodes[i] = isId ? postModels.get(i).getPostId()
: postModels.get(i).getShortCode();
}
final NavDirections action = ProfileFragmentDirections.actionGlobalPostViewFragment(
position,
idsOrShortCodes,
isId);
NavHostFragment.findNavController(this).navigate(action);
}, (model, position) -> {
if (!postsAdapter.isSelecting()) {
checkAndResetAction();
return true;
}
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
return true;
}
@ -657,9 +719,11 @@ public class ProfileFragment extends Fragment {
});
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager,
(page, totalItemsCount) -> {
if (!hasNextPage) return;
binding.swipeRefreshLayout.setRefreshing(true);
binding.swipeRefreshLayout
.setRefreshing(true);
fetchPosts();
endCursor = null;
});
@ -668,7 +732,7 @@ public class ProfileFragment extends Fragment {
private void fetchPosts() {
stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(profileModel.getId(), endCursor, postsFetchListener)
currentlyExecuting = new PostsFetcher(profileModel.getId(), false, endCursor, postsFetchListener)
.setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -678,15 +742,17 @@ public class ProfileFragment extends Fragment {
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
if (logCollector != null) logCollector.appendException(e,
LogCollector.LogFile.MAIN_HELPER,
"stopCurrentExecutor");
Log.e(TAG, "", e);
}
}
}
private boolean checkAndResetAction() {
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
return false;
}

View File

@ -0,0 +1,19 @@
package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import awais.instagrabber.models.DiscoverItemModel;
public class DiscoverItemViewModel extends ViewModel {
private MutableLiveData<List<DiscoverItemModel>> list;
public MutableLiveData<List<DiscoverItemModel>> getList() {
if (list == null) {
list = new MutableLiveData<>();
}
return list;
}
}

View File

@ -1,13 +1,12 @@
package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import awais.instagrabber.models.DiscoverItemModel;
public class DiscoverItemViewModel extends ViewModel {
public class DiscoverItemViewModel extends BasePostViewModel<DiscoverItemModel> {
private MutableLiveData<List<DiscoverItemModel>> list;
public MutableLiveData<List<DiscoverItemModel>> getList() {

View File

@ -1,14 +1,13 @@
package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.Collections;
import java.util.List;
import awais.instagrabber.models.FeedModel;
public class FeedViewModel extends ViewModel {
public class FeedViewModel extends BasePostViewModel<FeedModel> {
private MutableLiveData<List<FeedModel>> list;
public MutableLiveData<List<FeedModel>> getList() {

View File

@ -1,13 +1,12 @@
package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import awais.instagrabber.models.PostModel;
public class PostsViewModel extends ViewModel {
public class PostsViewModel extends BasePostViewModel<PostModel> {
private MutableLiveData<List<PostModel>> list;
public MutableLiveData<List<PostModel>> getList() {

View File

@ -0,0 +1,18 @@
package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData;
import java.util.List;
import awais.instagrabber.models.ViewerPostModel;
public class ViewPostViewModel extends BasePostViewModel<ViewerPostModel> {
private MutableLiveData<List<ViewerPostModel>> list;
public MutableLiveData<List<ViewerPostModel>> getList() {
if (list == null) {
list = new MutableLiveData<>();
}
return list;
}
}

View File

@ -4,8 +4,8 @@ import java.io.Serializable;
import java.util.List;
import awais.instagrabber.models.BasePostModel;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.PostItemType;
public interface ItemGetter extends Serializable {
List<? extends BasePostModel> get(final ItemGetType itemGetType);
List<? extends BasePostModel> get(final PostItemType postItemType);
}

View File

@ -96,11 +96,11 @@ public abstract class BasePostModel implements Serializable, Selectable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final BasePostModel that = (BasePostModel) o;
return ObjectsCompat.equals(postId, that.postId);
return ObjectsCompat.equals(postId, that.postId) && ObjectsCompat.equals(shortCode, that.shortCode);
}
@Override
public int hashCode() {
return ObjectsCompat.hash(postId);
return ObjectsCompat.hash(postId, shortCode);
}
}

View File

@ -1,26 +1,40 @@
package awais.instagrabber.models;
import org.json.JSONObject;
import awais.instagrabber.models.enums.MediaItemType;
public final class FeedModel extends PostModel {
private final ProfileModel profileModel;
private final long commentsCount, viewCount;
private boolean captionExpanded = false, mentionClicked = false;
private final JSONObject location;
private final long commentsCount;
private final long viewCount;
private boolean captionExpanded = false;
private boolean mentionClicked = false;
private ViewerPostModel[] sliderItems;
private int imageWidth;
private int imageHeight;
private String locationName;
private String locationId;
public FeedModel(final ProfileModel profileModel, final MediaItemType itemType, final long viewCount, final String postId,
final String displayUrl, final String thumbnailUrl, final String shortCode, final String postCaption,
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked, long likes, JSONObject location) {
public FeedModel(final ProfileModel profileModel,
final MediaItemType itemType,
final long viewCount,
final String postId,
final String displayUrl,
final String thumbnailUrl,
final String shortCode,
final String postCaption,
final long commentsCount,
final long timestamp,
final boolean liked,
final boolean bookmarked,
final long likes,
final String locationName,
final String locationId) {
super(itemType, postId, displayUrl, thumbnailUrl, shortCode, postCaption, timestamp, liked, bookmarked, likes);
this.profileModel = profileModel;
this.commentsCount = commentsCount;
this.viewCount = viewCount;
this.location = location;
this.locationName = locationName;
this.locationId = locationId;
}
public ProfileModel getProfileModel() {
@ -39,10 +53,6 @@ public final class FeedModel extends PostModel {
return commentsCount;
}
public JSONObject getLocation() {
return location;
}
public boolean isCaptionExpanded() {
return captionExpanded;
}
@ -79,4 +89,20 @@ public final class FeedModel extends PostModel {
public int getImageHeight() {
return imageHeight;
}
public String getLocationName() {
return locationName;
}
public void setLocationName(final String locationName) {
this.locationName = locationName;
}
public String getLocationId() {
return locationId;
}
public void setLocationId(final String locationId) {
this.locationId = locationId;
}
}

View File

@ -4,11 +4,26 @@ import java.io.Serializable;
public final class LocationModel implements Serializable {
private final long postCount;
private final String id, name, bio, url, sdProfilePic, lat, lng;
private final String id;
private final String slug;
private final String name;
private final String bio;
private final String url;
private final String sdProfilePic;
private final String lat;
private final String lng;
public LocationModel(final String id, final String name, final String bio, final String url,
final String sdProfilePic, final long postCount, final String lat, final String lng) {
this.id = id; // <- id + "/" + slug
public LocationModel(final String id,
final String slug,
final String name,
final String bio,
final String url,
final String sdProfilePic,
final long postCount,
final String lat,
final String lng) {
this.id = id;
this.slug = slug;
this.name = name;
this.bio = bio;
this.url = url;
@ -22,6 +37,10 @@ public final class LocationModel implements Serializable {
return id;
}
public String getSlug() {
return slug;
}
public String getName() {
return name;
}
@ -34,7 +53,7 @@ public final class LocationModel implements Serializable {
return url;
}
public String getGeo() { return "geo:"+lat+","+lng+"?z=17&q="+lat+","+lng+"("+name+")"; }
public String getGeo() { return "geo:" + lat + "," + lng + "?z=17&q=" + lat + "," + lng + "(" + name + ")"; }
public String getSdProfilePic() {
return sdProfilePic;

View File

@ -39,6 +39,10 @@ public final class ProfileModel implements Serializable {
return new ProfileModel(false, false, false, userId, null, null, null, null, null, null, 0, 0, 0, false, false, false, false);
}
public static ProfileModel getDefaultProfileModel(final String userId, final String username) {
return new ProfileModel(false, false, false, userId, username, null, null, null, null, null, 0, 0, 0, false, false, false, false);
}
public boolean isPrivate() {
return isPrivate;
}

View File

@ -1,24 +1,34 @@
package awais.instagrabber.models;
import org.json.JSONObject;
import awais.instagrabber.models.enums.MediaItemType;
public final class ViewerPostModel extends BasePostModel {
protected final String username, locationName, location;
protected final ProfileModel profileModel;
protected final String locationName;
protected final String location;
protected final long videoViews;
protected String sliderDisplayUrl;
protected long commentsCount, likes;
private boolean isCurrentSlide = false;
public ViewerPostModel(final MediaItemType itemType, final String postId, final String displayUrl, final String shortCode,
final String postCaption, final String username, final long videoViews, final long timestamp,
boolean liked, boolean bookmarked, long likes, final String locationName, final String location) {
public ViewerPostModel(final MediaItemType itemType,
final String postId,
final String displayUrl,
final String shortCode,
final String postCaption,
final ProfileModel profileModel,
final long videoViews,
final long timestamp,
boolean liked,
boolean bookmarked,
long likes,
final String locationName,
final String location) {
this.itemType = itemType;
this.postId = postId;
this.displayUrl = displayUrl;
this.postCaption = postCaption;
this.username = username;
this.profileModel = profileModel;
this.shortCode = shortCode;
this.videoViews = videoViews;
this.timestamp = timestamp;
@ -29,6 +39,10 @@ public final class ViewerPostModel extends BasePostModel {
this.location = location;
}
public static ViewerPostModel getDefaultModel(final int postId, final String shortCode) {
return new ViewerPostModel(null, String.valueOf(postId), null, "", null, null, -1, -1, false, false, -1, null, null);
}
public long getCommentsCount() {
return commentsCount;
}
@ -37,8 +51,8 @@ public final class ViewerPostModel extends BasePostModel {
return sliderDisplayUrl;
}
public String getUsername() {
return username;
public ProfileModel getProfileModel() {
return profileModel;
}
public String getLocationName() {

View File

@ -0,0 +1,23 @@
package awais.instagrabber.models;
public class ViewerPostModelWrapper {
private int position;
private ViewerPostModel[] viewerPostModels;
public ViewerPostModelWrapper(final int position, final ViewerPostModel[] viewerPostModels) {
this.position = position;
this.viewerPostModels = viewerPostModels;
}
public int getPosition() {
return position;
}
public ViewerPostModel[] getViewerPostModels() {
return viewerPostModels;
}
public void setViewerPostModels(final ViewerPostModel[] viewerPostModels) {
this.viewerPostModels = viewerPostModels;
}
}

View File

@ -7,8 +7,10 @@ import androidx.annotation.NonNull;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
class LoggingInterceptor implements Interceptor {
private static final String TAG = "LoggingInterceptor";
@ -22,8 +24,12 @@ class LoggingInterceptor implements Interceptor {
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s\nbody: %s",
response.request().url(), (t2 - t1) / 1e6d, response.headers(), response.body()));
return response;
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
MediaType contentType = response.body().contentType();
String content = response.body().string();
Log.d("OkHttp", content);
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
return response.newBuilder().body(wrappedBody).build();
}
}

View File

@ -55,8 +55,10 @@ public final class LocaleUtils {
if (Utils.settingsHelper == null)
Utils.settingsHelper = new SettingsHelper(baseContext);
final int appLanguageIndex = Integer.parseInt(Utils.settingsHelper.getString(Constants.APP_LANGUAGE));
final String appLanguageSettings = Utils.settingsHelper.getString(Constants.APP_LANGUAGE);
if (Utils.isEmpty(appLanguageSettings)) return null;
final int appLanguageIndex = Integer.parseInt(appLanguageSettings);
if (appLanguageIndex == 1) return "en";
if (appLanguageIndex == 2) return "fr";
if (appLanguageIndex == 3) return "es";

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@ -42,7 +42,8 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="gone">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
@ -77,7 +78,7 @@
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:padding="4dp"
android:visibility="visible"
android:visibility="gone"
app:srcCompat="@drawable/ic_volume_up_24"
app:tint="?android:textColorPrimary" />

View File

@ -25,6 +25,7 @@
android:orientation="vertical"
android:paddingStart="8dp"
android:paddingLeft="8dp"
android:gravity="center"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:weightSum="2">
@ -46,7 +47,8 @@
android:gravity="center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/feed_text_primary_color"
android:textSize="15sp" />
android:textSize="15sp"
android:visibility="visible"
tools:text="location" />
</RelativeLayout>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:weightSum="3.2"
tools:context=".activities.PostViewer">
<include
android:id="@+id/topPanel"
layout="@layout/item_feed_top" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.9">
<awais.instagrabber.customviews.helpers.NestedScrollableHost
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/mediaViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</awais.instagrabber.customviews.helpers.NestedScrollableHost>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mediaCounter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:background="@drawable/rounder_corner_semi_black_bg"
android:gravity="center"
android:padding="5dp"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
android:textColor="@android:color/white"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progressView"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ivToggleFullScreen"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end|top"
android:background="?selectableItemBackgroundBorderless"
android:padding="4dp"
app:srcCompat="@drawable/ic_fullscreen"
app:tint="?android:textColorPrimary" />
</FrameLayout>
<include
android:id="@+id/bottomPanel"
layout="@layout/item_feed_bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/postActions"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"
android:background="#0000"
android:weightSum="2">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnLike"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:textColor="@color/btn_lightpink_text_color"
android:textSize="18sp"
app:backgroundTint="@color/btn_lightpink_background"
tools:text="@string/like" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnBookmark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="8dp"
android:layout_marginEnd="6dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:text="@string/bookmark"
android:textColor="@color/btn_lightorange_text_color"
android:textSize="18sp"
app:backgroundTint="@color/btn_lightorange_background" />
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>

View File

@ -4,25 +4,15 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="3.2"
android:animateLayoutChanges="true"
android:orientation="vertical"
tools:context=".activities.PostViewer">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingRight="4dp"
android:paddingBottom="6dp">
android:weightSum="3.2"
tools:context=".activities.PostViewer"
android:layout_marginTop="?attr/actionBarSize">
<include
android:id="@+id/topPanel"
layout="@layout/item_feed_top" />
</FrameLayout>
<FrameLayout
android:id="@+id/container"
@ -38,7 +28,7 @@
app:auto_show="true"
app:repeat_toggle_modes="all" />
<com.github.chrisbanes.photoview.PhotoView
<awais.instagrabber.customviews.drawee.ZoomableDraweeView
android:id="@+id/imageViewer"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -63,7 +53,8 @@
android:layout_gravity="end|top"
android:background="?selectableItemBackgroundBorderless"
android:padding="4dp"
app:srcCompat="@drawable/ic_fullscreen" />
app:srcCompat="@drawable/ic_fullscreen"
app:tint="?android:textColorPrimary" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/btnDownload"
@ -89,14 +80,15 @@
android:paddingLeft="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_child_post" />
<include
android:id="@+id/bottomPanel"
layout="@layout/item_feed_bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
android:layout_weight="1" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/postActions"
@ -104,26 +96,26 @@
android:layout_height="0dp"
android:layout_weight="0.3"
android:background="#0000"
android:weightSum="2"
android:layout_alignParentBottom="true">
android:weightSum="2">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnLike"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="6dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:text="@string/like"
android:textColor="@color/btn_lightpink_text_color"
android:textSize="18sp"
app:backgroundTint="@color/btn_lightpink_background" />
app:backgroundTint="@color/btn_lightpink_background"
tools:text="@string/like" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnBookmark"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="8dp"
android:layout_marginEnd="6dp"
android:layout_marginRight="8dp"

View File

@ -1,11 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/discover_nav_graph"
app:startDestination="@id/discoverFragment">
<include app:graph="@navigation/post_view_nav_graph" />
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/post_view_nav_graph">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
<fragment
android:id="@+id/discoverFragment"
android:name="awais.instagrabber.fragments.main.DiscoverFragment"
android:label="DiscoverFragment" />
android:label="DiscoverFragment"
tools:layout="@layout/fragment_discover" />
</navigation>

View File

@ -24,9 +24,36 @@
<argument
android:name="username"
app:argType="string"
app:nullable="true" />
</action>
<include app:graph="@navigation/location_nav_graph" />
<action
android:id="@+id/action_global_locationFragment"
app:destination="@id/location_nav_graph">
<argument
android:name="locationId"
app:argType="string"
app:nullable="false" />
</action>
<include app:graph="@navigation/post_view_nav_graph" />
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/post_view_nav_graph">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
<fragment
android:id="@+id/feedFragment"
android:name="awais.instagrabber.fragments.main.FeedFragment"
@ -35,9 +62,6 @@
<action
android:id="@+id/action_feedFragment_to_storyViewerFragment"
app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_feedFragment_to_locationFragment"
app:destination="@id/locationFragment" />
</fragment>
<fragment
android:id="@+id/storyViewerFragment"
@ -56,14 +80,4 @@
android:name="isHashtag"
app:argType="boolean" />
</fragment>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="location"
app:argType="string"
app:nullable="false" />
</fragment>
</navigation>

View File

@ -4,6 +4,21 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/hashtag_nav_graph"
app:startDestination="@id/hashTagFragment">
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/post_view_nav_graph">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
<fragment
android:id="@+id/hashTagFragment"
android:name="awais.instagrabber.fragments.HashTagFragment"

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/location_nav_graph"
app:startDestination="@id/locationFragment">
<!--<include app:graph="@navigation/post_view_nav_graph" />-->
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/post_view_nav_graph">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
<fragment
android:id="@+id/locationFragment"
android:name="awais.instagrabber.fragments.LocationFragment"
android:label=""
tools:layout="@layout/fragment_location">
<argument
android:name="locationId"
app:argType="string"
app:nullable="false" />
</fragment>
<action
android:id="@+id/action_global_locationFragment"
app:destination="@id/locationFragment">
<argument
android:name="locationId"
app:argType="string"
app:nullable="false" />
</action>
</navigation>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/post_view_nav_graph"
app:startDestination="@id/postViewFragment">
<include app:graph="@navigation/hashtag_nav_graph" />
<action
android:id="@+id/action_global_hashTagFragment"
app:destination="@id/hashtag_nav_graph">
<argument
android:name="hashtag"
app:argType="string"
app:nullable="false" />
</action>
<!--<include app:graph="@navigation/profile_nav_graph" />-->
<action
android:id="@+id/action_global_profileFragment"
app:destination="@id/profile_nav_graph">
<argument
android:name="username"
app:argType="string"
app:nullable="true" />
</action>
<include app:graph="@navigation/location_nav_graph" />
<action
android:id="@+id/action_global_locationFragment"
app:destination="@id/location_nav_graph">
<argument
android:name="locationId"
app:argType="string"
app:nullable="false" />
</action>
<fragment
android:id="@+id/postViewFragment"
android:name="awais.instagrabber.fragments.PostViewFragment"
tools:layout="@layout/item_full_post_view">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</fragment>
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/postViewFragment">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
</navigation>

View File

@ -16,11 +16,28 @@
app:nullable="false" />
</action>
<include app:graph="@navigation/post_view_nav_graph" />
<action
android:id="@+id/action_global_postViewFragment"
app:destination="@id/post_view_nav_graph">
<argument
android:name="index"
app:argType="integer" />
<argument
android:name="idOrCodeArray"
app:argType="string[]" />
<argument
android:name="isId"
app:argType="boolean" />
</action>
<action
android:id="@+id/action_global_profileFragment"
app:destination="@id/profileFragment">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="false" />
</action>
@ -29,13 +46,11 @@
android:id="@+id/profileFragment"
android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile" >
tools:layout="@layout/fragment_profile">
<argument
android:name="username"
android:defaultValue=""
app:argType="string"
app:nullable="false" />
<!--<action-->
<!-- android:id="@+id/action_profileFragment_self"-->
<!-- app:destination="@id/profileFragment" />-->
app:nullable="true" />
</fragment>
</navigation>