1
0
mirror of https://github.com/KokaKiwi/BarInsta synced 2024-09-27 21:27:30 +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.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.IntentModelType; import awais.instagrabber.models.enums.IntentModelType;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox; import awais.instagrabber.utils.DataBox;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
@ -149,7 +149,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (autoloadPosts && hasNextPage) if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher( currentlyExecuting = new PostsFetcher(
mainActivity.profileModel != null ? mainActivity.profileModel.getId() 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()) .setUsername((isLocation || isHashtag) ? null : mainActivity.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
@ -168,7 +173,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() { private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() {
@Override @Override
public void doBefore() { 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 @Override
@ -232,7 +238,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
feedAdapter.submitList(mainActivity.feedItems); feedAdapter.submitList(mainActivity.feedItems);
feedAdapter.notifyItemRangeInserted(oldSize, result.length); 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]; final PostModel feedPostModel = result[result.length - 1];
if (feedPostModel != null) { if (feedPostModel != null) {
@ -308,8 +315,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
private final MentionClickListener mentionClickListener = new MentionClickListener() { private final MentionClickListener mentionClickListener = new MentionClickListener() {
@Override @Override
public void onClick(final RamboTextView view, final String text, final boolean isHashtag, final boolean isLocation) { 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)
.setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> { .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); if (MainActivityBackup.scanHack != null) MainActivityBackup.scanHack.onResult(text);
}).show(); }).show();
} }
@ -433,7 +441,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} else { } else {
// this changes toolbar title // this changes toolbar title
mainActivity.mainBinding.toolbar.toolbar.setTitle(slideOffset >= 0.466 ? titleDiscover : 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); imageTintList = ImageViewCompat.getImageTintList(iconFeed);
alpha = imageTintList != null ? (imageTintList.getDefaultColor() & 0xFF_000000) >> 24 : 0; 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); collapsingToolbar = mainActivity.mainBinding.profileView.appBarLayout.getChildAt(0);
mainActivity.mainBinding.profileView.mainPosts.setNestedScrollingEnabled(false); 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); mainActivity.mainBinding.profileView.highlightsList.setAdapter(mainActivity.highlightsAdapter);
// int color = -1; // int color = -1;
@ -554,7 +565,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true); mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(mainActivity.profileModel != null ? mainActivity.profileModel.getId() 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()) .setUsername((isHashtag || isLocation) ? null : mainActivity.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null; endCursor = null;
@ -585,16 +601,16 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
switch (id) { switch (id) {
case R.id.btnComments: case R.id.btnComments:
mainActivity.startActivityForResult(new Intent(mainActivity, CommentsViewer.class) mainActivity.startActivityForResult(new Intent(mainActivity, CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode()) .putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId()) .putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969); .putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()), 6969);
break; break;
case R.id.viewStoryPost: case R.id.viewStoryPost:
mainActivity.startActivity(new Intent(mainActivity, PostViewer.class) mainActivity.startActivity(new Intent(mainActivity, PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition()) .putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false)) .putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS)); .putExtra(Constants.EXTRAS_TYPE, PostItemType.FEED));
break; break;
case R.id.btnDownload: case R.id.btnDownload:
@ -656,8 +672,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
mainActivity.mainBinding.feedView.feedPosts.setHasFixedSize(true); mainActivity.mainBinding.feedView.feedPosts.setHasFixedSize(true);
mainActivity.mainBinding.feedView.feedPosts.setLayoutManager(layoutManager); mainActivity.mainBinding.feedView.feedPosts.setLayoutManager(layoutManager);
mainActivity.mainBinding.feedView.feedPosts.setAdapter(feedAdapter = new FeedAdapter(clickListener, (view, text, isHashtag, isLocation) -> 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)
.setTitle(text).setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, (dialog, which) -> { .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) { if (MainActivityBackup.scanHack != null) {
mainActivity.mainBinding.drawerLayout.closeDrawers(); mainActivity.mainBinding.drawerLayout.closeDrawers();
MainActivityBackup.scanHack.onResult(text); MainActivityBackup.scanHack.onResult(text);
@ -673,13 +690,14 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
new FeedFetcher(feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new FeedFetcher(feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}); });
mainActivity.mainBinding.feedView.feedPosts.addOnScrollListener(feedLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { mainActivity.mainBinding.feedView.feedPosts
if (feedHasNextPage) { .addOnScrollListener(feedLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true); if (feedHasNextPage) {
new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); mainActivity.mainBinding.feedView.feedSwipeRefreshLayout.setRefreshing(true);
feedEndCursor = null; new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} feedEndCursor = null;
})); }
}));
if (SHOULD_AUTO_PLAY) { if (SHOULD_AUTO_PLAY) {
videoAwareRecyclerScroller = new VideoAwareRecyclerScroller(); videoAwareRecyclerScroller = new VideoAwareRecyclerScroller();
@ -753,13 +771,15 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
// return true; // return true;
// })); // }));
mainActivity.mainBinding.discoverPosts.addOnScrollListener(discoverLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { mainActivity.mainBinding.discoverPosts
if (discoverHasMore) { .addOnScrollListener(discoverLazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
mainActivity.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true); if (discoverHasMore) {
new DiscoverFetcher(topic, discoverEndMaxId, rankToken, discoverFetchListener, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); mainActivity.mainBinding.discoverSwipeRefreshLayout.setRefreshing(true);
discoverEndMaxId = null; new DiscoverFetcher(topic, discoverEndMaxId, rankToken, discoverFetchListener, false)
} .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
})); discoverEndMaxId = null;
}
}));
} }
public void onIntent(final Intent intent) { public void onIntent(final Intent intent) {
@ -795,12 +815,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (modelType == IntentModelType.POST) { if (modelType == IntentModelType.POST) {
mainActivity.startActivityForResult(new Intent(mainActivity, PostViewer.class) mainActivity.startActivityForResult(new Intent(mainActivity, PostViewer.class)
.putExtra(Constants.EXTRAS_USER, mainActivity.userQuery) .putExtra(Constants.EXTRAS_USER, mainActivity.userQuery)
.putExtra(Constants.EXTRAS_POST, new PostModel(modelText, false)), 9629); .putExtra(Constants.EXTRAS_POST, new PostModel(modelText, false)), 9629);
} else { } else {
mainActivity.addToStack(); mainActivity.addToStack();
mainActivity.userQuery = modelType == IntentModelType.HASHTAG ? ('#' + modelText) : mainActivity.userQuery = modelType == IntentModelType.HASHTAG ? ('#' + modelText) :
(modelType == IntentModelType.LOCATION ? modelText : ('@' + modelText)); (modelType == IntentModelType.LOCATION ? modelText : ('@' + modelText));
onRefresh(); onRefresh();
} }
} }
@ -968,12 +988,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (isLoggedIn || settingsHelper.getBoolean(Constants.STORIESIG)) { if (isLoggedIn || settingsHelper.getBoolean(Constants.STORIESIG)) {
new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false, new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false,
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false,
result -> { result -> {
mainActivity.storyModels = result; mainActivity.storyModels = result;
if (result != null && result.length > 0) if (result != null && result.length > 0)
mainActivity.mainBinding.profileView.mainProfileImage.setStoriesBorder(); mainActivity.mainBinding.profileView.mainProfileImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).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) { if (result != null && result.length > 0) {
@ -1096,7 +1116,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
mainActivity.mainBinding.profileView.mainFollowing.setText(span); 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(); CharSequence biography = profileModel.getBiography();
mainActivity.mainBinding.profileView.mainBiography.setCaptionIsExpandable(true); mainActivity.mainBinding.profileView.mainBiography.setCaptionIsExpandable(true);
@ -1127,9 +1148,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (isLoggedIn) { if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> mainActivity.startActivity(new Intent(mainActivity, FollowViewer.class) final View.OnClickListener followClickListener = v -> mainActivity.startActivity(new Intent(mainActivity, FollowViewer.class)
.putExtra(Constants.EXTRAS_FOLLOWERS, v == mainActivity.mainBinding.profileView.mainFollowers) .putExtra(Constants.EXTRAS_FOLLOWERS,
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername()) v == mainActivity.mainBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_ID, profileId)); .putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID,
profileId));
mainActivity.mainBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null); mainActivity.mainBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
mainActivity.mainBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null); mainActivity.mainBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
@ -1372,18 +1396,23 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
@Override @Override
public void onClick(final View v) { public void onClick(final View v) {
final String userIdFromCookie = Utils.getUserIdFromCookie(MainHelper.this.cookie); 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 if (!isLoggedIn
&& Utils.dataBox.getFavorite(mainActivity.userQuery) != null && Utils.dataBox.getFavorite(mainActivity.userQuery) != null
&& v == mainActivity.mainBinding.profileView.btnFollow) { && v == mainActivity.mainBinding.profileView.btnFollow) {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery,
Long.parseLong(Utils.dataBox.getFavorite(mainActivity.userQuery).split("/")[1]), 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(); onRefresh();
} else if (!isLoggedIn } else if (!isLoggedIn
&& (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) { && (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, System.currentTimeMillis(), 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(); onRefresh();
} else if (v == mainActivity.mainBinding.profileView.btnFollow) { } else if (v == mainActivity.mainBinding.profileView.btnFollow) {
new ProfileAction().execute("follow"); new ProfileAction().execute("follow");
@ -1395,18 +1424,18 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
new ProfileAction().execute("followtag"); new ProfileAction().execute("followtag");
} else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) { } else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) {
mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class) mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );
} else if (v == mainActivity.mainBinding.profileView.btnSaved) { } else if (v == mainActivity.mainBinding.profileView.btnSaved) {
mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class) mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "$" + mainActivity.profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "$" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );
} else if (v == mainActivity.mainBinding.profileView.btnLiked) { } else if (v == mainActivity.mainBinding.profileView.btnLiked) {
mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class) mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "^" + mainActivity.profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "^" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );
} }
} }
@ -1418,12 +1447,31 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
protected Void doInBackground(String... rawAction) { protected Void doInBackground(String... rawAction) {
action = rawAction[0]; 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") ? final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null
mainActivity.profileModel.getFollowing() || mainActivity.profileModel.getRequested() ? "tags/" + (mainActivity.hashtagModel.getFollowing()
? "unfollow/" : "follow/" : ? "unfollow/"
action.equals("restrict") ? : "follow/") + mainActivity.hashtagModel.getName() + "/"
mainActivity.profileModel.getRestricted() ? "unrestrict/" : "restrict/" : : (action.equals("restrict") && mainActivity.profileModel != null
mainActivity.profileModel.getBlocked() ? "unblock/" : "block/")); ? "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 { try {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST"); urlConnection.setRequestMethod("POST");

View File

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

View File

@ -6,7 +6,7 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Animatable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
@ -32,20 +32,17 @@ import androidx.core.view.GestureDetectorCompat;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.facebook.drawee.backends.pipeline.Fresco;
import com.bumptech.glide.RequestManager; import com.facebook.drawee.controller.BaseControllerListener;
import com.bumptech.glide.load.DataSource; import com.facebook.imagepipeline.image.ImageInfo;
import com.bumptech.glide.load.engine.GlideException; import com.facebook.imagepipeline.request.ImageRequest;
import com.bumptech.glide.request.RequestListener; import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.bumptech.glide.request.target.Target;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
@ -60,7 +57,7 @@ import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.i.iPostFetcher; import awais.instagrabber.asyncs.i.iPostFetcher;
import awais.instagrabber.customviews.CommentMentionClickSpan; import awais.instagrabber.customviews.CommentMentionClickSpan;
import awais.instagrabber.customviews.helpers.SwipeGestureListener; 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.FetchListener;
import awais.instagrabber.interfaces.SwipeEvent; import awais.instagrabber.interfaces.SwipeEvent;
import awais.instagrabber.models.BasePostModel; import awais.instagrabber.models.BasePostModel;
@ -68,16 +65,17 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import static awais.instagrabber.utils.Utils.settingsHelper; import static awais.instagrabber.utils.Utils.settingsHelper;
@Deprecated
public final class PostViewer extends BaseLanguageActivity { public final class PostViewer extends BaseLanguageActivity {
private ActivityViewerBinding viewerBinding; private ItemFullPostViewBkBinding viewerBinding;
private String url, prevUsername, commentsEndCursor; private String url, prevUsername;
private ProfileModel profileModel; private ProfileModel profileModel;
private BasePostModel postModel; private BasePostModel postModel;
private ViewerPostModel viewerPostModel; private ViewerPostModel viewerPostModel;
@ -90,7 +88,7 @@ public final class PostViewer extends BaseLanguageActivity {
private Resources resources; private Resources resources;
private boolean session = false, isFromShare, liked, saved, ok = false; private boolean session = false, isFromShare, liked, saved, ok = false;
private int slidePos = 0, lastSlidePos = 0; private int slidePos = 0, lastSlidePos = 0;
private ItemGetType itemGetType; private PostItemType postItemType;
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
final View.OnTouchListener gestureTouchListener = new View.OnTouchListener() { final View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
private float startX; private float startX;
@ -117,13 +115,13 @@ public final class PostViewer extends BaseLanguageActivity {
} }
}; };
private final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> { private final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
final String username = viewerPostModel.getUsername(); final String username = viewerPostModel.getProfileModel().getUsername();
if (which == 0) { if (which == 0) {
searchUsername(username); searchUsername(username);
} else if (profileModel != null && which == 1) { } else if (profileModel != null && which == 1) {
startActivity(new Intent(this, ProfilePicViewer.class) startActivity(new Intent(this, ProfilePicViewer.class)
.putExtra(Constants.EXTRAS_PROFILE, profileModel)); .putExtra(Constants.EXTRAS_PROFILE, profileModel));
} }
}; };
private final View.OnClickListener onClickListener = new View.OnClickListener() { private final View.OnClickListener onClickListener = new View.OnClickListener() {
@ -131,7 +129,8 @@ public final class PostViewer extends BaseLanguageActivity {
public void onClick(final View v) { public void onClick(final View v) {
if (v == viewerBinding.topPanel.ivProfilePic) { if (v == viewerBinding.topPanel.ivProfilePic) {
new AlertDialog.Builder(PostViewer.this).setAdapter(profileDialogAdapter, profileDialogListener) 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) { } else if (v == viewerBinding.ivToggleFullScreen) {
toggleFullscreen(); toggleFullscreen();
@ -185,7 +184,6 @@ public final class PostViewer extends BaseLanguageActivity {
ActivityCompat.requestPermissions(this, Utils.PERMS, 8020); ActivityCompat.requestPermissions(this, Utils.PERMS, 8020);
}; };
private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener); private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
private RequestManager glideRequestManager;
private LinearLayout.LayoutParams containerLayoutParams; private LinearLayout.LayoutParams containerLayoutParams;
private final FetchListener<ViewerPostModel[]> pfl = result -> { private final FetchListener<ViewerPostModel[]> pfl = result -> {
if (result == null || result.length < 1) { if (result == null || result.length < 1) {
@ -208,25 +206,28 @@ public final class PostViewer extends BaseLanguageActivity {
viewerCaptionParent.setOnTouchListener(gestureTouchListener); viewerCaptionParent.setOnTouchListener(gestureTouchListener);
viewerBinding.playerView.setOnTouchListener(gestureTouchListener); viewerBinding.playerView.setOnTouchListener(gestureTouchListener);
viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> { // viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
final float diffX = e2.getX() - e1.getX(); // final float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD // if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
&& Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) { // && Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
swipeEvent.onSwipe(diffX > 0); // swipeEvent.onSwipe(diffX > 0);
return true; // return true;
} // }
return false; // return false;
}); // });
final long commentsCount = viewerPostModel.getCommentsCount(); final long commentsCount = viewerPostModel.getCommentsCount();
viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount)); viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE); viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
viewerBinding.bottomPanel.btnComments.setOnClickListener(v -> viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
startActivityForResult(new Intent(this, CommentsViewer.class) startActivityForResult(new Intent(this, CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, postModel.getShortCode()) .putExtra(Constants.EXTRAS_SHORTCODE,
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId()) postModel.getShortCode())
.putExtra(Constants.EXTRAS_USER, postUserId), 6969)); .putExtra(Constants.EXTRAS_POST,
viewerPostModel.getPostId())
.putExtra(Constants.EXTRAS_USER, postUserId),
6969));
viewerBinding.bottomPanel.btnComments.setClickable(true); viewerBinding.bottomPanel.btnComments.setClickable(true);
viewerBinding.bottomPanel.btnComments.setEnabled(true); viewerBinding.bottomPanel.btnComments.setEnabled(true);
@ -241,8 +242,8 @@ public final class PostViewer extends BaseLanguageActivity {
} }
} }
setupPostInfoBar("@" + viewerPostModel.getUsername(), viewerPostModel.getItemType(), setupPostInfoBar("@" + viewerPostModel.getProfileModel().getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocationName(), viewerPostModel.getLocation()); viewerPostModel.getLocationName(), viewerPostModel.getLocation());
postCaption = postModel.getPostCaption(); postCaption = postModel.getPostCaption();
viewerCaptionParent.setVisibility(View.VISIBLE); viewerCaptionParent.setVisibility(View.VISIBLE);
@ -255,11 +256,9 @@ public final class PostViewer extends BaseLanguageActivity {
@Override @Override
protected void onCreate(@Nullable final Bundle savedInstanceState) { protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
viewerBinding = ActivityViewerBinding.inflate(getLayoutInflater()); viewerBinding = ItemFullPostViewBkBinding.inflate(getLayoutInflater());
setContentView(viewerBinding.getRoot()); setContentView(viewerBinding.getRoot());
glideRequestManager = Glide.with(this);
final Intent intent = getIntent(); final Intent intent = getIntent();
if (intent == null || !intent.hasExtra(Constants.EXTRAS_POST) if (intent == null || !intent.hasExtra(Constants.EXTRAS_POST)
|| (postModel = (PostModel) intent.getSerializableExtra(Constants.EXTRAS_POST)) == null) { || (postModel = (PostModel) intent.getSerializableExtra(Constants.EXTRAS_POST)) == null) {
@ -270,7 +269,7 @@ public final class PostViewer extends BaseLanguageActivity {
containerLayoutParams = (LinearLayout.LayoutParams) viewerBinding.container.getLayoutParams(); containerLayoutParams = (LinearLayout.LayoutParams) viewerBinding.container.getLayoutParams();
if (intent.hasExtra(Constants.EXTRAS_TYPE)) if (intent.hasExtra(Constants.EXTRAS_TYPE))
itemGetType = (ItemGetType) intent.getSerializableExtra(Constants.EXTRAS_TYPE); postItemType = (PostItemType) intent.getSerializableExtra(Constants.EXTRAS_TYPE);
resources = getResources(); resources = getResources();
@ -295,7 +294,7 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.btnDownload.setOnClickListener(downloadClickListener); viewerBinding.btnDownload.setOnClickListener(downloadClickListener);
profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
new String[]{resources.getString(R.string.open_profile), resources.getString(R.string.view_pfp)}); new String[]{resources.getString(R.string.open_profile), resources.getString(R.string.view_pfp)});
postModel.setPosition(intent.getIntExtra(Constants.EXTRAS_INDEX, -1)); postModel.setPosition(intent.getIntExtra(Constants.EXTRAS_INDEX, -1));
@ -314,17 +313,17 @@ public final class PostViewer extends BaseLanguageActivity {
swipeEvent = isRight -> { swipeEvent = isRight -> {
final List<? extends BasePostModel> itemGetterItems; final List<? extends BasePostModel> itemGetterItems;
final boolean isMainSwipe; final boolean isSwipeable;
if (itemGetType == ItemGetType.SAVED_ITEMS && SavedViewer.itemGetter != null) { if (postItemType == PostItemType.SAVED && SavedViewer.itemGetter != null) {
itemGetterItems = SavedViewer.itemGetter.get(itemGetType); itemGetterItems = SavedViewer.itemGetter.get(postItemType);
isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.SAVED_ITEMS && isFromShare); isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.SAVED && isFromShare);
} else if (itemGetType != null && MainActivityBackup.itemGetter != null) { } else if (postItemType != null && MainActivityBackup.itemGetter != null) {
itemGetterItems = MainActivityBackup.itemGetter.get(itemGetType); itemGetterItems = MainActivityBackup.itemGetter.get(postItemType);
isMainSwipe = !(itemGetterItems.size() < 1 || itemGetType == ItemGetType.MAIN_ITEMS && isFromShare); isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.MAIN && isFromShare);
} else { } else {
itemGetterItems = null; itemGetterItems = null;
isMainSwipe = false; isSwipeable = false;
} }
final BasePostModel[] basePostModels = mediaAdapter.getPostModels(); final BasePostModel[] basePostModels = mediaAdapter.getPostModels();
@ -334,7 +333,7 @@ public final class PostViewer extends BaseLanguageActivity {
if (isRight) { if (isRight) {
--slidePos; --slidePos;
if (!isMainSwipe && slidePos < 0) slidePos = 0; if (!isSwipeable && slidePos < 0) slidePos = 0;
if (slides > 0 && slidePos >= 0) { if (slides > 0 && slidePos >= 0) {
if (basePostModels[slidePos] instanceof ViewerPostModel) { if (basePostModels[slidePos] instanceof ViewerPostModel) {
viewerPostModel = (ViewerPostModel) basePostModels[slidePos]; viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
@ -342,10 +341,10 @@ public final class PostViewer extends BaseLanguageActivity {
refreshPost(); refreshPost();
return; return;
} }
if (isMainSwipe && --position < 0) position = itemGetterItems.size() - 1; if (isSwipeable && --position < 0) position = itemGetterItems.size() - 1;
} else { } else {
++slidePos; ++slidePos;
if (!isMainSwipe && slidePos >= slides) slidePos = slides - 1; if (!isSwipeable && slidePos >= slides) slidePos = slides - 1;
if (slides > 0 && slidePos < slides) { if (slides > 0 && slidePos < slides) {
if (basePostModels[slidePos] instanceof ViewerPostModel) { if (basePostModels[slidePos] instanceof ViewerPostModel) {
viewerPostModel = (ViewerPostModel) basePostModels[slidePos]; viewerPostModel = (ViewerPostModel) basePostModels[slidePos];
@ -353,10 +352,10 @@ public final class PostViewer extends BaseLanguageActivity {
refreshPost(); refreshPost();
return; return;
} }
if (isMainSwipe && ++position >= itemGetterItems.size()) position = 0; if (isSwipeable && ++position >= itemGetterItems.size()) position = 0;
} }
if (isMainSwipe) { if (isSwipeable) {
slidePos = 0; slidePos = 0;
ok = false; ok = false;
Log.d("AWAISKING_APP", "swipe left <<< post[" + position + "]: " + postModel + " -- " + slides); 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.setVisibility(View.GONE);
viewerBinding.playerView.setPlayer(null); viewerBinding.playerView.setPlayer(null);
viewerBinding.imageViewer.setImageResource(0); viewerBinding.imageViewer.setController(null);
viewerBinding.imageViewer.setImageDrawable(null);
if (postModel.getShortCode() != null) if (postModel.getShortCode() != null)
new PostFetcher(postModel.getShortCode(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 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.bottomPanel.btnMute.setVisibility(View.VISIBLE);
viewerBinding.progressView.setVisibility(View.GONE); viewerBinding.progressView.setVisibility(View.GONE);
viewerBinding.imageViewer.setVisibility(View.GONE); viewerBinding.imageViewer.setVisibility(View.GONE);
viewerBinding.imageViewer.setImageDrawable(null); viewerBinding.imageViewer.setController(null);
if (viewerPostModel.getVideoViews() > -1) { if (viewerPostModel.getVideoViews() > -1) {
viewsContainer.setVisibility(View.VISIBLE); viewsContainer.setVisibility(View.VISIBLE);
@ -426,22 +424,36 @@ public final class PostViewer extends BaseLanguageActivity {
.createMediaSource(Uri.parse(url)); .createMediaSource(Uri.parse(url));
mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() { mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
@Override @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); viewerBinding.progressView.setVisibility(View.GONE);
} }
@Override @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); viewerBinding.progressView.setVisibility(View.VISIBLE);
} }
@Override @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); viewerBinding.progressView.setVisibility(View.GONE);
} }
@Override @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); viewerBinding.progressView.setVisibility(View.GONE);
} }
}); });
@ -459,26 +471,31 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.progressView.setVisibility(View.VISIBLE); viewerBinding.progressView.setVisibility(View.VISIBLE);
viewerBinding.bottomPanel.btnMute.setVisibility(View.GONE); viewerBinding.bottomPanel.btnMute.setVisibility(View.GONE);
viewerBinding.bottomPanel.btnDownload.setVisibility(View.VISIBLE); viewerBinding.bottomPanel.btnDownload.setVisibility(View.VISIBLE);
viewerBinding.imageViewer.setImageDrawable(null);
viewerBinding.imageViewer.setVisibility(View.VISIBLE); 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))
@Override .setLocalThumbnailPreviewsEnabled(true)
public boolean onLoadFailed(@Nullable final GlideException e, final Object model, final Target<Drawable> target, final boolean isFirstResource) { .setProgressiveRenderingEnabled(true)
viewerBinding.progressView.setVisibility(View.GONE); .build();
return false; viewerBinding.imageViewer.setController(
} Fresco.newDraweeControllerBuilder()
.setImageRequest(requestBuilder)
.setOldController(viewerBinding.imageViewer.getController())
.setLowResImageRequest(ImageRequest.fromUri(url))
.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override @Override
public boolean onResourceReady(final Drawable resource, final Object model, final Target<Drawable> target, final DataSource dataSource, final boolean isFirstResource) { public void onFailure(final String id, final Throwable throwable) {
viewerBinding.progressView.setVisibility(View.GONE); viewerBinding.progressView.setVisibility(View.GONE);
return false; }
}
}).into(viewerBinding.imageViewer); @Override
public void onFinalImageSet(final String id, final ImageInfo imageInfo, final Animatable animatable) {
viewerBinding.progressView.setVisibility(View.GONE);
}
})
.build()
);
} }
private void showDownloadDialog() { private void showDownloadDialog() {
@ -502,15 +519,17 @@ public final class PostViewer extends BaseLanguageActivity {
} }
if (postModels.size() > 0) 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) new AlertDialog.Builder(this).setTitle(R.string.post_viewer_download_dialog_title)
.setMessage(R.string.post_viewer_download_message) .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(); .setNegativeButton(R.string.post_viewer_download_album, clickListener).show();
} else { } 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));
} }
} }
@ -582,9 +601,9 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.viewerCaption.setMentionClickListener(null); viewerBinding.bottomPanel.viewerCaption.setMentionClickListener(null);
viewerBinding.bottomPanel.viewerCaption.setText(postCaption); viewerBinding.bottomPanel.viewerCaption.setText(postCaption);
} }
setupPostInfoBar("@" + viewerPostModel.getUsername(), viewerPostModel.getItemType(), setupPostInfoBar("@" + viewerPostModel.getProfileModel().getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocationName(), viewerPostModel.getLocation()); viewerPostModel.getLocationName(), viewerPostModel.getLocation());
if (postModel instanceof PostModel) { if (postModel instanceof PostModel) {
final PostModel postModel = (PostModel) this.postModel; final PostModel postModel = (PostModel) this.postModel;
@ -682,7 +701,9 @@ public final class PostViewer extends BaseLanguageActivity {
sharingIntent.setType("text/plain"); sharingIntent.setType("text/plain");
sharingIntent.putExtra(Intent.EXTRA_TEXT, "https://instagram.com/p/" + postShortCode); sharingIntent.putExtra(Intent.EXTRA_TEXT, "https://instagram.com/p/" + postShortCode);
startActivity(Intent.createChooser(sharingIntent, 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)));
}); });
} }
} }
@ -691,7 +712,7 @@ public final class PostViewer extends BaseLanguageActivity {
} }
final String titlePrefix = resources.getString(mediaItemType == MediaItemType.MEDIA_TYPE_VIDEO ? final String titlePrefix = resources.getString(mediaItemType == MediaItemType.MEDIA_TYPE_VIDEO ?
R.string.post_viewer_video_post : R.string.post_viewer_image_post); R.string.post_viewer_video_post : R.string.post_viewer_image_post);
if (Utils.isEmpty(from)) viewerBinding.topPanel.title.setText(titlePrefix); if (Utils.isEmpty(from)) viewerBinding.topPanel.title.setText(titlePrefix);
else { else {
final int titleLen = from.length(); final int titleLen = from.length();
@ -731,15 +752,15 @@ public final class PostViewer extends BaseLanguageActivity {
protected Void doInBackground(String... rawAction) { protected Void doInBackground(String... rawAction) {
action = rawAction[0]; action = rawAction[0];
final String url = "https://www.instagram.com/web/" + action + "/" + postModel.getPostId() + "/" + (action == "save" ? final String url = "https://www.instagram.com/web/" + action + "/" + postModel.getPostId() + "/" + (action == "save" ?
(saved ? "unsave/" : "save/") : (saved ? "unsave/" : "save/") :
(liked ? "unlike/" : "like/")); (liked ? "unlike/" : "like/"));
try { try {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST"); urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false); urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT); urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
urlConnection.setRequestProperty("x-csrftoken", urlConnection.setRequestProperty("x-csrftoken",
settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]); settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);
urlConnection.connect(); urlConnection.connect();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
ok = true; ok = true;

View File

@ -109,7 +109,10 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (autoloadPosts && hasNextPage) if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher( currentlyExecuting = new PostsFetcher(
profileModel != null ? profileModel.getId() 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()) .setUsername((isLocation || isHashtag) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
@ -138,7 +141,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (tag instanceof HighlightModel) { if (tag instanceof HighlightModel) {
final HighlightModel highlightModel = (HighlightModel) tag; final HighlightModel highlightModel = (HighlightModel) tag;
new iStoryStatusFetcher(highlightModel.getId(), null, false, false, new iStoryStatusFetcher(highlightModel.getId(), null, false, false,
(!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), true, result -> { (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), true, result -> {
if (result != null && result.length > 0) { if (result != null && result.length > 0) {
// startActivity(new Intent(ProfileViewer.this, StoryViewer.class) // startActivity(new Intent(ProfileViewer.this, StoryViewer.class)
// .putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", "")) // .putExtra(Constants.EXTRAS_USERNAME, userQuery.replace("@", ""))
@ -180,12 +183,14 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
resources = getResources(); resources = getResources();
profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, profileDialogAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
new String[]{resources.getString(R.string.view_pfp), resources.getString(R.string.show_stories)}); new String[]{resources.getString(R.string.view_pfp), resources.getString(R.string.show_stories)});
profileDialogListener = (dialog, which) -> { profileDialogListener = (dialog, which) -> {
final Intent newintent; final Intent newintent;
if (which == 0 || storyModels == null || storyModels.length < 1) { if (which == 0 || storyModels == null || storyModels.length < 1) {
newintent = new Intent(this, ProfilePicViewer.class).putExtra( 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))); ((hashtagModel != null) ? hashtagModel : (locationModel != null ? locationModel : profileModel)));
} }
// else // else
@ -239,7 +244,11 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true); profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(profileModel != null ? profileModel.getId() 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()) .setUsername((isHashtag || isLocation) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null; endCursor = null;
@ -429,12 +438,12 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (isLoggedIn || Utils.settingsHelper.getBoolean(Constants.STORIESIG)) { if (isLoggedIn || Utils.settingsHelper.getBoolean(Constants.STORIESIG)) {
new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false, new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false,
(!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), false, (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), false,
stories -> { stories -> {
storyModels = stories; storyModels = stories;
if (stories != null && stories.length > 0) if (stories != null && stories.length > 0)
profileBinding.profileView.mainProfileImage.setStoriesBorder(); profileBinding.profileView.mainProfileImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new HighlightsFetcher(profileId, (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), hls -> { new HighlightsFetcher(profileId, (!isLoggedIn && Utils.settingsHelper.getBoolean(Constants.STORIESIG)), hls -> {
if (hls != null && hls.length > 0) { if (hls != null && hls.length > 0) {
@ -555,7 +564,8 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
profileBinding.profileView.mainFollowing.setText(span); 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(); CharSequence biography = profileModel.getBiography();
profileBinding.profileView.mainBiography.setCaptionIsExpandable(true); profileBinding.profileView.mainBiography.setCaptionIsExpandable(true);
@ -586,9 +596,11 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (isLoggedIn) { if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent(ProfileViewer.this, FollowViewer.class) final View.OnClickListener followClickListener = v -> startActivity(new Intent(ProfileViewer.this, FollowViewer.class)
.putExtra(Constants.EXTRAS_FOLLOWERS, v == profileBinding.profileView.mainFollowers) .putExtra(Constants.EXTRAS_FOLLOWERS,
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername()) v == profileBinding.profileView.mainFollowers)
.putExtra(Constants.EXTRAS_ID, profileId)); .putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
profileBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null); profileBinding.profileView.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null);
profileBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null); profileBinding.profileView.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null);
@ -749,12 +761,16 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
favouriteAction.setOnMenuItemClickListener(item -> { favouriteAction.setOnMenuItemClickListener(item -> {
if (Utils.dataBox.getFavorite(userQuery) == null) { if (Utils.dataBox.getFavorite(userQuery) == null) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(), 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); favouriteAction.setIcon(R.drawable.ic_like);
} else { } else {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery, Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]), 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); favouriteAction.setIcon(R.drawable.ic_not_liked);
} }
return true; return true;
@ -834,12 +850,16 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
final boolean iamme = (isLoggedIn && profileModel != null) && Utils.getUserIdFromCookie(cookie).equals(profileModel.getId()); final boolean iamme = (isLoggedIn && profileModel != null) && Utils.getUserIdFromCookie(cookie).equals(profileModel.getId());
if (!isLoggedIn && Utils.dataBox.getFavorite(userQuery) != null && v == profileBinding.profileView.btnFollow) { if (!isLoggedIn && Utils.dataBox.getFavorite(userQuery) != null && v == profileBinding.profileView.btnFollow) {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery, Utils.dataBox.delFavorite(new DataBox.FavoriteModel(userQuery,
Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]), Long.parseLong(Utils.dataBox.getFavorite(userQuery).split("/")[1]),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", ""))); locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
onRefresh(); onRefresh();
} else if (!isLoggedIn && (v == profileBinding.profileView.btnFollow || v == profileBinding.profileView.btnFollowTag)) { } else if (!isLoggedIn && (v == profileBinding.profileView.btnFollow || v == profileBinding.profileView.btnFollowTag)) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(), Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(),
locationModel != null ? locationModel.getName() : userQuery.replaceAll("^@", ""))); locationModel != null
? locationModel.getName()
: userQuery.replaceAll("^@", "")));
onRefresh(); onRefresh();
} else if (v == profileBinding.profileView.btnFollow) { } else if (v == profileBinding.profileView.btnFollow) {
new ProfileAction().execute("follow"); new ProfileAction().execute("follow");
@ -851,18 +871,18 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
new ProfileAction().execute("followtag"); new ProfileAction().execute("followtag");
} else if (v == profileBinding.profileView.btnTagged || (v == profileBinding.profileView.btnRestrict && !isLoggedIn)) { } else if (v == profileBinding.profileView.btnTagged || (v == profileBinding.profileView.btnRestrict && !isLoggedIn)) {
startActivity(new Intent(ProfileViewer.this, SavedViewer.class) startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );
} else if (v == profileBinding.profileView.btnSaved) { } else if (v == profileBinding.profileView.btnSaved) {
startActivity(new Intent(ProfileViewer.this, SavedViewer.class) startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );
} else if (v == profileBinding.profileView.btnLiked) { } else if (v == profileBinding.profileView.btnLiked) {
startActivity(new Intent(ProfileViewer.this, SavedViewer.class) startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );
} }
} }
@ -877,14 +897,16 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
final String url = "https://www.instagram.com/web/" + final String url = "https://www.instagram.com/web/" +
((action.equals("followtag") && hashtagModel != null) ? ("tags/" + ((action.equals("followtag") && hashtagModel != null) ? ("tags/" +
(hashtagModel.getFollowing() ? "unfollow/" : "follow/") + hashtagModel.getName() + "/") : ( (hashtagModel.getFollowing() ? "unfollow/" : "follow/") + hashtagModel.getName() + "/") : (
((action.equals("restrict") && profileModel != null) ? "restrict_action" : ("friendships/" + profileModel.getId())) + "/" + ((action.equals("restrict") && profileModel != null)
((action.equals("follow") && profileModel != null) ? ? "restrict_action"
((profileModel.getFollowing() || : ("friendships/" + profileModel.getId())) + "/" +
(!profileModel.getFollowing() && profileModel.getRequested())) ((action.equals("follow") && profileModel != null) ?
? "unfollow/" : "follow/") : ((profileModel.getFollowing() ||
((action.equals("restrict") && profileModel != null) ? (!profileModel.getFollowing() && profileModel.getRequested()))
(profileModel.getRestricted() ? "unrestrict/" : "restrict/") : ? "unfollow/" : "follow/") :
(profileModel.getBlocked() ? "unblock/" : "block/"))))); ((action.equals("restrict") && profileModel != null) ?
(profileModel.getRestricted() ? "unrestrict/" : "restrict/") :
(profileModel.getBlocked() ? "unblock/" : "block/")))));
try { try {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST"); urlConnection.setRequestMethod("POST");

View File

@ -38,7 +38,7 @@ import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.ItemGetter; import awais.instagrabber.interfaces.ItemGetter;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.DownloadMethod; 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.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -87,9 +87,9 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
return false; return false;
} }
Utils.batchDownload(SavedViewer.this, Utils.batchDownload(SavedViewer.this,
username, username,
DownloadMethod.DOWNLOAD_MAIN, DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels()); postsAdapter.getSelectedModels());
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
@ -123,7 +123,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener) currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if (autoloadPosts && hasNextPage) else if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(action, endCursor, this) currentlyExecuting = new PostsFetcher(action, false, endCursor, this)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
savedBinding.swipeRefreshLayout.setRefreshing(false); savedBinding.swipeRefreshLayout.setRefreshing(false);
@ -170,10 +170,10 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
} }
if (checkAndResetAction()) return; if (checkAndResetAction()) return;
startActivity(new Intent(this, PostViewer.class) startActivity(new Intent(this, PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position) .putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel) .putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, username) .putExtra(Constants.EXTRAS_USER, username)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.SAVED_ITEMS)); .putExtra(Constants.EXTRAS_TYPE, PostItemType.SAVED));
}, (model, position) -> { }, (model, position) -> {
if (!postsAdapter.isSelecting()) { if (!postsAdapter.isSelecting()) {
@ -193,7 +193,7 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
savedBinding.swipeRefreshLayout.setRefreshing(true); savedBinding.swipeRefreshLayout.setRefreshing(true);
setSupportActionBar(savedBinding.toolbar.toolbar); setSupportActionBar(savedBinding.toolbar.toolbar);
savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved : savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved :
(action.charAt(0) == '%' ? R.string.tagged : R.string.liked))); (action.charAt(0) == '%' ? R.string.tagged : R.string.liked)));
savedBinding.toolbar.toolbar.setSubtitle(username); savedBinding.toolbar.toolbar.setSubtitle(username);
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
@ -202,15 +202,16 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = action.charAt(0) == '^' currentlyExecuting = action.charAt(0) == '^'
? new iLikedFetcher(endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) ? 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; endCursor = null;
} }
}); });
savedBinding.mainPosts.addOnScrollListener(lazyLoader); savedBinding.mainPosts.addOnScrollListener(lazyLoader);
itemGetter = itemGetType -> { itemGetter = itemGetType -> {
if (itemGetType == ItemGetType.SAVED_ITEMS) if (itemGetType == PostItemType.SAVED)
return postsViewModel.getList().getValue(); return postsViewModel.getList().getValue();
return null; 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.SpannableString;
import android.text.Spanned; import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.View; import android.view.View;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
@ -10,8 +9,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONObject;
import awais.instagrabber.customviews.CommentMentionClickSpan; import awais.instagrabber.customviews.CommentMentionClickSpan;
import awais.instagrabber.customviews.RamboTextView; import awais.instagrabber.customviews.RamboTextView;
import awais.instagrabber.databinding.ItemFeedBottomBinding; import awais.instagrabber.databinding.ItemFeedBottomBinding;
@ -37,7 +34,7 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
this.topBinding = topBinding; this.topBinding = topBinding;
this.bottomBinding = bottomBinding; this.bottomBinding = bottomBinding;
this.mentionClickListener = mentionClickListener; this.mentionClickListener = mentionClickListener;
topBinding.title.setMovementMethod(new LinkMovementMethod()); // topBinding.title.setMovementMethod(new LinkMovementMethod());
bottomBinding.btnComments.setOnClickListener(clickListener); bottomBinding.btnComments.setOnClickListener(clickListener);
topBinding.viewStoryPost.setOnClickListener(clickListener); topBinding.viewStoryPost.setOnClickListener(clickListener);
topBinding.ivProfilePic.setOnClickListener(clickListener); topBinding.ivProfilePic.setOnClickListener(clickListener);
@ -63,14 +60,16 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
final SpannableString spannableString = new SpannableString("@" + profileModel.getUsername()); final SpannableString spannableString = new SpannableString("@" + profileModel.getUsername());
spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0); spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
topBinding.title.setText(spannableString); 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()); bottomBinding.tvPostDate.setText(feedModel.getPostDate());
final long commentsCount = feedModel.getCommentsCount(); final long commentsCount = feedModel.getCommentsCount();
bottomBinding.commentsCount.setText(String.valueOf(commentsCount)); bottomBinding.commentsCount.setText(String.valueOf(commentsCount));
final JSONObject location = feedModel.getLocation(); final String locationName = feedModel.getLocationName();
setLocation(location); final String locationId = feedModel.getLocationId();
setLocation(locationName, locationId);
CharSequence postCaption = feedModel.getPostCaption(); CharSequence postCaption = feedModel.getPostCaption();
final boolean captionEmpty = Utils.isEmpty(postCaption); final boolean captionEmpty = Utils.isEmpty(postCaption);
bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE); bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE);
@ -87,22 +86,19 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder {
bindItem(feedModel); bindItem(feedModel);
} }
private void setLocation(final JSONObject location) { private void setLocation(final String locationName, final String locationId) {
if (location == null) { if (Utils.isEmpty(locationName)) {
topBinding.location.setVisibility(View.GONE); topBinding.location.setVisibility(View.GONE);
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams( topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
)); ));
} else { } else {
topBinding.location.setVisibility(View.VISIBLE); topBinding.location.setVisibility(View.VISIBLE);
topBinding.location.setText(location.optString("name")); topBinding.location.setText(locationName);
topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams( topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
)); ));
topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location, topBinding.location.setOnClickListener(v -> mentionClickListener.onClick(topBinding.location, locationId, false, true));
location.optString("id") + "/" + location.optString("slug"),
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) { private ArrayList<DiscoverItemModel> fetchItems(ArrayList<DiscoverItemModel> discoverItemModels, final String maxId) {
try { try {
final String url = "https://www.instagram.com/explore/grid/?is_prefetch=false&omit_cover_media=true&module=explore_popular" + 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(); final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
@ -130,10 +130,10 @@ public final class DiscoverFetcher extends AsyncTask<Void, Void, DiscoverItemMod
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_DISCOVER_FETCHER, "fetchItems", logCollector.appendException(e, LogCollector.LogFile.ASYNC_DISCOVER_FETCHER, "fetchItems",
new Pair<>("maxId", maxId), new Pair<>("maxId", maxId),
new Pair<>("lastId", lastId), new Pair<>("lastId", lastId),
new Pair<>("isFirst", isFirst), new Pair<>("isFirst", isFirst),
new Pair<>("nextMaxId", nextMaxId)); new Pair<>("nextMaxId", nextMaxId));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
} }
@ -163,19 +163,21 @@ public final class DiscoverFetcher extends AsyncTask<Void, Void, DiscoverItemMod
final MediaItemType mediaType = Utils.getMediaItemType(media.getInt("media_type")); final MediaItemType mediaType = Utils.getMediaItemType(media.getInt("media_type"));
final DiscoverItemModel model = new DiscoverItemModel(mediaType, final DiscoverItemModel model = new DiscoverItemModel(mediaType,
media.getString(Constants.EXTRAS_ID), media.getString("pk"),
media.getString("code"), media.getString("code"),
Utils.getThumbnailUrl(media, mediaType)); Utils.getThumbnailUrl(media, mediaType));
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" + 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 // to check if file exists
File customDir = null; File customDir = null;
if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) { if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = settingsHelper.getString(FOLDER_PATH); final String customPath = settingsHelper.getString(FOLDER_PATH);
if (!Utils.isEmpty(customPath)) customDir = new File(customPath + 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); 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) { if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
final String json = Utils.readFromConnection(urlConnection); final String json = Utils.readFromConnection(urlConnection);
Log.d(TAG, json); // Log.d(TAG, json);
final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data") final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data")
.getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline"); .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; ProfileModel profileModel = null;
if (feedItem.has("owner")) { if (feedItem.has("owner")) {
final JSONObject owner = feedItem.getJSONObject("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 false, // if you can see it then you def follow
owner.optBoolean("is_verified"), owner.optBoolean("is_verified"),
owner.getString(Constants.EXTRAS_ID), owner.getString(Constants.EXTRAS_ID),
owner.getString(Constants.EXTRAS_USERNAME), owner.getString(Constants.EXTRAS_USERNAME),
owner.optString("full_name"), owner.optString("full_name"),
null, null, null,
null,
owner.getString("profile_pic_url"), 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"); 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"); 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, isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
videoViews, videoViews,
feedItem.getString(Constants.EXTRAS_ID), 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_liked"),
feedItem.getBoolean("viewer_has_saved"), feedItem.getBoolean("viewer_has_saved"),
feedItem.getJSONObject("edge_media_preview_like").getLong("count"), 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"); 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, isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
node.getString(Constants.EXTRAS_ID), node.getString(Constants.EXTRAS_ID),
isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node), isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
null, null, null, null,
node.optLong("video_view_count", -1), -1, false, false, null,
null,
node.optLong("video_view_count", -1),
-1,
false,
false,
feedItem.getJSONObject("edge_media_preview_like").getLong("count"), feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
feedItem.isNull("location") ? null : feedItem.getJSONObject("location").optString("name"), locationName,
feedItem.isNull("location") ? null : locationId);
(feedItem.getJSONObject("location").optString("id") + "/" +
feedItem.getJSONObject("location").optString("slug")));
sliderItems[j].setSliderDisplayUrl(node.getString("display_url")); sliderItems[j].setSliderDisplayUrl(node.getString("display_url"));
} }
@ -193,7 +220,9 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_FEED_FETCHER, "doInBackground"); 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; return result;

View File

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

View File

@ -13,6 +13,7 @@ import java.net.URL;
import awais.instagrabber.BuildConfig; import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants; 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) if (commentObject != null && (commentObject = commentObject.optJSONObject("page_info")) != null)
endCursor = commentObject.optString("end_cursor"); endCursor = commentObject.optString("end_cursor");
final ProfileModel profileModel = ProfileModel.getDefaultProfileModel(null, username);
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) { if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType, final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
media.getString(Constants.EXTRAS_ID), media.getString(Constants.EXTRAS_ID),
isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media), isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media),
shortCode, shortCode,
Utils.isEmpty(postCaption) ? null : postCaption, Utils.isEmpty(postCaption) ? null : postCaption,
username, profileModel,
isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1, isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"), timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"), 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), isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node),
node.getString(Constants.EXTRAS_SHORTCODE), node.getString(Constants.EXTRAS_SHORTCODE),
postCaption, postCaption,
username, profileModel,
isChildVideo && node.has("video_view_count") ? node.getLong("video_view_count") : -1, isChildVideo && node.has("video_view_count") ? node.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"), timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"), 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[]> { public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
private static final String TAG = "PostsFetcher"; private static final String TAG = "PostsFetcher";
private boolean isLocation;
private final String endCursor; private final String endCursor;
private final String id; private final String id;
private final FetchListener<PostModel[]> fetchListener; private final FetchListener<PostModel[]> fetchListener;
@ -37,8 +38,12 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
this.fetchListener = fetchListener; 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.id = id;
this.isLocation = isLocation;
this.endCursor = endCursor == null ? "" : endCursor; this.endCursor = endCursor == null ? "" : endCursor;
this.fetchListener = fetchListener; this.fetchListener = fetchListener;
} }
@ -53,15 +58,15 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
final boolean isHashTag = id.charAt(0) == '#'; final boolean isHashTag = id.charAt(0) == '#';
final boolean isSaved = id.charAt(0) == '$'; final boolean isSaved = id.charAt(0) == '$';
final boolean isTagged = id.charAt(0) == '%'; final boolean isTagged = id.charAt(0) == '%';
final boolean isLocation = id.contains("/"); // final boolean isLocation = id.contains("/");
final String url; final String url;
if (isHashTag) 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 + "\"}"; "{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isLocation) else if (isLocation)
url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" + 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) else if (isSaved)
url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" + url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" +
"{\"id\":\"" + id.substring(1) + "\",\"first\":150,\"after\":\"" + endCursor + "\"}"; "{\"id\":\"" + id.substring(1) + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
@ -84,18 +89,20 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
File customDir = null; File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH + 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); if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
} }
final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn)) final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn))
.getJSONObject("data") .getJSONObject("data")
.getJSONObject(isHashTag ? Constants.EXTRAS_HASHTAG : .getJSONObject(isHashTag ? Constants.EXTRAS_HASHTAG :
(isLocation ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_USER)) (isLocation ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_USER))
.getJSONObject(isHashTag ? "edge_hashtag_to_media" : .getJSONObject(isHashTag ? "edge_hashtag_to_media" :
(isLocation ? "edge_location_to_media" : (isLocation ? "edge_location_to_media" :
(isSaved ? "edge_saved_media" : (isSaved ? "edge_saved_media" :
(isTagged ? "edge_user_to_photos_of_you" : "edge_owner_to_timeline_media")))); (isTagged ? "edge_user_to_photos_of_you" : "edge_owner_to_timeline_media"))));
final String endCursor; final String endCursor;
final boolean hasNextPage; final boolean hasNextPage;
@ -124,11 +131,11 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
else itemType = MediaItemType.MEDIA_TYPE_IMAGE; else itemType = MediaItemType.MEDIA_TYPE_IMAGE;
models[i] = new PostModel(itemType, mediaNode.getString(Constants.EXTRAS_ID), models[i] = new PostModel(itemType, mediaNode.getString(Constants.EXTRAS_ID),
mediaNode.getString("display_url"), mediaNode.getString("thumbnail_src"), mediaNode.getString("display_url"), mediaNode.getString("thumbnail_src"),
mediaNode.getString(Constants.EXTRAS_SHORTCODE), mediaNode.getString(Constants.EXTRAS_SHORTCODE),
captions.length() > 0 ? captions.getJSONObject(0).getJSONObject("node").getString("text") : null, captions.length() > 0 ? captions.getJSONObject(0).getJSONObject("node").getString("text") : null,
mediaNode.getLong("taken_at_timestamp"), mediaNode.optBoolean("viewer_has_liked"), mediaNode.getLong("taken_at_timestamp"), mediaNode.optBoolean("viewer_has_liked"),
mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count")); mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count"));
Utils.checkExistence(downloadDir, customDir, isSlider, models[i]); Utils.checkExistence(downloadDir, customDir, isSlider, models[i]);
} }

View File

@ -43,7 +43,7 @@ public class DirectThreadBroadcaster extends AsyncTask<DirectThreadBroadcaster.B
final String cookie = settingsHelper.getString(Constants.COOKIE); final String cookie = settingsHelper.getString(Constants.COOKIE);
final String cc = UUID.randomUUID().toString(); final String cc = UUID.randomUUID().toString();
final Map<String, String> form = new HashMap<>(); 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("_uid", Utils.getUserIdFromCookie(cookie));
form.put("__uuid", settingsHelper.getString(Constants.DEVICE_UUID)); form.put("__uuid", settingsHelper.getString(Constants.DEVICE_UUID));
form.put("client_context", cc); form.put("client_context", cc);

View File

@ -13,6 +13,7 @@ import java.net.URL;
import awais.instagrabber.BuildConfig; import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants; 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; import static awais.instagrabber.utils.Utils.logCollector;
public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]> { public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]> {
private static final String TAG = "iPostFetcher";
private final String id; private final String id;
private final FetchListener<ViewerPostModel[]> fetchListener; private final FetchListener<ViewerPostModel[]> fetchListener;
@ -43,18 +46,54 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
conn.connect(); conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject media = new JSONObject(Utils.readFromConnection(conn))
final JSONObject media = new JSONObject(Utils.readFromConnection(conn)).getJSONArray("items").getJSONObject(0); .getJSONArray("items")
.getJSONObject(0);
final String username = media.has("user") ? media.getJSONObject("user").getString(Constants.EXTRAS_USERNAME) : null; 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 // to check if file exists
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" + final boolean shouldDownloadToUserFolder = Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER);
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : "")); final File downloadDir = new File(
Environment.getExternalStorageDirectory(),
"Download" + (shouldDownloadToUserFolder ? "/" + profileModel.getUsername() : ""));
File customDir = null; File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH + final String customPath = Utils.settingsHelper.getString(FOLDER_PATH)
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : "")); + (shouldDownloadToUserFolder ? "/" + profileModel.getUsername() : "");
if (!Utils.isEmpty(customPath)) customDir = new File(customPath); 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 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) { if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType, final ViewerPostModel postModel = new ViewerPostModel(
mediaItemType,
media.getString(Constants.EXTRAS_ID), media.getString(Constants.EXTRAS_ID),
isVideo isVideo ? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false)
? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false)
: Utils.getHighQualityImage(media), : Utils.getHighQualityImage(media),
media.getString("code"), media.getString("code"),
Utils.isEmpty(postCaption) ? null : postCaption, Utils.isEmpty(postCaption) ? null : postCaption,
username, profileModel,
isVideo && media.has("view_count") ? media.getLong("view_count") : -1, 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.getLong("like_count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"), locationName,
media.isNull("location") ? null : locationId);
(media.getJSONObject("location").optString("id") + "/" +
media.getJSONObject("location").optString("slug")));
postModel.setCommentsCount(commentsCount); postModel.setCommentsCount(commentsCount);
@ -106,23 +156,22 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
final JSONObject node = children.getJSONObject(i); final JSONObject node = children.getJSONObject(i);
final boolean isChildVideo = node.has("video_duration"); 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), media.getString(Constants.EXTRAS_ID),
isChildVideo isChildVideo ? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false)
? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false) : Utils.getHighQualityImage(node),
: Utils.getHighQualityImage(node),
media.getString("code"), media.getString("code"),
postCaption, postCaption,
username, profileModel,
-1, -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.getLong("like_count"),
media.isNull("location") ? null : media.getJSONObject("location").optString("name"), locationName,
media.isNull("location") ? null : locationId);
(media.getJSONObject("location").optString("id") + "/" +
media.getJSONObject("location").optString("slug")));
postModels[i].setSliderDisplayUrl(Utils.getHighQualityImage(node)); postModels[i].setSliderDisplayUrl(Utils.getHighQualityImage(node));
Utils.checkExistence(downloadDir, customDir, true, postModels[i]); Utils.checkExistence(downloadDir, customDir, true, postModels[i]);
} }
@ -135,7 +184,9 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
} catch (Exception e) { } catch (Exception e) {
if (logCollector != null) if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground (i)"); 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; 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 LazyLoadListener lazyLoadListener;
private final RecyclerView.LayoutManager layoutManager; 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.layoutManager = layoutManager;
this.lazyLoadListener = lazyLoadListener; this.lazyLoadListener = lazyLoadListener;
if (threshold > 0) {
this.visibleThreshold = threshold;
return;
}
if (layoutManager instanceof GridLayoutManager) { if (layoutManager instanceof GridLayoutManager) {
this.visibleThreshold = 5 * Math.max(3, ((GridLayoutManager) layoutManager).getSpanCount()); this.visibleThreshold = 5 * Math.max(3, ((GridLayoutManager) layoutManager).getSpanCount());
} else if (layoutManager instanceof LinearLayoutManager) { } 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 @Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) { public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
final int totalItemCount = layoutManager.getItemCount(); final int totalItemCount = layoutManager.getItemCount();
@ -54,7 +62,8 @@ public final class RecyclerLazyLoader extends RecyclerView.OnScrollListener {
} }
if (!loading && lastVisibleItemPosition + visibleThreshold > totalItemCount) { if (!loading && lastVisibleItemPosition + visibleThreshold > totalItemCount) {
if (lazyLoadListener != null) lazyLoadListener.onLoadMore(++currentPage, totalItemCount); if (lazyLoadListener != null)
lazyLoadListener.onLoadMore(++currentPage, totalItemCount);
loading = true; loading = true;
} }
} }

View File

@ -136,7 +136,7 @@ public final class DirectDownload extends Activity {
if (notificationManager != null) notificationManager.cancel(1900000000); if (notificationManager != null) notificationManager.cancel(1900000000);
if (result != null) { if (result != null) {
if (result.length == 1) { 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)); Arrays.asList(result));
} else if (result.length > 1) { } else if (result.length > 1) {
context.startActivity(new Intent(context, MultiDirectDialog.class) context.startActivity(new Intent(context, MultiDirectDialog.class)

View File

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

View File

@ -1,6 +1,5 @@
package awais.instagrabber.fragments; package awais.instagrabber.fragments;
import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -25,6 +24,8 @@ import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -33,7 +34,6 @@ import java.util.List;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HashtagFetcher; import awais.instagrabber.asyncs.HashtagFetcher;
import awais.instagrabber.asyncs.PostsFetcher; import awais.instagrabber.asyncs.PostsFetcher;
@ -50,7 +50,6 @@ import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -104,9 +103,9 @@ public class HashTagFragment extends Fragment {
return false; return false;
} }
Utils.batchDownload(requireContext(), Utils.batchDownload(requireContext(),
hashtag, hashtag,
DownloadMethod.DOWNLOAD_MAIN, DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels()); postsAdapter.getSelectedModels());
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
@ -191,11 +190,26 @@ public class HashTagFragment extends Fragment {
return; return;
} }
if (checkAndResetAction()) return; if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class) // startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position) // .putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel) // .putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, hashtag) // .putExtra(Constants.EXTRAS_USER, hashtag)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS)); // .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) -> { }, (model, position) -> {
if (!postsAdapter.isSelecting()) { if (!postsAdapter.isSelecting()) {
@ -242,7 +256,7 @@ public class HashTagFragment extends Fragment {
stopCurrentExecutor(); stopCurrentExecutor();
binding.btnFollowTag.setVisibility(View.VISIBLE); binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.swipeRefreshLayout.setRefreshing(true); 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) { if (isLoggedIn) {
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> { new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
storyModels = stories; storyModels = stories;
@ -254,16 +268,16 @@ public class HashTagFragment extends Fragment {
binding.btnFollowTag.setText(hashtagModel.getFollowing() ? R.string.unfollow : R.string.follow); binding.btnFollowTag.setText(hashtagModel.getFollowing() ? R.string.unfollow : R.string.follow);
ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf( ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf(
ContextCompat.getColor(requireContext(), hashtagModel.getFollowing() ContextCompat.getColor(requireContext(), hashtagModel.getFollowing()
? R.color.btn_purple_background ? R.color.btn_purple_background
: R.color.btn_pink_background))); : R.color.btn_pink_background)));
} else { } else {
binding.btnFollowTag.setText(Utils.dataBox.getFavorite(hashtag) != null binding.btnFollowTag.setText(Utils.dataBox.getFavorite(hashtag) != null
? R.string.unfavorite_short ? R.string.unfavorite_short
: R.string.favorite_short); : R.string.favorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf( ViewCompat.setBackgroundTintList(binding.btnFollowTag, ColorStateList.valueOf(
ContextCompat.getColor(requireContext(), Utils.dataBox.getFavorite(hashtag) != null ContextCompat.getColor(requireContext(), Utils.dataBox.getFavorite(hashtag) != null
? R.color.btn_purple_background ? R.color.btn_purple_background
: R.color.btn_pink_background))); : R.color.btn_pink_background)));
} }
binding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic()); binding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic());
final String postCount = String.valueOf(hashtagModel.getPostCount()); final String postCount = String.valueOf(hashtagModel.getPostCount());

View File

@ -24,6 +24,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -32,7 +34,6 @@ import java.util.List;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.LocationFetcher; import awais.instagrabber.asyncs.LocationFetcher;
import awais.instagrabber.asyncs.PostsFetcher; import awais.instagrabber.asyncs.PostsFetcher;
@ -49,7 +50,6 @@ import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -64,7 +64,7 @@ public class LocationFragment extends Fragment {
private FragmentLocationBinding binding; private FragmentLocationBinding binding;
private NestedCoordinatorLayout root; private NestedCoordinatorLayout root;
private boolean shouldRefresh = true; private boolean shouldRefresh = true;
private String location; private String locationId;
private LocationModel locationModel; private LocationModel locationModel;
private PostsViewModel postsViewModel; private PostsViewModel postsViewModel;
private PostsAdapter postsAdapter; private PostsAdapter postsAdapter;
@ -89,29 +89,29 @@ public class LocationFragment extends Fragment {
} }
}; };
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback( private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
R.menu.multi_select_download_menu, R.menu.multi_select_download_menu, new PrimaryActionModeCallback.CallbacksHelper() {
new PrimaryActionModeCallback.CallbacksHelper() { @Override
@Override public void onDestroy(final ActionMode mode) {
public void onDestroy(final ActionMode mode) { onBackPressedCallback.handleOnBackPressed();
onBackPressedCallback.handleOnBackPressed(); }
}
@Override @Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { public boolean onActionItemClicked(final ActionMode mode,
if (item.getItemId() == R.id.action_download) { final MenuItem item) {
if (postsAdapter == null || location == null) { if (item.getItemId() == R.id.action_download) {
return false; if (postsAdapter == null || locationId == null) {
}
Utils.batchDownload(requireContext(),
location,
DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels());
checkAndResetAction();
return true;
}
return false; return false;
} }
}); Utils.batchDownload(requireContext(),
locationId,
DownloadMethod.DOWNLOAD_MAIN,
postsAdapter.getSelectedModels());
checkAndResetAction();
return true;
}
return false;
}
});
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() { private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override @Override
public void onResult(final PostModel[] result) { public void onResult(final PostModel[] result) {
@ -119,7 +119,8 @@ public class LocationFragment extends Fragment {
if (result == null) return; if (result == null) return;
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
final List<PostModel> postModels = postsViewModel.getList().getValue(); 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)); finalList.addAll(Arrays.asList(result));
postsViewModel.getList().postValue(finalList); postsViewModel.getList().postValue(finalList);
PostModel model = null; PostModel model = null;
@ -141,7 +142,9 @@ public class LocationFragment extends Fragment {
@Nullable @Nullable
@Override @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) { if (root != null) {
shouldRefresh = false; shouldRefresh = false;
return root; return root;
@ -171,7 +174,7 @@ public class LocationFragment extends Fragment {
final String cookie = settingsHelper.getString(Constants.COOKIE); final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments()); final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments());
location = fragmentArgs.getLocation(); locationId = fragmentArgs.getLocationId();
setTitle(); setTitle();
setupPosts(); setupPosts();
fetchLocationModel(); fetchLocationModel();
@ -190,11 +193,26 @@ public class LocationFragment extends Fragment {
return; return;
} }
if (checkAndResetAction()) return; if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class) final List<PostModel> postModels = postsViewModel.getList().getValue();
.putExtra(Constants.EXTRAS_INDEX, position) if (postModels == null || postModels.size() == 0) return;
.putExtra(Constants.EXTRAS_POST, postModel) if (postModels.get(0) == null) return;
.putExtra(Constants.EXTRAS_USER, location) final String postId = postModels.get(0).getPostId();
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS)); 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) -> { }, (model, position) -> {
if (!postsAdapter.isSelecting()) { if (!postsAdapter.isSelecting()) {
@ -204,7 +222,8 @@ public class LocationFragment extends Fragment {
if (onBackPressedCallback.isEnabled()) { if (onBackPressedCallback.isEnabled()) {
return true; return true;
} }
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher(); final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
onBackPressedCallback.setEnabled(true); onBackPressedCallback.setEnabled(true);
actionMode = fragmentActivity.startActionMode(multiSelectAction); actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1); final String title = getString(R.string.number_selected, 1);
@ -226,7 +245,7 @@ public class LocationFragment extends Fragment {
private void fetchLocationModel() { private void fetchLocationModel() {
stopCurrentExecutor(); stopCurrentExecutor();
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new LocationFetcher(location.split("/")[0], result -> { currentlyExecuting = new LocationFetcher(locationId, result -> {
locationModel = result; locationModel = result;
binding.swipeRefreshLayout.setRefreshing(false); binding.swipeRefreshLayout.setRefreshing(false);
if (locationModel == null) { if (locationModel == null) {
@ -243,16 +262,24 @@ public class LocationFragment extends Fragment {
final String locationId = locationModel.getId(); final String locationId = locationModel.getId();
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
if (isLoggedIn) { if (isLoggedIn) {
new iStoryStatusFetcher(locationId.split("/")[0], null, true, false, false, false, stories -> { new iStoryStatusFetcher(
storyModels = stories; locationId,
if (stories != null && stories.length > 0) { null,
binding.mainLocationImage.setStoriesBorder(); true,
} false,
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); false,
false,
stories -> {
storyModels = stories;
if (stories != null && stories.length > 0) {
binding.mainLocationImage.setStoriesBorder();
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
binding.mainLocationImage.setImageURI(locationModel.getSdProfilePic()); binding.mainLocationImage.setImageURI(locationModel.getSdProfilePic());
final String postCount = String.valueOf(locationModel.getPostCount()); 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 RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
binding.mainLocPostCount.setText(span); binding.mainLocPostCount.setText(span);
@ -301,7 +328,7 @@ public class LocationFragment extends Fragment {
private void fetchPosts() { private void fetchPosts() {
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(locationModel.getId(), endCursor, postsFetchListener) currentlyExecuting = new PostsFetcher(locationModel.getId(), true, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -310,8 +337,8 @@ public class LocationFragment extends Fragment {
try { try {
currentlyExecuting.cancel(true); currentlyExecuting.cancel(true);
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null) logCollector.appendException(
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e); 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.core.view.GestureDetectorCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.backends.pipeline.Fresco;
@ -57,7 +59,6 @@ import java.util.List;
import awais.instagrabber.BuildConfig; import awais.instagrabber.BuildConfig;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.StoriesAdapter; import awais.instagrabber.adapters.StoriesAdapter;
import awais.instagrabber.asyncs.CommentAction; import awais.instagrabber.asyncs.CommentAction;
import awais.instagrabber.asyncs.DownloadAsync; 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.fragments.main.viewmodels.StoriesViewModel;
import awais.instagrabber.interfaces.SwipeEvent; import awais.instagrabber.interfaces.SwipeEvent;
import awais.instagrabber.models.FeedStoryModel; import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.stickers.PollModel; import awais.instagrabber.models.stickers.PollModel;
@ -121,6 +121,7 @@ public class StoryViewerFragment extends Fragment {
private int currentFeedStoryIndex; private int currentFeedStoryIndex;
private StoriesViewModel storiesViewModel; private StoriesViewModel storiesViewModel;
private String currentStoryMediaId; private String currentStoryMediaId;
private boolean shouldRefresh = true;
private final String cookie = settingsHelper.getString(Constants.COOKIE); private final String cookie = settingsHelper.getString(Constants.COOKIE);
private StoryViewerFragmentArgs fragmentArgs; private StoryViewerFragmentArgs fragmentArgs;
@ -137,6 +138,7 @@ public class StoryViewerFragment extends Fragment {
@Override @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) { if (root != null) {
shouldRefresh = false;
return root; return root;
} }
binding = ActivityStoryViewerBinding.inflate(inflater, container, false); binding = ActivityStoryViewerBinding.inflate(inflater, container, false);
@ -146,6 +148,7 @@ public class StoryViewerFragment extends Fragment {
@Override @Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init(); init();
} }
@ -274,8 +277,8 @@ public class StoryViewerFragment extends Fragment {
return; return;
} }
final FeedStoryModel feedStoryModel = isRightSwipe final FeedStoryModel feedStoryModel = isRightSwipe
? feedStoryModels.get(index - 1) ? feedStoryModels.get(index - 1)
: feedStoryModels.size() == index + 1 ? null : feedStoryModels.get(index + 1); : feedStoryModels.size() == index + 1 ? null : feedStoryModels.get(index + 1);
if (feedStoryModel != null) { if (feedStoryModel != null) {
if (fetching) { if (fetching) {
Toast.makeText(requireContext(), R.string.be_patient, Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), R.string.be_patient, Toast.LENGTH_SHORT).show();
@ -324,8 +327,8 @@ public class StoryViewerFragment extends Fragment {
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ACTIVITY_STORY_VIEWER, "setupListeners", logCollector.appendException(e, LogCollector.LogFile.ACTIVITY_STORY_VIEWER, "setupListeners",
new Pair<>("swipeEvent", swipeEvent), new Pair<>("swipeEvent", swipeEvent),
new Pair<>("diffX", diffX)); new Pair<>("diffX", diffX));
if (BuildConfig.DEBUG) Log.e(TAG, "Error", e); if (BuildConfig.DEBUG) Log.e(TAG, "Error", e);
} }
return false; return false;
@ -342,9 +345,17 @@ public class StoryViewerFragment extends Fragment {
}); });
binding.viewStoryPost.setOnClickListener(v -> { binding.viewStoryPost.setOnClickListener(v -> {
final Object tag = v.getTag(); final Object tag = v.getTag();
if (tag instanceof CharSequence) if (!(tag instanceof CharSequence)) return;
startActivity(new Intent(requireContext(), PostViewer.class) final String postId = tag.toString();
.putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString(), tag.toString().matches("^[\\d]+$")))); 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 View.OnClickListener storyActionListener = v -> {
final Object tag = v.getTag(); final Object tag = v.getTag();
@ -352,10 +363,15 @@ public class StoryViewerFragment extends Fragment {
poll = (PollModel) tag; poll = (PollModel) tag;
if (poll.getMyChoice() > -1) { if (poll.getMyChoice() > -1) {
new AlertDialog.Builder(requireContext()).setTitle(R.string.voted_story_poll) new AlertDialog.Builder(requireContext()).setTitle(R.string.voted_story_poll)
.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, new String[]{ .setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1,
(poll.getMyChoice() == 0 ? "" : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")", new String[]{
(poll.getMyChoice() == 1 ? "" : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")" (poll.getMyChoice() == 0 ? "" : "") + poll
}), null) .getLeftChoice() + " (" + poll
.getLeftCount() + ")",
(poll.getMyChoice() == 1 ? "" : "") + poll
.getRightChoice() + " (" + poll
.getRightCount() + ")"
}), null)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.show(); .show();
} else { } else {
@ -567,13 +583,15 @@ public class StoryViewerFragment extends Fragment {
dir = new File(dir, currentStoryUsername); dir = new File(dir, currentStoryUsername);
if (dir.exists() || dir.mkdirs()) { 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() final File saveFile = new File(dir, currentStory.getStoryMediaId() + "_" + currentStory.getTimestamp()
+ Utils.getExtensionFromModel(storyUrl, currentStory)); + Utils.getExtensionFromModel(storyUrl, currentStory));
new DownloadAsync(requireContext(), storyUrl, saveFile, result -> { new DownloadAsync(requireContext(), storyUrl, saveFile, result -> {
final int toastRes = result != null && result.exists() ? R.string.downloader_complete final int toastRes = result != null && result.exists() ? R.string.downloader_complete
: R.string.downloader_error_download_file; : R.string.downloader_error_download_file;
Toast.makeText(requireContext(), toastRes, Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), toastRes, Toast.LENGTH_SHORT).show();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -598,8 +616,16 @@ public class StoryViewerFragment extends Fragment {
.setImageRequest(requestBuilder) .setImageRequest(requestBuilder)
.setOldController(binding.imageViewer.getController()) .setOldController(binding.imageViewer.getController())
.setControllerListener(new BaseControllerListener<ImageInfo>() { .setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override @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) { if (menuDownload != null) {
menuDownload.setVisible(true); menuDownload.setVisible(true);
} }
@ -627,7 +653,10 @@ public class StoryViewerFragment extends Fragment {
.createMediaSource(Uri.parse(url)); .createMediaSource(Uri.parse(url));
mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() { mediaSource.addEventListener(new Handler(), new MediaSourceEventListener() {
@Override @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 (menuDownload != null) menuDownload.setVisible(true);
if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie))
menuDm.setVisible(true); menuDm.setVisible(true);
@ -635,7 +664,10 @@ public class StoryViewerFragment extends Fragment {
} }
@Override @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 (menuDownload != null) menuDownload.setVisible(true);
if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie))
menuDm.setVisible(true); menuDm.setVisible(true);
@ -643,12 +675,20 @@ public class StoryViewerFragment extends Fragment {
} }
@Override @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); binding.progressView.setVisibility(View.GONE);
} }
@Override @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 (menuDownload != null) menuDownload.setVisible(false);
if (menuDm != null) menuDm.setVisible(false); if (menuDm != null) menuDm.setVisible(false);
binding.progressView.setVisibility(View.GONE); 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 AsyncTask<Void, Void, InboxModel> currentlyRunning;
private InboxThreadModelListViewModel listViewModel; private InboxThreadModelListViewModel listViewModel;
public static boolean refreshPlease = false; public static boolean refreshPlease = false;
private boolean shouldRefresh = true;
private final FetchListener<InboxModel> fetchListener = new FetchListener<InboxModel>() { private final FetchListener<InboxModel> fetchListener = new FetchListener<InboxModel>() {
@Override @Override
@ -89,6 +90,7 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
final ViewGroup container, final ViewGroup container,
final Bundle savedInstanceState) { final Bundle savedInstanceState) {
if (root != null) { if (root != null) {
shouldRefresh = false;
return root; return root;
} }
binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false); binding = FragmentDirectMessagesInboxBinding.inflate(inflater, container, false);
@ -99,16 +101,22 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
layoutManager = new LinearLayoutManager(requireContext()); layoutManager = new LinearLayoutManager(requireContext());
inboxList.setLayoutManager(layoutManager); inboxList.setLayoutManager(layoutManager);
final DirectMessageInboxAdapter inboxAdapter = new DirectMessageInboxAdapter(inboxThreadModel -> { 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); NavHostFragment.findNavController(this).navigate(action);
}); });
inboxList.setAdapter(inboxAdapter); inboxList.setAdapter(inboxAdapter);
listViewModel = new ViewModelProvider(this).get(InboxThreadModelListViewModel.class); listViewModel = new ViewModelProvider(this).get(InboxThreadModelListViewModel.class);
listViewModel.getList().observe(fragmentActivity, inboxAdapter::submitList); listViewModel.getList().observe(fragmentActivity, inboxAdapter::submitList);
initData();
return root; return root;
} }
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
initData();
}
@Override @Override
public void onRefresh() { public void onRefresh() {
endCursor = null; endCursor = null;
@ -130,7 +138,9 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
listViewModel.getList().postValue(Collections.emptyList()); if (listViewModel != null) {
listViewModel.getList().postValue(Collections.emptyList());
}
} }
private void initData() { private void initData() {

View File

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

View File

@ -1,6 +1,5 @@
package awais.instagrabber.fragments.main; package awais.instagrabber.fragments.main;
import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.ActionMode; import android.view.ActionMode;
@ -19,6 +18,8 @@ import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavDirections;
import androidx.navigation.fragment.NavHostFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -27,7 +28,6 @@ import java.util.List;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.DiscoverAdapter; import awais.instagrabber.adapters.DiscoverAdapter;
import awais.instagrabber.asyncs.DiscoverFetcher; import awais.instagrabber.asyncs.DiscoverFetcher;
import awais.instagrabber.asyncs.i.iTopicFetcher; 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.interfaces.FetchListener;
import awais.instagrabber.models.DiscoverItemModel; import awais.instagrabber.models.DiscoverItemModel;
import awais.instagrabber.models.DiscoverTopicModel; import awais.instagrabber.models.DiscoverTopicModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
public class DiscoverFragment extends Fragment { public class DiscoverFragment extends Fragment {
@ -134,9 +131,9 @@ public class DiscoverFragment extends Fragment {
if (item.getItemId() == R.id.action_download) { if (item.getItemId() == R.id.action_download) {
if (discoverAdapter == null) return false; if (discoverAdapter == null) return false;
Utils.batchDownload(requireContext(), Utils.batchDownload(requireContext(),
null, null,
DownloadMethod.DOWNLOAD_DISCOVER, DownloadMethod.DOWNLOAD_DISCOVER,
discoverAdapter.getSelectedModels()); discoverAdapter.getSelectedModels());
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
@ -183,7 +180,8 @@ public class DiscoverFragment extends Fragment {
binding.discoverSwipeRefreshLayout.setRefreshing(true); binding.discoverSwipeRefreshLayout.setRefreshing(true);
if (lazyLoader != null) lazyLoader.resetState(); if (lazyLoader != null) lazyLoader.resetState();
discoverItemViewModel.getList().postValue(Collections.emptyList()); 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; return;
} }
if (checkAndResetAction()) return; if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class) // startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position) // .putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.DISCOVER_ITEMS) // .putExtra(Constants.EXTRAS_TYPE, PostItemType.DISCOVER)
.putExtra(Constants.EXTRAS_POST, new PostModel(model.getShortCode(), false))); // .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) -> { }, (model, position) -> {
if (!discoverAdapter.isSelecting()) { if (!discoverAdapter.isSelecting()) {
checkAndResetAction(); checkAndResetAction();
@ -229,7 +242,8 @@ public class DiscoverFragment extends Fragment {
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (discoverHasMore) { if (discoverHasMore) {
binding.discoverSwipeRefreshLayout.setRefreshing(true); 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; discoverEndMaxId = null;
} }
}); });

View File

@ -37,7 +37,6 @@ import java.util.Map;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.CommentsViewer; import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.adapters.FeedAdapter; import awais.instagrabber.adapters.FeedAdapter;
import awais.instagrabber.adapters.FeedStoriesAdapter; import awais.instagrabber.adapters.FeedStoriesAdapter;
import awais.instagrabber.adapters.viewholder.feed.FeedItemViewHolder; 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.ProfileModel;
import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.ViewerPostModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.services.ServiceCallback;
import awais.instagrabber.services.StoriesService; import awais.instagrabber.services.StoriesService;
@ -70,7 +68,7 @@ public class FeedFragment extends Fragment {
private static final String TAG = "FeedFragment"; private static final String TAG = "FeedFragment";
private static final double MAX_VIDEO_HEIGHT = 0.9 * Utils.displayMetrics.heightPixels; private static final double MAX_VIDEO_HEIGHT = 0.9 * Utils.displayMetrics.heightPixels;
private static final int RESIZED_VIDEO_HEIGHT = (int) (0.8 * Utils.displayMetrics.heightPixels); private static final int 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 MainActivity fragmentActivity;
private CoordinatorLayout root; private CoordinatorLayout root;
@ -112,12 +110,16 @@ public class FeedFragment extends Fragment {
final FeedModel feedModel = thumbToFeedMap.get(thumbUri.toString()); final FeedModel feedModel = thumbToFeedMap.get(thumbUri.toString());
if (feedModel == null) return; if (feedModel == null) return;
int requiredWidth = Utils.displayMetrics.widthPixels; int requiredWidth = Utils.displayMetrics.widthPixels;
int resultingHeight = Utils.getResultingHeight(requiredWidth, encodedHeight, encodedWidth); int resultingHeight = Utils
if (feedModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO && resultingHeight >= MAX_VIDEO_HEIGHT) { .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, // If its a video and the height is too large, need to reduce the height,
// so that entire video fits on screen // so that entire video fits on screen
resultingHeight = RESIZED_VIDEO_HEIGHT; resultingHeight = RESIZED_VIDEO_HEIGHT;
requiredWidth = Utils.getResultingWidth(RESIZED_VIDEO_HEIGHT, resultingHeight, requiredWidth); requiredWidth = Utils.getResultingWidth(RESIZED_VIDEO_HEIGHT,
resultingHeight,
requiredWidth);
} }
feedModel.setImageWidth(requiredWidth); feedModel.setImageWidth(requiredWidth);
feedModel.setImageHeight(resultingHeight); feedModel.setImageHeight(resultingHeight);
@ -133,7 +135,9 @@ public class FeedFragment extends Fragment {
public void updateAdapter() { public void updateAdapter() {
if (failed + success != result.length) return; 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)); finalList.addAll(Arrays.asList(result));
feedViewModel.getList().postValue(finalList); feedViewModel.getList().postValue(finalList);
final PostModel feedPostModel = result[result.length - 1]; final PostModel feedPostModel = result[result.length - 1];
@ -147,7 +151,8 @@ public class FeedFragment extends Fragment {
}; };
for (final FeedModel feedModel : result) { 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()); ds.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
} }
} }
@ -159,7 +164,7 @@ public class FeedFragment extends Fragment {
return; return;
} }
if (isLocation) { if (isLocation) {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToLocationFragment(text); final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
return; return;
} }
@ -172,8 +177,7 @@ public class FeedFragment extends Fragment {
final FeedModel feedModel = (FeedModel) tag; final FeedModel feedModel = (FeedModel) tag;
if (v instanceof RamboTextView) { if (v instanceof RamboTextView) {
if (feedModel.isMentionClicked()) if (feedModel.isMentionClicked()) feedModel.toggleCaption();
feedModel.toggleCaption();
feedModel.setMentionClicked(false); feedModel.setMentionClicked(false);
if (!FeedItemViewHolder.expandCollapseTextView((RamboTextView) v, feedModel.getPostCaption())) if (!FeedItemViewHolder.expandCollapseTextView((RamboTextView) v, feedModel.getPostCaption()))
feedModel.toggleCaption(); feedModel.toggleCaption();
@ -184,16 +188,31 @@ public class FeedFragment extends Fragment {
switch (id) { switch (id) {
case R.id.btnComments: case R.id.btnComments:
startActivity(new Intent(requireContext(), CommentsViewer.class) startActivity(new Intent(requireContext(), CommentsViewer.class)
.putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode()) .putExtra(Constants.EXTRAS_SHORTCODE, feedModel.getShortCode())
.putExtra(Constants.EXTRAS_POST, feedModel.getPostId()) .putExtra(Constants.EXTRAS_POST, feedModel.getPostId())
.putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId())); .putExtra(Constants.EXTRAS_USER, feedModel.getProfileModel().getId()));
break; break;
case R.id.viewStoryPost: case R.id.viewStoryPost:
startActivity(new Intent(requireContext(), PostViewer.class) // startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition()) // .putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false)) // .putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS)); // .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; break;
case R.id.btnDownload: case R.id.btnDownload:
@ -202,8 +221,12 @@ public class FeedFragment extends Fragment {
final ViewerPostModel[] sliderItems = feedModel.getSliderItems(); final ViewerPostModel[] sliderItems = feedModel.getSliderItems();
if (feedModel.getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1) if (feedModel
Utils.batchDownload(requireContext(), username, DownloadMethod.DOWNLOAD_FEED, Collections.singletonList(feedModel)); .getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1)
Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_FEED,
Collections.singletonList(feedModel));
else { else {
final ArrayList<BasePostModel> postModels = new ArrayList<>(); final ArrayList<BasePostModel> postModels = new ArrayList<>();
final DialogInterface.OnClickListener clickListener1 = (dialog, which) -> { final DialogInterface.OnClickListener clickListener1 = (dialog, which) -> {
@ -213,8 +236,7 @@ public class FeedFragment extends Fragment {
for (final ViewerPostModel sliderItem : sliderItems) { for (final ViewerPostModel sliderItem : sliderItems) {
if (sliderItem != null) { if (sliderItem != null) {
if (!breakWhenFoundSelected) if (!breakWhenFoundSelected) postModels.add(sliderItem);
postModels.add(sliderItem);
else if (sliderItem.isSelected()) { else if (sliderItem.isSelected()) {
postModels.add(sliderItem); postModels.add(sliderItem);
break; 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 // 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]); postModels.add(sliderItems[0]);
}
if (postModels.size() > 0) if (postModels.size() > 0) {
Utils.batchDownload(requireContext(), username, DownloadMethod.DOWNLOAD_FEED, postModels); Utils.batchDownload(requireContext(),
username,
DownloadMethod.DOWNLOAD_FEED,
postModels);
}
}; };
new AlertDialog.Builder(requireContext()) new AlertDialog.Builder(requireContext())
.setTitle(R.string.post_viewer_download_dialog_title) .setTitle(R.string.post_viewer_download_dialog_title).setPositiveButton(
.setPositiveButton(R.string.post_viewer_download_current, clickListener1) R.string.post_viewer_download_current,
clickListener1)
.setNegativeButton(R.string.post_viewer_download_album, clickListener1) .setNegativeButton(R.string.post_viewer_download_album, clickListener1)
.show(); .show();
} }
@ -240,8 +267,7 @@ public class FeedFragment extends Fragment {
case R.id.ivProfilePic: case R.id.ivProfilePic:
profileModel = feedModel.getProfileModel(); profileModel = feedModel.getProfileModel();
if (profileModel != null) if (profileModel != null) mentionClickListener.onClick(null, profileModel.getUsername(), false, false);
mentionClickListener.onClick(null, profileModel.getUsername(), false, false);
break; break;
} }
}; };
@ -251,6 +277,7 @@ public class FeedFragment extends Fragment {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity(); fragmentActivity = (MainActivity) requireActivity();
storiesService = StoriesService.getInstance(); storiesService = StoriesService.getInstance();
// feedService = FeedService.getInstance();
} }
@Override @Override
@ -273,6 +300,7 @@ public class FeedFragment extends Fragment {
setupFeedStories(); setupFeedStories();
setupFeed(); setupFeed();
shouldRefresh = false; shouldRefresh = false;
// feedService.getFeed(11, null);
} }
@Override @Override
@ -315,17 +343,15 @@ public class FeedFragment extends Fragment {
private void fetchFeed() { private void fetchFeed() {
binding.feedSwipeRefreshLayout.setRefreshing(true); binding.feedSwipeRefreshLayout.setRefreshing(true);
new FeedFetcher(feedEndCursor, feedFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new FeedFetcher(feedEndCursor, feedFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
feedEndCursor = null; feedEndCursor = null;
} }
private void setupFeedStories() { private void setupFeedStories() {
final FeedStoriesViewModel feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class); final FeedStoriesViewModel feedStoriesViewModel = new ViewModelProvider(fragmentActivity).get(FeedStoriesViewModel.class);
final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter((model, position) -> { final FeedStoriesAdapter feedStoriesAdapter = new FeedStoriesAdapter((model, position) -> {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment( final NavDirections action = FeedFragmentDirections.actionFeedFragmentToStoryViewerFragment(position, null, false);
position,
null,
false);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
}); });
binding.feedStoriesRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)); 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.Collections;
import java.util.List; import java.util.List;
import awais.instagrabber.ProfileNavGraphDirections;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.FollowViewer; import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.activities.SavedViewer; import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HighlightsFetcher; import awais.instagrabber.asyncs.HighlightsFetcher;
@ -61,7 +61,6 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.ItemGetType;
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse; import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse; import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse;
import awais.instagrabber.services.FriendshipService; import awais.instagrabber.services.FriendshipService;
@ -97,8 +96,10 @@ public class ProfileFragment extends Fragment {
; ;
private final Runnable usernameSettingRunnable = () -> { private final Runnable usernameSettingRunnable = () -> {
final ActionBar actionBar = fragmentActivity.getSupportActionBar(); final ActionBar actionBar = fragmentActivity.getSupportActionBar();
if (actionBar != null) { if (actionBar != null && !Utils.isEmpty(username)) {
actionBar.setTitle(username.substring(1)); final String finalUsername = username.startsWith("@") ? username.substring(1)
: username;
actionBar.setTitle(finalUsername);
} }
}; };
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
@ -112,28 +113,35 @@ public class ProfileFragment extends Fragment {
remove(); 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,
@Override new CallbacksHelper() {
public void onDestroy(final ActionMode mode) { @Override
onBackPressedCallback.handleOnBackPressed(); public void onDestroy(
} final ActionMode mode) {
onBackPressedCallback
.handleOnBackPressed();
}
@Override @Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { public boolean onActionItemClicked(
if (item.getItemId() == R.id.action_download) { final ActionMode mode,
if (postsAdapter == null || username == null) { final MenuItem item) {
return false; if (item.getItemId() == R.id.action_download) {
} if (postsAdapter == null || username == null) {
Utils.batchDownload(requireContext(), return false;
username, }
DownloadMethod.DOWNLOAD_MAIN, Utils.batchDownload(
postsAdapter.getSelectedModels()); requireContext(),
checkAndResetAction(); username,
return true; DownloadMethod.DOWNLOAD_MAIN,
} postsAdapter
return false; .getSelectedModels());
} checkAndResetAction();
}); return true;
}
return false;
}
});
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() { private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override @Override
public void onResult(final PostModel[] result) { public void onResult(final PostModel[] result) {
@ -142,7 +150,8 @@ public class ProfileFragment extends Fragment {
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
// final int oldSize = mainActivity.allItems.size(); // final int oldSize = mainActivity.allItems.size();
final List<PostModel> postModels = postsViewModel.getList().getValue(); 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)); finalList.addAll(Arrays.asList(result));
postsViewModel.getList().postValue(finalList); postsViewModel.getList().postValue(finalList);
PostModel model = null; PostModel model = null;
@ -163,16 +172,19 @@ public class ProfileFragment extends Fragment {
private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> { private final MentionClickListener mentionClickListener = (view, text, isHashtag, isLocation) -> {
Log.d(TAG, "action..."); Log.d(TAG, "action...");
if (isHashtag) { if (isHashtag) {
final NavDirections action = ProfileFragmentDirections.actionGlobalHashTagFragment(text); final NavDirections action = ProfileFragmentDirections
.actionGlobalHashTagFragment(text);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
return; return;
} }
if (isLocation) { if (isLocation) {
final NavDirections action = FeedFragmentDirections.actionFeedFragmentToLocationFragment(text); final NavDirections action = FeedFragmentDirections.actionGlobalLocationFragment(text);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
return; return;
} }
final NavDirections action = ProfileFragmentDirections.actionGlobalProfileFragment("@" + text); final ProfileNavGraphDirections.ActionGlobalProfileFragment action = ProfileFragmentDirections
.actionGlobalProfileFragment();
action.setUsername("@" + text);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
}; };
@ -189,7 +201,8 @@ public class ProfileFragment extends Fragment {
final Bundle savedInstanceState) { final Bundle savedInstanceState) {
if (root != null) { if (root != null) {
if (getArguments() != null) { if (getArguments() != null) {
final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments()); final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs
.fromBundle(getArguments());
if (!fragmentArgs.getUsername().equals(username)) { if (!fragmentArgs.getUsername().equals(username)) {
shouldRefresh = true; shouldRefresh = true;
return root; return root;
@ -243,7 +256,7 @@ public class ProfileFragment extends Fragment {
private void fetchUsername() { private void fetchUsername() {
final String uid = Utils.getUserIdFromCookie(cookie); final String uid = Utils.getUserIdFromCookie(cookie);
if (username == null && uid != null) { if (Utils.isEmpty(username) && uid != null) {
final FetchListener<String> fetchListener = username -> { final FetchListener<String> fetchListener = username -> {
if (Utils.isEmpty(username)) return; if (Utils.isEmpty(username)) return;
this.username = username; this.username = username;
@ -251,21 +264,23 @@ public class ProfileFragment extends Fragment {
fetchProfileDetails(); fetchProfileDetails();
// adds cookies to database for quick access // adds cookies to database for quick access
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid); 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)); Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
}; };
boolean found = false; boolean found = false;
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid); final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
if (cookieModel != null) { if (cookieModel != null) {
final String username = cookieModel.getUsername(); final String username = cookieModel.getUsername();
if (username != null) { if (!Utils.isEmpty(username)) {
found = true; found = true;
fetchListener.onResult("@" + username); fetchListener.onResult("@" + username);
} }
} }
if (!found) { if (!found) {
// if not in database, fetch info from instagram // 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; return;
} }
@ -283,33 +298,34 @@ public class ProfileFragment extends Fragment {
private void setProfileDetails() { private void setProfileDetails() {
if (profileModel == null) { if (profileModel == null) {
binding.swipeRefreshLayout.setRefreshing(false); 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; return;
} }
binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE); binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
final String profileId = profileModel.getId(); final String profileId = profileModel.getId();
if (settingsHelper.getBoolean(Constants.STORIESIG)) { if (settingsHelper.getBoolean(Constants.STORIESIG)) {
new iStoryStatusFetcher( new iStoryStatusFetcher(profileId,
profileId, profileModel.getUsername(),
profileModel.getUsername(), false,
false, false,
false, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false,
false, result -> {
result -> { storyModels = result;
storyModels = result; if (result != null && result.length > 0) {
if (result != null && result.length > 0) { binding.mainProfileImage.setStoriesBorder();
binding.mainProfileImage.setStoriesBorder(); }
} }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> { new HighlightsFetcher(profileId,
if (result != null && result.length > 0) { (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
binding.highlightsList.setVisibility(View.VISIBLE); result -> {
// highlightsAdapter.setData(result); if (result != null && result.length > 0) {
} else binding.highlightsList.setVisibility(View.VISIBLE);
binding.highlightsList.setVisibility(View.GONE); // highlightsAdapter.setData(result);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } else binding.highlightsList.setVisibility(View.GONE);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
if (isLoggedIn) { if (isLoggedIn) {
@ -319,9 +335,10 @@ public class ProfileFragment extends Fragment {
binding.btnSaved.setVisibility(View.VISIBLE); binding.btnSaved.setVisibility(View.VISIBLE);
binding.btnLiked.setVisibility(View.VISIBLE); binding.btnLiked.setVisibility(View.VISIBLE);
binding.btnSaved.setText(R.string.saved); binding.btnSaved.setText(R.string.saved);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnSaved,
binding.btnSaved, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background))); requireContext(),
R.color.btn_orange_background)));
} else { } else {
binding.btnTagged.setVisibility(View.GONE); binding.btnTagged.setVisibility(View.GONE);
binding.btnSaved.setVisibility(View.GONE); binding.btnSaved.setVisibility(View.GONE);
@ -329,65 +346,75 @@ public class ProfileFragment extends Fragment {
binding.btnFollow.setVisibility(View.VISIBLE); binding.btnFollow.setVisibility(View.VISIBLE);
if (profileModel.getFollowing()) { if (profileModel.getFollowing()) {
binding.btnFollow.setText(R.string.unfollow); binding.btnFollow.setText(R.string.unfollow);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnFollow,
binding.btnFollow, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background))); requireContext(),
R.color.btn_purple_background)));
} else if (profileModel.getRequested()) { } else if (profileModel.getRequested()) {
binding.btnFollow.setText(R.string.cancel); binding.btnFollow.setText(R.string.cancel);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnFollow,
binding.btnFollow, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background))); requireContext(),
R.color.btn_purple_background)));
} else { } else {
binding.btnFollow.setText(R.string.follow); binding.btnFollow.setText(R.string.follow);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnFollow,
binding.btnFollow, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background))); requireContext(),
R.color.btn_pink_background)));
} }
binding.btnRestrict.setVisibility(View.VISIBLE); binding.btnRestrict.setVisibility(View.VISIBLE);
if (profileModel.getRestricted()) { if (profileModel.getRestricted()) {
binding.btnRestrict.setText(R.string.unrestrict); binding.btnRestrict.setText(R.string.unrestrict);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnRestrict,
binding.btnRestrict, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background))); requireContext(),
R.color.btn_green_background)));
} else { } else {
binding.btnRestrict.setText(R.string.restrict); binding.btnRestrict.setText(R.string.restrict);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnRestrict,
binding.btnRestrict, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background))); requireContext(),
R.color.btn_orange_background)));
} }
binding.btnBlock.setVisibility(View.VISIBLE); binding.btnBlock.setVisibility(View.VISIBLE);
binding.btnTagged.setVisibility(View.VISIBLE); binding.btnTagged.setVisibility(View.VISIBLE);
if (profileModel.getBlocked()) { if (profileModel.getBlocked()) {
binding.btnBlock.setText(R.string.unblock); binding.btnBlock.setText(R.string.unblock);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnBlock,
binding.btnBlock, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background))); requireContext(),
R.color.btn_green_background)));
} else { } else {
binding.btnBlock.setText(R.string.block); binding.btnBlock.setText(R.string.block);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnBlock,
binding.btnBlock, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_red_background))); requireContext(),
R.color.btn_red_background)));
} }
} }
} else { } else {
if (Utils.dataBox.getFavorite(username) != null) { if (Utils.dataBox.getFavorite(username) != null) {
binding.btnFollow.setText(R.string.unfavorite_short); binding.btnFollow.setText(R.string.unfavorite_short);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnFollow,
binding.btnFollow, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background))); requireContext(),
R.color.btn_purple_background)));
} else { } else {
binding.btnFollow.setText(R.string.favorite_short); binding.btnFollow.setText(R.string.favorite_short);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnFollow,
binding.btnFollow, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background))); requireContext(),
R.color.btn_pink_background)));
} }
binding.btnFollow.setVisibility(View.VISIBLE); binding.btnFollow.setVisibility(View.VISIBLE);
if (!profileModel.isReallyPrivate()) { if (!profileModel.isReallyPrivate()) {
binding.btnRestrict.setVisibility(View.VISIBLE); binding.btnRestrict.setVisibility(View.VISIBLE);
binding.btnRestrict.setText(R.string.tagged); binding.btnRestrict.setText(R.string.tagged);
ViewCompat.setBackgroundTintList( ViewCompat.setBackgroundTintList(binding.btnRestrict,
binding.btnRestrict, ColorStateList.valueOf(ContextCompat.getColor(
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_blue_background))); requireContext(),
R.color.btn_blue_background)));
} }
} }
@ -398,26 +425,30 @@ public class ProfileFragment extends Fragment {
final String postCount = String.valueOf(profileModel.getPostCount()); 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 RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
binding.mainPostCount.setText(span); binding.mainPostCount.setText(span);
final String followersCountStr = String.valueOf(followersCount); final String followersCountStr = String.valueOf(followersCount);
final int followersCountStrLen = followersCountStr.length(); 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 RelativeSizeSpan(1.2f), 0, followersCountStrLen, 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, followersCountStrLen, 0);
binding.mainFollowers.setText(span); binding.mainFollowers.setText(span);
final String followingCountStr = String.valueOf(followingCount); final String followingCountStr = String.valueOf(followingCount);
final int followingCountStrLen = followingCountStr.length(); 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 RelativeSizeSpan(1.2f), 0, followingCountStrLen, 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0); span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0);
binding.mainFollowing.setText(span); 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(); CharSequence biography = profileModel.getBiography();
binding.mainBiography.setCaptionIsExpandable(true); binding.mainBiography.setCaptionIsExpandable(true);
@ -447,13 +478,18 @@ public class ProfileFragment extends Fragment {
binding.mainFollowers.setClickable(true); binding.mainFollowers.setClickable(true);
if (isLoggedIn) { if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent(requireContext(), FollowViewer.class) final View.OnClickListener followClickListener = v -> startActivity(new Intent(
.putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers) requireContext(),
.putExtra(Constants.EXTRAS_NAME, profileModel.getUsername()) FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS,
.putExtra(Constants.EXTRAS_ID, profileId)); v == binding.mainFollowers)
.putExtra(Constants.EXTRAS_NAME,
profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
binding.mainFollowers.setOnClickListener(followersCount > 0 ? followClickListener : null); binding.mainFollowers
binding.mainFollowing.setOnClickListener(followingCount > 0 ? followClickListener : null); .setOnClickListener(followersCount > 0 ? followClickListener : null);
binding.mainFollowing
.setOnClickListener(followingCount > 0 ? followClickListener : null);
} }
if (profileModel.getPostCount() == 0) { if (profileModel.getPostCount() == 0) {
@ -481,137 +517,144 @@ public class ProfileFragment extends Fragment {
private void setupCommonListeners() { private void setupCommonListeners() {
final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); final String userIdFromCookie = Utils.getUserIdFromCookie(cookie);
final boolean isSelf = isLoggedIn final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null && userIdFromCookie
&& profileModel != null .equals(profileModel.getId());
&& userIdFromCookie != null
&& userIdFromCookie.equals(profileModel.getId());
final String favorite = Utils.dataBox.getFavorite(username); final String favorite = Utils.dataBox.getFavorite(username);
binding.btnFollow.setOnClickListener(v -> { binding.btnFollow.setOnClickListener(v -> {
if (!isLoggedIn) { if (!isLoggedIn) {
if (favorite != null && v == binding.btnFollow) { if (favorite != null && v == binding.btnFollow) {
Utils.dataBox.delFavorite( Utils.dataBox.delFavorite(new DataBox.FavoriteModel(username,
new DataBox.FavoriteModel(username, Long.parseLong(favorite.split(
Long.parseLong(favorite.split("/")[1]), "/")[1]),
username.replaceAll("^@", "") username.replaceAll("^@",
) "")));
);
} else if (v == binding.btnFollow) { } else if (v == binding.btnFollow) {
Utils.dataBox.addFavorite( Utils.dataBox.addFavorite(new DataBox.FavoriteModel(username,
new DataBox.FavoriteModel(username, System.currentTimeMillis(), System.currentTimeMillis(),
username.replaceAll("^@", ""))); username.replaceAll("^@",
"")));
} }
fetchProfileDetails(); fetchProfileDetails();
return; return;
} }
if (profileModel.getFollowing() || profileModel.getRequested()) { if (profileModel.getFollowing() || profileModel.getRequested()) {
friendshipService.unfollow( friendshipService.unfollow(userIdFromCookie,
userIdFromCookie, profileModel.getId(),
profileModel.getId(), Utils.getCsrfTokenFromCookie(cookie),
Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback<FriendshipRepoChangeRootResponse>() {
new ServiceCallback<FriendshipRepoChangeRootResponse>() { @Override
@Override public void onSuccess(final FriendshipRepoChangeRootResponse result) {
public void onSuccess(final FriendshipRepoChangeRootResponse result) { Log.d(TAG, "Unfollow success: " + result);
Log.d(TAG, "Unfollow success: " + result); fetchProfileDetails();
fetchProfileDetails(); }
}
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error unfollowing", t); Log.e(TAG, "Error unfollowing", t);
} }
}); });
} else { } else {
friendshipService.follow( friendshipService.follow(userIdFromCookie,
userIdFromCookie, profileModel.getId(),
profileModel.getId(), Utils.getCsrfTokenFromCookie(cookie),
Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback<FriendshipRepoChangeRootResponse>() {
new ServiceCallback<FriendshipRepoChangeRootResponse>() { @Override
@Override public void onSuccess(final FriendshipRepoChangeRootResponse result) {
public void onSuccess(final FriendshipRepoChangeRootResponse result) { Log.d(TAG, "Follow success: " + result);
Log.d(TAG, "Follow success: " + result); fetchProfileDetails();
fetchProfileDetails(); }
}
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error following", t); Log.e(TAG, "Error following", t);
} }
}); });
} }
}); });
binding.btnRestrict.setOnClickListener(v -> { binding.btnRestrict.setOnClickListener(v -> {
if (!isLoggedIn) return; if (!isLoggedIn) return;
final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict"; final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict";
friendshipService.toggleRestrict( friendshipService.toggleRestrict(profileModel.getId(),
profileModel.getId(), !profileModel.getRestricted(),
!profileModel.getRestricted(), Utils.getCsrfTokenFromCookie(cookie),
Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback<FriendshipRepoRestrictRootResponse>() {
new ServiceCallback<FriendshipRepoRestrictRootResponse>() { @Override
@Override public void onSuccess(final FriendshipRepoRestrictRootResponse result) {
public void onSuccess(final FriendshipRepoRestrictRootResponse result) { Log.d(TAG, action + " success: " + result);
Log.d(TAG, action + " success: " + result); fetchProfileDetails();
fetchProfileDetails(); }
}
@Override @Override
public void onFailure(final Throwable t) { 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 -> { binding.btnBlock.setOnClickListener(v -> {
if (!isLoggedIn) return; if (!isLoggedIn) return;
if (profileModel.getBlocked()) { if (profileModel.getBlocked()) {
friendshipService.unblock( friendshipService.unblock(userIdFromCookie,
userIdFromCookie, profileModel.getId(),
profileModel.getId(), Utils.getCsrfTokenFromCookie(cookie),
Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback<FriendshipRepoChangeRootResponse>() {
new ServiceCallback<FriendshipRepoChangeRootResponse>() { @Override
@Override public void onSuccess(final FriendshipRepoChangeRootResponse result) {
public void onSuccess(final FriendshipRepoChangeRootResponse result) { Log.d(TAG, "Unblock success: " + result);
Log.d(TAG, "Unblock success: " + result); fetchProfileDetails();
fetchProfileDetails(); }
}
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error unblocking", t); Log.e(TAG, "Error unblocking", t);
} }
}); });
return; return;
} }
friendshipService.block( friendshipService.block(userIdFromCookie,
userIdFromCookie, profileModel.getId(),
profileModel.getId(), Utils.getCsrfTokenFromCookie(cookie),
Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback<FriendshipRepoChangeRootResponse>() {
new ServiceCallback<FriendshipRepoChangeRootResponse>() { @Override
@Override public void onSuccess(final FriendshipRepoChangeRootResponse result) {
public void onSuccess(final FriendshipRepoChangeRootResponse result) { Log.d(TAG, "Block success: " + result);
Log.d(TAG, "Block success: " + result); fetchProfileDetails();
fetchProfileDetails(); }
}
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error blocking", t); Log.e(TAG, "Error blocking", t);
} }
}); });
}); });
binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class) binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(),
.putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId()) SavedViewer.class)
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_INDEX,
)); "$" + profileModel
binding.btnLiked.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class) .getId())
.putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId()) .putExtra(Constants.EXTRAS_USER,
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) "@" + 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) binding.btnTagged.setOnClickListener(v -> startActivity(new Intent(requireContext(),
.putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId()) SavedViewer.class)
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_INDEX,
)); "%" + profileModel
.getId())
.putExtra(Constants.EXTRAS_USER,
"@" + profileModel
.getUsername())));
} }
private void setUsernameDelayed() { private void setUsernameDelayed() {
@ -623,29 +666,48 @@ public class ProfileFragment extends Fragment {
private void setupPosts() { private void setupPosts() {
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class); 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.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
postsAdapter = new PostsAdapter((postModel, position) -> { postsAdapter = new PostsAdapter((postModel, position) -> {
if (postsAdapter.isSelecting()) { if (postsAdapter.isSelecting()) {
if (actionMode == null) return; 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); actionMode.setTitle(title);
return; return;
} }
if (checkAndResetAction()) return; if (checkAndResetAction()) return;
startActivity(new Intent(requireContext(), PostViewer.class) // startActivity(new Intent(requireContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_INDEX, position) // .putExtra(Constants.EXTRAS_INDEX, position)
.putExtra(Constants.EXTRAS_POST, postModel) // .putExtra(Constants.EXTRAS_POST, postModel)
.putExtra(Constants.EXTRAS_USER, username) // .putExtra(Constants.EXTRAS_USER, username)
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.MAIN_ITEMS)); // .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) -> { }, (model, position) -> {
if (!postsAdapter.isSelecting()) { if (!postsAdapter.isSelecting()) {
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher(); final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (onBackPressedDispatcher.hasEnabledCallbacks()) { if (onBackPressedDispatcher.hasEnabledCallbacks()) {
return true; return true;
} }
@ -657,18 +719,20 @@ public class ProfileFragment extends Fragment {
}); });
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter); binding.mainPosts.setAdapter(postsAdapter);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager,
if (!hasNextPage) return; (page, totalItemsCount) -> {
binding.swipeRefreshLayout.setRefreshing(true); if (!hasNextPage) return;
fetchPosts(); binding.swipeRefreshLayout
endCursor = null; .setRefreshing(true);
}); fetchPosts();
endCursor = null;
});
binding.mainPosts.addOnScrollListener(lazyLoader); binding.mainPosts.addOnScrollListener(lazyLoader);
} }
private void fetchPosts() { private void fetchPosts() {
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(profileModel.getId(), endCursor, postsFetchListener) currentlyExecuting = new PostsFetcher(profileModel.getId(), false, endCursor, postsFetchListener)
.setUsername(profileModel.getUsername()) .setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -678,15 +742,17 @@ public class ProfileFragment extends Fragment {
try { try {
currentlyExecuting.cancel(true); currentlyExecuting.cancel(true);
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null) logCollector.appendException(e,
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); LogCollector.LogFile.MAIN_HELPER,
"stopCurrentExecutor");
Log.e(TAG, "", e); Log.e(TAG, "", e);
} }
} }
} }
private boolean checkAndResetAction() { private boolean checkAndResetAction() {
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher(); final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) { if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
return false; 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; package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List; import java.util.List;
import awais.instagrabber.models.DiscoverItemModel; import awais.instagrabber.models.DiscoverItemModel;
public class DiscoverItemViewModel extends ViewModel { public class DiscoverItemViewModel extends BasePostViewModel<DiscoverItemModel> {
private MutableLiveData<List<DiscoverItemModel>> list; private MutableLiveData<List<DiscoverItemModel>> list;
public MutableLiveData<List<DiscoverItemModel>> getList() { public MutableLiveData<List<DiscoverItemModel>> getList() {

View File

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

View File

@ -1,13 +1,12 @@
package awais.instagrabber.fragments.main.viewmodels; package awais.instagrabber.fragments.main.viewmodels;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List; import java.util.List;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
public class PostsViewModel extends ViewModel { public class PostsViewModel extends BasePostViewModel<PostModel> {
private MutableLiveData<List<PostModel>> list; private MutableLiveData<List<PostModel>> list;
public MutableLiveData<List<PostModel>> getList() { 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 java.util.List;
import awais.instagrabber.models.BasePostModel; import awais.instagrabber.models.BasePostModel;
import awais.instagrabber.models.enums.ItemGetType; import awais.instagrabber.models.enums.PostItemType;
public interface ItemGetter extends Serializable { 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 (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
final BasePostModel that = (BasePostModel) o; final BasePostModel that = (BasePostModel) o;
return ObjectsCompat.equals(postId, that.postId); return ObjectsCompat.equals(postId, that.postId) && ObjectsCompat.equals(shortCode, that.shortCode);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return ObjectsCompat.hash(postId); return ObjectsCompat.hash(postId, shortCode);
} }
} }

View File

@ -1,26 +1,40 @@
package awais.instagrabber.models; package awais.instagrabber.models;
import org.json.JSONObject;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
public final class FeedModel extends PostModel { public final class FeedModel extends PostModel {
private final ProfileModel profileModel; private final ProfileModel profileModel;
private final long commentsCount, viewCount; private final long commentsCount;
private boolean captionExpanded = false, mentionClicked = false; private final long viewCount;
private final JSONObject location; private boolean captionExpanded = false;
private boolean mentionClicked = false;
private ViewerPostModel[] sliderItems; private ViewerPostModel[] sliderItems;
private int imageWidth; private int imageWidth;
private int imageHeight; private int imageHeight;
private String locationName;
private String locationId;
public FeedModel(final ProfileModel profileModel, final MediaItemType itemType, final long viewCount, final String postId, public FeedModel(final ProfileModel profileModel,
final String displayUrl, final String thumbnailUrl, final String shortCode, final String postCaption, final MediaItemType itemType,
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked, long likes, JSONObject location) { 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); super(itemType, postId, displayUrl, thumbnailUrl, shortCode, postCaption, timestamp, liked, bookmarked, likes);
this.profileModel = profileModel; this.profileModel = profileModel;
this.commentsCount = commentsCount; this.commentsCount = commentsCount;
this.viewCount = viewCount; this.viewCount = viewCount;
this.location = location; this.locationName = locationName;
this.locationId = locationId;
} }
public ProfileModel getProfileModel() { public ProfileModel getProfileModel() {
@ -39,10 +53,6 @@ public final class FeedModel extends PostModel {
return commentsCount; return commentsCount;
} }
public JSONObject getLocation() {
return location;
}
public boolean isCaptionExpanded() { public boolean isCaptionExpanded() {
return captionExpanded; return captionExpanded;
} }
@ -79,4 +89,20 @@ public final class FeedModel extends PostModel {
public int getImageHeight() { public int getImageHeight() {
return imageHeight; 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 { public final class LocationModel implements Serializable {
private final long postCount; 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, public LocationModel(final String id,
final String sdProfilePic, final long postCount, final String lat, final String lng) { final String slug,
this.id = id; // <- id + "/" + 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.name = name;
this.bio = bio; this.bio = bio;
this.url = url; this.url = url;
@ -22,6 +37,10 @@ public final class LocationModel implements Serializable {
return id; return id;
} }
public String getSlug() {
return slug;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -34,7 +53,7 @@ public final class LocationModel implements Serializable {
return url; 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() { public String getSdProfilePic() {
return sdProfilePic; 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); 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() { public boolean isPrivate() {
return isPrivate; return isPrivate;
} }

View File

@ -1,24 +1,34 @@
package awais.instagrabber.models; package awais.instagrabber.models;
import org.json.JSONObject;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
public final class ViewerPostModel extends BasePostModel { 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 final long videoViews;
protected String sliderDisplayUrl; protected String sliderDisplayUrl;
protected long commentsCount, likes; protected long commentsCount, likes;
private boolean isCurrentSlide = false; private boolean isCurrentSlide = false;
public ViewerPostModel(final MediaItemType itemType, final String postId, final String displayUrl, final String shortCode, public ViewerPostModel(final MediaItemType itemType,
final String postCaption, final String username, final long videoViews, final long timestamp, final String postId,
boolean liked, boolean bookmarked, long likes, final String locationName, final String location) { 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.itemType = itemType;
this.postId = postId; this.postId = postId;
this.displayUrl = displayUrl; this.displayUrl = displayUrl;
this.postCaption = postCaption; this.postCaption = postCaption;
this.username = username; this.profileModel = profileModel;
this.shortCode = shortCode; this.shortCode = shortCode;
this.videoViews = videoViews; this.videoViews = videoViews;
this.timestamp = timestamp; this.timestamp = timestamp;
@ -29,6 +39,10 @@ public final class ViewerPostModel extends BasePostModel {
this.location = location; 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() { public long getCommentsCount() {
return commentsCount; return commentsCount;
} }
@ -37,8 +51,8 @@ public final class ViewerPostModel extends BasePostModel {
return sliderDisplayUrl; return sliderDisplayUrl;
} }
public String getUsername() { public ProfileModel getProfileModel() {
return username; return profileModel;
} }
public String getLocationName() { 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 java.io.IOException;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody;
class LoggingInterceptor implements Interceptor { class LoggingInterceptor implements Interceptor {
private static final String TAG = "LoggingInterceptor"; private static final String TAG = "LoggingInterceptor";
@ -22,8 +24,12 @@ class LoggingInterceptor implements Interceptor {
request.url(), chain.connection(), request.headers())); request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request); Response response = chain.proceed(request);
long t2 = System.nanoTime(); long t2 = System.nanoTime();
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s\nbody: %s", Log.i(TAG, String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
response.request().url(), (t2 - t1) / 1e6d, response.headers(), response.body())); MediaType contentType = response.body().contentType();
return response; 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) if (Utils.settingsHelper == null)
Utils.settingsHelper = new SettingsHelper(baseContext); 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 == 1) return "en";
if (appLanguageIndex == 2) return "fr"; if (appLanguageIndex == 2) return "fr";
if (appLanguageIndex == 3) return "es"; 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_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal"
android:visibility="gone">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -77,7 +78,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
android:padding="4dp" android:padding="4dp"
android:visibility="visible" android:visibility="gone"
app:srcCompat="@drawable/ic_volume_up_24" app:srcCompat="@drawable/ic_volume_up_24"
app:tint="?android:textColorPrimary" /> app:tint="?android:textColorPrimary" />

View File

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

View File

@ -1,11 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android" <navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/discover_nav_graph" android:id="@+id/discover_nav_graph"
app:startDestination="@id/discoverFragment"> 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 <fragment
android:id="@+id/discoverFragment" android:id="@+id/discoverFragment"
android:name="awais.instagrabber.fragments.main.DiscoverFragment" android:name="awais.instagrabber.fragments.main.DiscoverFragment"
android:label="DiscoverFragment" /> android:label="DiscoverFragment"
tools:layout="@layout/fragment_discover" />
</navigation> </navigation>

View File

@ -24,9 +24,36 @@
<argument <argument
android:name="username" android:name="username"
app:argType="string" 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" /> app:nullable="false" />
</action> </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 <fragment
android:id="@+id/feedFragment" android:id="@+id/feedFragment"
android:name="awais.instagrabber.fragments.main.FeedFragment" android:name="awais.instagrabber.fragments.main.FeedFragment"
@ -35,9 +62,6 @@
<action <action
android:id="@+id/action_feedFragment_to_storyViewerFragment" android:id="@+id/action_feedFragment_to_storyViewerFragment"
app:destination="@id/storyViewerFragment" /> app:destination="@id/storyViewerFragment" />
<action
android:id="@+id/action_feedFragment_to_locationFragment"
app:destination="@id/locationFragment" />
</fragment> </fragment>
<fragment <fragment
android:id="@+id/storyViewerFragment" android:id="@+id/storyViewerFragment"
@ -56,14 +80,4 @@
android:name="isHashtag" android:name="isHashtag"
app:argType="boolean" /> app:argType="boolean" />
</fragment> </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> </navigation>

View File

@ -4,6 +4,21 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/hashtag_nav_graph" android:id="@+id/hashtag_nav_graph"
app:startDestination="@id/hashTagFragment"> 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 <fragment
android:id="@+id/hashTagFragment" android:id="@+id/hashTagFragment"
android:name="awais.instagrabber.fragments.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" /> app:nullable="false" />
</action> </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 <action
android:id="@+id/action_global_profileFragment" android:id="@+id/action_global_profileFragment"
app:destination="@id/profileFragment"> app:destination="@id/profileFragment">
<argument <argument
android:name="username" android:name="username"
android:defaultValue=""
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="false" />
</action> </action>
@ -29,13 +46,11 @@
android:id="@+id/profileFragment" android:id="@+id/profileFragment"
android:name="awais.instagrabber.fragments.main.ProfileFragment" android:name="awais.instagrabber.fragments.main.ProfileFragment"
android:label="@string/profile" android:label="@string/profile"
tools:layout="@layout/fragment_profile" > tools:layout="@layout/fragment_profile">
<argument <argument
android:name="username" android:name="username"
android:defaultValue=""
app:argType="string" app:argType="string"
app:nullable="false" /> app:nullable="true" />
<!--<action-->
<!-- android:id="@+id/action_profileFragment_self"-->
<!-- app:destination="@id/profileFragment" />-->
</fragment> </fragment>
</navigation> </navigation>