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

liked viewer

This commit is contained in:
Austin Huang 2020-08-04 22:18:38 -04:00
parent af458ce6c6
commit ecc1958a23
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
15 changed files with 312 additions and 65 deletions

View File

@ -9,11 +9,8 @@ android {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
// REMEMBER TO CHANGE versionCode AS WELL versionCode 39
// 16.7 is 32, 16.9 is 35 (34 is public beta) versionName '17.3'
versionCode 38
versionName '17.2'
multiDexEnabled true multiDexEnabled true

View File

@ -142,9 +142,10 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} }
hasNextPage = model.hasNextPage(); hasNextPage = model.hasNextPage();
if ((autoloadPosts && hasNextPage) && !isHashtag) if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(main.profileModel.getId(), endCursor, this) currentlyExecuting = new PostsFetcher(main.profileModel.getId(), endCursor, this)
.setUsername(main.profileModel.getUsername()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .setUsername((isLocation || isHashtag) ? null : main.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
main.mainBinding.swipeRefreshLayout.setRefreshing(false); main.mainBinding.swipeRefreshLayout.setRefreshing(false);
} }
@ -468,7 +469,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.swipeRefreshLayout.setRefreshing(true); main.mainBinding.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher((isHashtag || isLocation) ? main.userQuery : main.profileModel.getId(), endCursor, postsFetchListener) currentlyExecuting = new PostsFetcher((isHashtag || isLocation) ? main.userQuery : main.profileModel.getId(), endCursor, postsFetchListener)
.setUsername(isHashtag ? null : main.profileModel.getUsername()) .setUsername((isHashtag || isLocation) ? null : main.profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null; endCursor = null;
} }
@ -658,6 +659,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.btnRestrict.setVisibility(View.GONE); main.mainBinding.btnRestrict.setVisibility(View.GONE);
main.mainBinding.btnBlock.setVisibility(View.GONE); main.mainBinding.btnBlock.setVisibility(View.GONE);
main.mainBinding.btnSaved.setVisibility(View.GONE); main.mainBinding.btnSaved.setVisibility(View.GONE);
main.mainBinding.btnLiked.setVisibility(View.GONE);
main.mainBinding.btnTagged.setVisibility(View.GONE); main.mainBinding.btnTagged.setVisibility(View.GONE);
main.mainBinding.btnMap.setVisibility(View.GONE); main.mainBinding.btnMap.setVisibility(View.GONE);
@ -665,6 +667,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.btnRestrict.setOnClickListener(profileActionListener); main.mainBinding.btnRestrict.setOnClickListener(profileActionListener);
main.mainBinding.btnBlock.setOnClickListener(profileActionListener); main.mainBinding.btnBlock.setOnClickListener(profileActionListener);
main.mainBinding.btnSaved.setOnClickListener(profileActionListener); main.mainBinding.btnSaved.setOnClickListener(profileActionListener);
main.mainBinding.btnLiked.setOnClickListener(profileActionListener);
main.mainBinding.btnTagged.setOnClickListener(profileActionListener); main.mainBinding.btnTagged.setOnClickListener(profileActionListener);
main.mainBinding.btnFollowTag.setOnClickListener(profileActionListener); main.mainBinding.btnFollowTag.setOnClickListener(profileActionListener);
@ -794,6 +797,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (!profileId.equals(myId)) { if (!profileId.equals(myId)) {
main.mainBinding.btnTagged.setVisibility(View.GONE); main.mainBinding.btnTagged.setVisibility(View.GONE);
main.mainBinding.btnSaved.setVisibility(View.GONE); main.mainBinding.btnSaved.setVisibility(View.GONE);
main.mainBinding.btnLiked.setVisibility(View.GONE);
main.mainBinding.btnFollow.setVisibility(View.VISIBLE); main.mainBinding.btnFollow.setVisibility(View.VISIBLE);
if (profileModel.getFollowing() == true) { if (profileModel.getFollowing() == true) {
main.mainBinding.btnFollow.setText(R.string.unfollow); main.mainBinding.btnFollow.setText(R.string.unfollow);
@ -823,7 +827,6 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} }
if (profileModel.isReallyPrivate()) { if (profileModel.isReallyPrivate()) {
main.mainBinding.btnBlock.setVisibility(View.VISIBLE); main.mainBinding.btnBlock.setVisibility(View.VISIBLE);
main.mainBinding.btnSaved.setVisibility(View.GONE);
main.mainBinding.btnTagged.setVisibility(View.GONE); main.mainBinding.btnTagged.setVisibility(View.GONE);
if (profileModel.getBlocked() == true) { if (profileModel.getBlocked() == true) {
main.mainBinding.btnBlock.setText(R.string.unblock); main.mainBinding.btnBlock.setText(R.string.unblock);
@ -852,6 +855,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
else { else {
main.mainBinding.btnTagged.setVisibility(View.VISIBLE); main.mainBinding.btnTagged.setVisibility(View.VISIBLE);
main.mainBinding.btnSaved.setVisibility(View.VISIBLE); main.mainBinding.btnSaved.setVisibility(View.VISIBLE);
main.mainBinding.btnLiked.setVisibility(View.VISIBLE);
main.mainBinding.btnSaved.setText(R.string.saved); main.mainBinding.btnSaved.setText(R.string.saved);
main.mainBinding.btnSaved.setBackgroundTintList(ColorStateList.valueOf(resources.getColor( main.mainBinding.btnSaved.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(
R.color.btn_orange_background, null))); R.color.btn_orange_background, null)));
@ -1063,7 +1067,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
else { else {
main.mainBinding.swipeRefreshLayout.setRefreshing(true); main.mainBinding.swipeRefreshLayout.setRefreshing(true);
main.mainBinding.mainPosts.setVisibility(View.VISIBLE); main.mainBinding.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(locationModel.getName()) currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
@ -1231,6 +1235,11 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
.putExtra(Constants.EXTRAS_INDEX, "$"+main.profileModel.getId()) .putExtra(Constants.EXTRAS_INDEX, "$"+main.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername())
); );
} else if (v == main.mainBinding.btnLiked) {
main.startActivity(new Intent(main, SavedViewer.class)
.putExtra(Constants.EXTRAS_INDEX, "^"+main.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@"+main.profileModel.getUsername())
);
} }
} }
}; };

View File

@ -12,19 +12,15 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.io.DataOutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.adapters.NotificationsAdapter; import awais.instagrabber.adapters.NotificationsAdapter;
@ -32,6 +28,7 @@ import awais.instagrabber.asyncs.NotificationsFetcher;
import awais.instagrabber.databinding.ActivityNotificationBinding; import awais.instagrabber.databinding.ActivityNotificationBinding;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.models.NotificationModel; import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
@ -46,7 +43,7 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S
private String shortCode, postId, userId; private String shortCode, postId, userId;
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
private Resources resources; private Resources resources;
private InputMethodManager imm; String[] commentDialogList;
@Override @Override
protected void onCreate(@Nullable final Bundle savedInstanceState) { protected void onCreate(@Nullable final Bundle savedInstanceState) {
@ -90,9 +87,11 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> { final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
if (which == 0) if (which == 0)
searchUsername(notificationModel.getUsername()); searchUsername(notificationModel.getUsername());
else if (which == 1) else if (which == 1 && commentDialogList.length == 2)
startActivity(new Intent(getApplicationContext(), PostViewer.class) startActivity(new Intent(getApplicationContext(), PostViewer.class)
.putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode(), false))); .putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode(), false)));
else if (which == 1) new ProfileAction().execute("/approve/");
else if (which == 2) new ProfileAction().execute("/ignore/");
}; };
private final View.OnClickListener clickListener = v -> { private final View.OnClickListener clickListener = v -> {
@ -104,12 +103,16 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S
final SpannableString title = new SpannableString(username + ":\n" + notificationModel.getText()); final SpannableString title = new SpannableString(username + ":\n" + notificationModel.getText());
title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); title.setSpan(new RelativeSizeSpan(1.23f), 0, username.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
String[] commentDialogList;
if (notificationModel.getShortcode() != null) commentDialogList = new String[]{ if (notificationModel.getShortcode() != null) commentDialogList = new String[]{
resources.getString(R.string.open_profile), resources.getString(R.string.open_profile),
resources.getString(R.string.view_post) resources.getString(R.string.view_post)
}; };
else if (notificationModel.getType() == NotificationType.REQUEST)
commentDialogList = new String[]{
resources.getString(R.string.open_profile),
resources.getString(R.string.request_approve),
resources.getString(R.string.request_reject)
};
else commentDialogList = new String[]{ else commentDialogList = new String[]{
resources.getString(R.string.open_profile) resources.getString(R.string.open_profile)
}; };
@ -137,4 +140,37 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S
finish(); finish();
} }
} }
class ProfileAction extends AsyncTask<String, Void, Void> {
boolean ok = false;
String action;
protected Void doInBackground(String... rawAction) {
action = rawAction[0];
final String url = "https://www.instagram.com/web/friendships/"+notificationModel.getId()+action;
try {
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
urlConnection.setRequestProperty("x-csrftoken",
Utils.settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]);urlConnection.connect();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
ok = true;
}
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
urlConnection.disconnect();
} catch (Throwable ex) {
Log.e("austin_debug", action+": " + ex);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (ok == true) {
onRefresh();
}
}
}
} }

View File

@ -22,6 +22,7 @@ import awais.instagrabber.BuildConfig;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.PostsFetcher; import awais.instagrabber.asyncs.PostsFetcher;
import awais.instagrabber.asyncs.i.iLikedFetcher;
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
@ -73,9 +74,12 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
endCursor = model.getEndCursor(); endCursor = model.getEndCursor();
hasNextPage = model.hasNextPage(); hasNextPage = model.hasNextPage();
if (autoloadPosts && hasNextPage) if (autoloadPosts && hasNextPage && action.charAt(0) == '^')
currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(action, endCursor, this) currentlyExecuting = new PostsFetcher(action, endCursor, this)
.setUsername(username).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else { else {
savedBinding.swipeRefreshLayout.setRefreshing(false); savedBinding.swipeRefreshLayout.setRefreshing(false);
} }
@ -141,8 +145,10 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
if (!autoloadPosts && hasNextPage) { if (!autoloadPosts && hasNextPage) {
savedBinding.swipeRefreshLayout.setRefreshing(true); savedBinding.swipeRefreshLayout.setRefreshing(true);
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(action, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); currentlyExecuting = action.charAt(0) == '^'
? new iLikedFetcher(endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
: new PostsFetcher(action, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
endCursor = null; endCursor = null;
} }
}); });
@ -153,7 +159,8 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
return null; return null;
}; };
new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); if (action.charAt(0) == '^') new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@Override @Override
@ -191,7 +198,8 @@ public final class SavedViewer extends BaseLanguageActivity implements SwipeRefr
postsAdapter.notifyDataSetChanged(); postsAdapter.notifyDataSetChanged();
} }
savedBinding.swipeRefreshLayout.setRefreshing(true); savedBinding.swipeRefreshLayout.setRefreshing(true);
new PostsFetcher(action, postsFetchListener).setUsername(username).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); if (action.charAt(0) == '^') new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@Override @Override

View File

@ -153,6 +153,11 @@ public final class StoryViewer extends BaseLanguageActivity {
(index == 0 ? null : storyFeed[index - 1]) : (index == 0 ? null : storyFeed[index - 1]) :
(storyFeed.length == index + 1 ? null : storyFeed[index + 1]); (storyFeed.length == index + 1 ? null : storyFeed[index + 1]);
if (feedStoryModel != null) { if (feedStoryModel != null) {
boolean fetching = false;
if (fetching) {
Toast.makeText(getApplicationContext(), R.string.be_patient, Toast.LENGTH_SHORT).show();
} else {
fetching = true;
new iStoryStatusFetcher(feedStoryModel.getStoryMediaId(), null, false, false, result -> { new iStoryStatusFetcher(feedStoryModel.getStoryMediaId(), null, false, false, result -> {
if (result != null && result.length > 0) { if (result != null && result.length > 0) {
final Intent newIntent = new Intent(getApplicationContext(), StoryViewer.class) final Intent newIntent = new Intent(getApplicationContext(), StoryViewer.class)
@ -162,12 +167,13 @@ public final class StoryViewer extends BaseLanguageActivity {
.putExtra(Constants.FEED_ORDER, isRightSwipe ? (index - 1) : (index + 1)); .putExtra(Constants.FEED_ORDER, isRightSwipe ? (index - 1) : (index + 1));
newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(newIntent); startActivity(newIntent);
} } else
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
} }
}
else { else {
if (isRightSwipe) { if (isRightSwipe) {
if (--slidePos <= 0) slidePos = 0; if (--slidePos <= 0) slidePos = 0;

View File

@ -1,6 +1,7 @@
package awais.instagrabber.adapters; package awais.instagrabber.adapters;
import android.content.Context; import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -18,6 +19,7 @@ import java.util.ArrayList;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.adapters.viewholder.NotificationViewHolder; import awais.instagrabber.adapters.viewholder.NotificationViewHolder;
import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.models.NotificationModel; import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.utils.LocaleUtils; import awais.instagrabber.utils.LocaleUtils;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
@ -67,10 +69,15 @@ public final class NotificationsAdapter extends RecyclerView.Adapter<Notificatio
case FOLLOW: case FOLLOW:
text = R.string.follow_notif; text = R.string.follow_notif;
break; break;
case REQUEST:
text = R.string.request_notif;
subtext = notificationModel.getText();
break;
} }
holder.setCommment(text); holder.setCommment(text);
holder.setSubCommment(subtext); holder.setSubCommment(subtext);
if (notificationModel.getType() != NotificationType.REQUEST)
holder.setDate(notificationModel.getDateTime()); holder.setDate(notificationModel.getDateTime());
holder.setUsername(notificationModel.getUsername()); holder.setUsername(notificationModel.getUsername());

View File

@ -12,6 +12,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.NotificationModel; import awais.instagrabber.models.NotificationModel;
import awais.instagrabber.models.enums.NotificationType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.LocaleUtils; import awais.instagrabber.utils.LocaleUtils;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
@ -39,16 +40,18 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, Notificati
conn.connect(); conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
JSONObject data = new JSONObject(Utils.readFromConnection(conn)) JSONObject page = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject("user"),
.getJSONObject("graphql").getJSONObject("user").getJSONObject("activity_feed").getJSONObject("edge_web_activity_feed"); ewaf = page.getJSONObject("activity_feed").optJSONObject("edge_web_activity_feed"),
efr = page.optJSONObject("edge_follow_requests"),
data;
JSONArray media; JSONArray media;
if ((media = data.optJSONArray("edges")) != null && media.length() > 0 && int totalLength = 0, mediaLen = 0, reqLen = 0;
NotificationModel[] models = null, req = null;
if ((media = ewaf.optJSONArray("edges")) != null && media.length() > 0 &&
(data = media.optJSONObject(0).optJSONObject("node")) != null) { (data = media.optJSONObject(0).optJSONObject("node")) != null) {
mediaLen = media.length();
final int mediaLen = media.length(); models = new NotificationModel[mediaLen];
final NotificationModel[] models = new NotificationModel[mediaLen];
for (int i = 0; i < mediaLen; ++i) { for (int i = 0; i < mediaLen; ++i) {
data = media.optJSONObject(i).optJSONObject("node"); data = media.optJSONObject(i).optJSONObject("node");
if (Utils.getNotifType(data.getString("__typename")) == null) continue; if (Utils.getNotifType(data.getString("__typename")) == null) continue;
@ -61,8 +64,23 @@ public final class NotificationsFetcher extends AsyncTask<Void, Void, Notificati
!data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null, !data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null,
Utils.getNotifType(data.getString("__typename"))); Utils.getNotifType(data.getString("__typename")));
} }
result = models;
} }
if (efr != null && (media = efr.optJSONArray("edges")) != null && media.length() > 0 &&
(data = media.optJSONObject(0).optJSONObject("node")) != null) {
reqLen = media.length();
req = new NotificationModel[reqLen];
for (int i = 0; i < reqLen; ++i) {
data = media.optJSONObject(i).optJSONObject("node");
req[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID),
data.optString("full_name"), 0L, data.getString("username"),
data.getString("profile_pic_url"), null, null, NotificationType.REQUEST);
}
}
result = new NotificationModel[mediaLen + reqLen];
if (req != null) System.arraycopy(req, 0, result, 0, reqLen);
if (models != null) System.arraycopy(models, 0, result, reqLen, mediaLen);
} }
conn.disconnect(); conn.disconnect();

View File

@ -28,7 +28,7 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
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;
private String username; private String username = null;
public PostsFetcher(final String id, final FetchListener<PostModel[]> fetchListener) { public PostsFetcher(final String id, final FetchListener<PostModel[]> fetchListener) {
this.id = id; this.id = id;

View File

@ -0,0 +1,123 @@
package awais.instagrabber.asyncs.i;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
import static awais.instagrabber.utils.Utils.logCollector;
public final class iLikedFetcher extends AsyncTask<Void, Void, PostModel[]> {
private final String endCursor;
private final FetchListener<PostModel[]> fetchListener;
public iLikedFetcher(final FetchListener<PostModel[]> fetchListener) {
this.endCursor = "";
this.fetchListener = fetchListener;
}
public iLikedFetcher(final String endCursor, final FetchListener<PostModel[]> fetchListener) {
this.endCursor = endCursor == null ? "" : endCursor;
this.fetchListener = fetchListener;
}
@Override
protected PostModel[] doInBackground(final Void... voids) {
final String url = "https://i.instagram.com/api/v1/feed/liked/?max_id="+endCursor;
PostModel[] result = null;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setUseCaches(false);
conn.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject body = new JSONObject(Utils.readFromConnection(conn));
final String endCursor;
final boolean hasNextPage;
if (body.has("more_available")) {
hasNextPage = body.optBoolean("more_available");
endCursor = hasNextPage ? body.optString("next_max_id") : null;
} else {
hasNextPage = false;
endCursor = null;
}
final JSONArray edges = body.getJSONArray("items");
final PostModel[] models = new PostModel[edges.length()];
for (int i = 0; i < models.length; ++i) {
final JSONObject mediaNode = edges.getJSONObject(i);
final boolean isSlider = mediaNode.has("carousel_media_count");
final boolean isVideo = mediaNode.has("video_duration");
final MediaItemType itemType;
if (isSlider) itemType = MediaItemType.MEDIA_TYPE_SLIDER;
else if (isVideo) itemType = MediaItemType.MEDIA_TYPE_VIDEO;
else itemType = MediaItemType.MEDIA_TYPE_IMAGE;
models[i] = new PostModel(itemType, mediaNode.getString(Constants.EXTRAS_ID),
isSlider
? Utils.getHighQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0))
: Utils.getHighQualityImage(mediaNode),
isSlider
? Utils.getLowQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0))
: Utils.getLowQualityImage(mediaNode),
mediaNode.getString("code"),
mediaNode.isNull("caption") ? null : mediaNode.getJSONObject("caption").optString("text"),
mediaNode.getLong("taken_at"), true,
mediaNode.optBoolean("has_viewer_saved"), mediaNode.getLong("like_count"));
String username = mediaNode.getJSONObject("user").getString("username");
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
File customDir = null;
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH +
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
}
Utils.checkExistence(downloadDir, customDir, isSlider, models[i]);
}
if (models[models.length - 1] != null)
models[models.length - 1].setPageCursor(hasNextPage, endCursor);
result = models;
}
conn.disconnect();
} catch (Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.ASYNC_MAIN_POSTS_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return result;
}
@Override
protected void onPostExecute(final PostModel[] postModels) {
if (fetchListener != null) fetchListener.onResult(postModels);
}
}

View File

@ -79,7 +79,7 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
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) ? 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,
@ -106,7 +106,7 @@ public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
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) ? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false)
: Utils.getHighQualityImage(node), : Utils.getHighQualityImage(node),
media.getString("code"), media.getString("code"),
postCaption, postCaption,

View File

@ -50,9 +50,9 @@ public final class iStoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[
conn.connect(); conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
JSONObject data = (isLoc || isHashtag) JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject((isLoc || isHashtag) ? "story" : "reels");
? new JSONObject(Utils.readFromConnection(conn)).getJSONObject("story") if (!isLoc && !isHashtag && data.isNull(id)) return null;
: new JSONObject(Utils.readFromConnection(conn)).getJSONObject("reels").getJSONObject(id); else if (!isLoc && !isHashtag) data = data.getJSONObject(id);
JSONArray media; JSONArray media;
if ((media = data.optJSONArray("items")) != null && media.length() > 0 && if ((media = data.optJSONArray("items")) != null && media.length() > 0 &&
@ -73,7 +73,7 @@ public final class iStoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[
final JSONArray videoResources = data.optJSONArray("video_versions"); final JSONArray videoResources = data.optJSONArray("video_versions");
if (isVideo && videoResources != null) if (isVideo && videoResources != null)
models[i].setVideoUrl(Utils.getHighQualityPost(videoResources, true, true)); models[i].setVideoUrl(Utils.getHighQualityPost(videoResources, true, true, false));
if (data.has("story_feed_media")) { if (data.has("story_feed_media")) {
models[i].setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id")); models[i].setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));

View File

@ -6,5 +6,6 @@ public enum NotificationType implements Serializable {
LIKE, LIKE,
FOLLOW, FOLLOW,
COMMENT, COMMENT,
MENTION MENTION,
REQUEST
} }

View File

@ -262,13 +262,13 @@ public final class Utils {
// isI: true if the content was requested from i.instagram.com instead of graphql // isI: true if the content was requested from i.instagram.com instead of graphql
@Nullable @Nullable
public static String getHighQualityPost(final JSONArray resources, final boolean isVideo, final boolean isI) { public static String getHighQualityPost(final JSONArray resources, final boolean isVideo, final boolean isI, final boolean low) {
try { try {
final int resourcesLen = resources.length(); final int resourcesLen = resources.length();
final String[] sources = new String[resourcesLen]; final String[] sources = new String[resourcesLen];
int lastResMain = 0, lastIndexMain = -1; int lastResMain = low ? 1000000 : 0, lastIndexMain = -1;
int lastResBase = 0, lastIndexBase = -1; int lastResBase = low ? 1000000 : 0, lastIndexBase = -1;
for (int i = 0; i < resourcesLen; ++i) { for (int i = 0; i < resourcesLen; ++i) {
final JSONObject item = resources.getJSONObject(i); final JSONObject item = resources.getJSONObject(i);
if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE) || isI)) { if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE) || isI)) {
@ -278,12 +278,20 @@ public final class Utils {
final String profile = isVideo ? item.optString(Constants.EXTRAS_PROFILE) : null; final String profile = isVideo ? item.optString(Constants.EXTRAS_PROFILE) : null;
if (!isVideo || "MAIN".equals(profile)) { if (!isVideo || "MAIN".equals(profile)) {
if (currRes > lastResMain) { if (currRes > lastResMain && !low) {
lastResMain = currRes;
lastIndexMain = i;
}
else if (currRes < lastResMain && low) {
lastResMain = currRes; lastResMain = currRes;
lastIndexMain = i; lastIndexMain = i;
} }
} else { } else {
if (currRes > lastResBase) { if (currRes > lastResBase && !low) {
lastResBase = currRes;
lastIndexBase = i;
}
else if (currRes < lastResBase && low) {
lastResBase = currRes; lastResBase = currRes;
lastIndexBase = i; lastIndexBase = i;
} }
@ -306,9 +314,9 @@ public final class Utils {
public static String getHighQualityImage(final JSONObject resources) { public static String getHighQualityImage(final JSONObject resources) {
String src = null; String src = null;
try { try {
if (resources.has("display_resources")) src = getHighQualityPost(resources.getJSONArray("display_resources"), false, false); if (resources.has("display_resources")) src = getHighQualityPost(resources.getJSONArray("display_resources"), false, false, false);
else if (resources.has("image_versions2")) else if (resources.has("image_versions2"))
src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true); src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, false);
if (src == null) return resources.getString("display_url"); if (src == null) return resources.getString("display_url");
} catch (final Exception e) { } catch (final Exception e) {
if (logCollector != null) if (logCollector != null)
@ -319,6 +327,19 @@ public final class Utils {
return src; return src;
} }
public static String getLowQualityImage(final JSONObject resources) {
String src = null;
try {
src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, true);
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.UTILS, "getLowQualityImage",
new Pair<>("resourcesNull", resources == null));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return src;
}
public static String getItemThumbnail(@NonNull final JSONArray jsonArray) { public static String getItemThumbnail(@NonNull final JSONArray jsonArray) {
String thumbnail = null; String thumbnail = null;
final int imageResLen = jsonArray.length(); final int imageResLen = jsonArray.length();
@ -1195,7 +1216,7 @@ public final class Utils {
data.getLong("taken_at_timestamp"), data.getJSONObject("owner").getString("username")); data.getLong("taken_at_timestamp"), data.getJSONObject("owner").getString("username"));
if (isVideo && data.has("video_resources")) if (isVideo && data.has("video_resources"))
storyModels[j].setVideoUrl(Utils.getHighQualityPost(data.getJSONArray("video_resources"), true, false)); storyModels[j].setVideoUrl(Utils.getHighQualityPost(data.getJSONArray("video_resources"), true, false, false));
if (!data.isNull("story_app_attribution")) if (!data.isNull("story_app_attribution"))
storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]); storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);

View File

@ -118,7 +118,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="2dp" android:layout_marginEnd="1dp"
android:layout_marginStart="1dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/follow" android:text="@string/follow"
@ -148,7 +149,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginEnd="2dp" android:layout_marginEnd="1dp"
android:layout_marginStart="1dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/block" android:text="@string/block"
@ -169,7 +171,8 @@
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_marginLeft="8dp"
android:layout_marginStart="2dp" android:layout_marginEnd="1dp"
android:layout_marginStart="1dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/tagged" android:text="@string/tagged"
@ -193,6 +196,20 @@
android:textSize="16sp" android:textSize="16sp"
app:backgroundTint="@color/btn_orange_background" app:backgroundTint="@color/btn_orange_background"
android:visibility="gone" /> android:visibility="gone" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnLiked"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginEnd="1dp"
android:layout_marginStart="1dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:text="@string/liked"
android:textColor="@color/btn_lightpink_text_color"
android:textSize="16sp"
app:backgroundTint="@color/btn_lightpink_background"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -61,6 +61,7 @@
<string name="post_viewer_download_album">Whole Album</string> <string name="post_viewer_download_album">Whole Album</string>
<string name="show_stories">Show stories</string> <string name="show_stories">Show stories</string>
<string name="no_more_stories">No more stories!</string> <string name="no_more_stories">No more stories!</string>
<string name="be_patient">Be patient!</string>
<string name="view_story_post">View Post</string> <string name="view_story_post">View Post</string>
<string name="view_post">View Post</string> <string name="view_post">View Post</string>
<string name="spotify">Spotify</string> <string name="spotify">Spotify</string>
@ -193,6 +194,9 @@
<string name="comment_notif">Commented on your post:</string> <string name="comment_notif">Commented on your post:</string>
<string name="follow_notif">Started following you</string> <string name="follow_notif">Started following you</string>
<string name="mention_notif">Mentioned you:</string> <string name="mention_notif">Mentioned you:</string>
<string name="request_notif">Requested following you</string>
<string name="request_approve">Approve request</string>
<string name="request_reject">Reject request</string>
<string name="share_public_post">Share this public post to...</string> <string name="share_public_post">Share this public post to...</string>
<string name="share_private_post">This is a private post! Share to those who can view them!</string> <string name="share_private_post">This is a private post! Share to those who can view them!</string>