1
0
mirror of https://github.com/KokaKiwi/BarInsta synced 2024-11-22 06:37:30 +00:00

Merge remote-tracking branch 'origin/dm-notifications-enhancements' into dm-notifications-enhancements

This commit is contained in:
Ammar Githam 2021-02-28 01:13:47 +09:00
commit e4741d3f7c
22 changed files with 260 additions and 229 deletions

View File

@ -11,7 +11,7 @@ android {
targetSdkVersion 29 targetSdkVersion 29
versionCode 58 versionCode 58
versionName '19.1.0' versionName '19.1.0-a1'
multiDexEnabled true multiDexEnabled true
@ -56,13 +56,13 @@ configurations.all {
} }
dependencies { dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
def appcompat_version = "1.2.0" def appcompat_version = "1.2.0"
def nav_version = '2.3.2' def nav_version = '2.3.3'
def exoplayer_version = '2.12.0' def exoplayer_version = '2.12.0'
implementation 'com.google.android.material:material:1.3.0-rc01' implementation 'com.google.android.material:material:1.4.0-alpha01'
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version" implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer_version" implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer_version"
@ -70,14 +70,14 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appcompat_version" implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.appcompat:appcompat-resources:$appcompat_version" implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
implementation "androidx.recyclerview:recyclerview:1.2.0-beta01" implementation "androidx.recyclerview:recyclerview:1.2.0-beta02"
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation "androidx.viewpager2:viewpager2:1.0.0" implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version"
implementation "androidx.constraintlayout:constraintlayout:2.0.4" implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.preference:preference:1.1.1" implementation "androidx.preference:preference:1.1.1"
implementation "androidx.work:work-runtime:2.4.0" implementation "androidx.work:work-runtime:2.5.0"
implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.palette:palette:1.0.0'
implementation 'com.google.guava:guava:27.0.1-android' implementation 'com.google.guava:guava:27.0.1-android'
@ -89,10 +89,10 @@ dependencies {
annotationProcessor "androidx.room:room-compiler:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version"
// CameraX // CameraX
def camerax_version = "1.0.0-rc01" def camerax_version = "1.0.0-alpha02"
implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha20" implementation "androidx.camera:camera-view:1.0.0-alpha22"
// EmojiCompat // EmojiCompat
def emoji_compat_version = "1.1.0" def emoji_compat_version = "1.1.0"

View File

@ -115,7 +115,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
owner.getString("profile_pic_url"), owner.getString("profile_pic_url"),
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
false, false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null); false, false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null);
final JSONObject likedBy = childComment.optJSONObject("edge_liked_by"); final JSONObject likedBy = childComment.optJSONObject("edge_liked_by");
commentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID), commentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),
childComment.getString("text"), childComment.getString("text"),
@ -193,7 +193,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
owner.optBoolean("is_verified"), owner.optBoolean("is_verified"),
false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null); false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null);
final JSONObject likedBy = comment.optJSONObject("edge_liked_by"); final JSONObject likedBy = comment.optJSONObject("edge_liked_by");
final String commentId = comment.getString(Constants.EXTRAS_ID); final String commentId = comment.getString(Constants.EXTRAS_ID);
final CommentModel commentModel = new CommentModel(commentId, final CommentModel commentModel = new CommentModel(commentId,
@ -235,7 +235,7 @@ public final class CommentsFetcher extends AsyncTask<Void, Void, List<CommentMod
null, null,
new FriendshipStatus(false, false, false, false, false, false, false, false, false, false), new FriendshipStatus(false, false, false, false, false, false, false, false, false, false),
tempJsonObject.optBoolean("is_verified"), false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, tempJsonObject.optBoolean("is_verified"), false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0,
null); null, null);
tempJsonObject = childComment.optJSONObject("edge_liked_by"); tempJsonObject = childComment.optJSONObject("edge_liked_by");
childCommentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID), childCommentModels.add(new CommentModel(childComment.getString(Constants.EXTRAS_ID),

View File

@ -3,77 +3,78 @@ package awais.instagrabber.asyncs;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
import org.json.JSONObject; import androidx.annotation.NonNull;
import java.io.DataOutputStream; import java.io.IOException;
import java.net.HttpURLConnection; import java.util.Collections;
import java.net.URL; import java.util.Locale;
import awais.instagrabber.repositories.responses.directmessages.DirectThread;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.CookieUtils;
import awais.instagrabber.utils.NetworkUtils;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awais.instagrabber.webservices.DirectMessagesService;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static awais.instagrabber.utils.Utils.settingsHelper; public class CreateThreadAction extends AsyncTask<Void, Void, Void> {
public class CreateThreadAction extends AsyncTask<Void, Void, String> {
private static final String TAG = "CommentAction"; private static final String TAG = "CommentAction";
private final String cookie; private final String cookie;
private final long userId; private final long userId;
private final OnTaskCompleteListener onTaskCompleteListener; private final OnTaskCompleteListener onTaskCompleteListener;
private final DirectMessagesService directMessagesService;
public CreateThreadAction(final String cookie, final long userId, final OnTaskCompleteListener onTaskCompleteListener) { public CreateThreadAction(final String cookie, final long userId, final OnTaskCompleteListener onTaskCompleteListener) {
this.cookie = cookie; this.cookie = cookie;
this.userId = userId; this.userId = userId;
this.onTaskCompleteListener = onTaskCompleteListener; this.onTaskCompleteListener = onTaskCompleteListener;
directMessagesService = DirectMessagesService.getInstance(CookieUtils.getCsrfTokenFromCookie(cookie),
CookieUtils.getUserIdFromCookie(cookie),
Utils.settingsHelper.getString(Constants.DEVICE_UUID));
} }
protected String doInBackground(Void... lmao) { protected Void doInBackground(Void... lmao) {
final String url = "https://i.instagram.com/api/v1/direct_v2/create_group_thread/"; final Call<DirectThread> createThreadRequest = directMessagesService.createThread(Collections.singletonList(userId), null);
HttpURLConnection urlConnection = null; createThreadRequest.enqueue(new Callback<DirectThread>() {
try { @Override
urlConnection = (HttpURLConnection) new URL(url).openConnection(); public void onResponse(@NonNull final Call<DirectThread> call, @NonNull final Response<DirectThread> response) {
urlConnection.setRequestMethod("POST"); if (!response.isSuccessful()) {
urlConnection.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.APP_UA)); if (response.errorBody() != null) {
urlConnection.setUseCaches(false); try {
final String urlParameters = Utils.sign("{\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0] final String string = response.errorBody().string();
+ "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie) final String msg = String.format(Locale.US,
+ "\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID) "onResponse: url: %s, responseCode: %d, errorBody: %s",
+ "\",\"recipient_users\":\"[" + userId // <- string of array of number (not joking) call.request().url().toString(),
+ "]\"}"); response.code(),
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); string);
if (urlParameters != null) { Log.e(TAG, msg);
urlConnection.setRequestProperty("Content-Length", "" + urlParameters.getBytes().length); } catch (IOException e) {
Log.e(TAG, "onResponse: ", e);
}
}
Log.e(TAG, "onResponse: request was not successful and response error body was null");
}
onTaskCompleteListener.onTaskComplete(response.body());
if (response.body() == null) {
Log.e(TAG, "onResponse: thread is null");
}
} }
urlConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); @Override
wr.writeBytes(urlParameters); public void onFailure(@NonNull final Call<DirectThread> call, @NonNull final Throwable t) {
wr.flush(); onTaskCompleteListener.onTaskComplete(null);
wr.close();
urlConnection.connect();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
return new JSONObject(NetworkUtils.readFromConnection(urlConnection)).getString("thread_id");
} }
} catch (Throwable ex) { });
Log.e(TAG, "reply (CT): " + ex);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null; return null;
} }
@Override // @Override
protected void onPostExecute(final String threadId) { // protected void onPostExecute() {
if (threadId == null || onTaskCompleteListener == null) { // }
return;
}
onTaskCompleteListener.onTaskComplete(threadId);
}
public interface OnTaskCompleteListener { public interface OnTaskCompleteListener {
void onTaskComplete(final String threadId); void onTaskComplete(final DirectThread thread);
} }
} }

View File

@ -5,9 +5,6 @@ import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.repositories.responses.FriendshipStatus; import awais.instagrabber.repositories.responses.FriendshipStatus;
import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.User;
@ -15,7 +12,7 @@ import awais.instagrabber.webservices.GraphQLService;
import awais.instagrabber.webservices.ServiceCallback; import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.UserService; import awais.instagrabber.webservices.UserService;
public final class ProfileFetcher extends AsyncTask<Void, Void, String> { public final class ProfileFetcher extends AsyncTask<Void, Void, Void> {
private static final String TAG = ProfileFetcher.class.getSimpleName(); private static final String TAG = ProfileFetcher.class.getSimpleName();
private final UserService userService; private final UserService userService;
private final GraphQLService graphQLService; private final GraphQLService graphQLService;
@ -36,12 +33,11 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, String> {
@Nullable @Nullable
@Override @Override
protected String doInBackground(final Void... voids) { protected Void doInBackground(final Void... voids) {
if (isLoggedIn) { if (isLoggedIn) {
userService.getUsernameInfo(userName, new ServiceCallback<User>() { userService.getUsernameInfo(userName, new ServiceCallback<User>() {
@Override @Override
public void onSuccess(final User user) { public void onSuccess(final User user) {
Log.d("austin_debug", user.getUsername() + " " + userName);
userService.getUserFriendship(user.getPk(), new ServiceCallback<FriendshipStatus>() { userService.getUserFriendship(user.getPk(), new ServiceCallback<FriendshipStatus>() {
@Override @Override
public void onSuccess(final FriendshipStatus status) { public void onSuccess(final FriendshipStatus status) {
@ -52,6 +48,7 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, String> {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error", t); Log.e(TAG, "Error", t);
fetchListener.onFailure(t);
} }
}); });
} }
@ -59,6 +56,7 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, String> {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error", t); Log.e(TAG, "Error", t);
fetchListener.onFailure(t);
} }
}); });
} }
@ -72,10 +70,11 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, String> {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error", t); Log.e(TAG, "Error", t);
fetchListener.onFailure(t);
} }
}); });
} }
return "yeah"; return null;
} }
@Override @Override

View File

@ -120,14 +120,17 @@ public class ProfilePicDialogFragment extends DialogFragment {
@Override @Override
public void onSuccess(final User result) { public void onSuccess(final User result) {
if (result != null) { if (result != null) {
setupPhoto(result.getProfilePicUrl()); setupPhoto(result.getHDProfilePicUrl());
} }
} }
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
final Context context = getContext(); final Context context = getContext();
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
getDialog().dismiss(); getDialog().dismiss();
} }
}); });

View File

@ -307,7 +307,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error deleting collection", t); Log.e(TAG, "Error deleting collection", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
}) })
@ -334,7 +337,10 @@ public class CollectionPostsFragment extends Fragment implements SwipeRefreshLay
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error editing collection", t); Log.e(TAG, "Error editing collection", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
}) })

View File

@ -371,7 +371,10 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error liking comment", t); Log.e(TAG, "Error liking comment", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
return; return;
@ -389,7 +392,10 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error unliking comment", t); Log.e(TAG, "Error unliking comment", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
break; break;
@ -411,7 +417,10 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error translating comment", t); Log.e(TAG, "Error translating comment", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
break; break;
@ -432,7 +441,10 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG, "Error deleting comment", t); Log.e(TAG, "Error deleting comment", t);
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); try {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
} }
}); });
break; break;

View File

@ -44,7 +44,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
private final ArrayList<FollowModel> followersModels = new ArrayList<>(); private final ArrayList<FollowModel> followersModels = new ArrayList<>();
private final ArrayList<FollowModel> allFollowing = new ArrayList<>(); private final ArrayList<FollowModel> allFollowing = new ArrayList<>();
private boolean moreAvailable = true, isFollowersList, isCompare = false, loading = false, shouldRefresh = true; private boolean moreAvailable = true, isFollowersList, isCompare = false, loading = false, shouldRefresh = true, searching = false;
private long profileId; private long profileId;
private String username; private String username;
private String namePost; private String namePost;
@ -65,7 +65,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
final ServiceCallback<FriendshipListFetchResponse> followingFetchCb = new ServiceCallback<FriendshipListFetchResponse>() { final ServiceCallback<FriendshipListFetchResponse> followingFetchCb = new ServiceCallback<FriendshipListFetchResponse>() {
@Override @Override
public void onSuccess(final FriendshipListFetchResponse result) { public void onSuccess(final FriendshipListFetchResponse result) {
if (result != null) { if (result != null && isCompare) {
followingModels.addAll(result.getItems()); followingModels.addAll(result.getItems());
if (!isFollowersList) followModels.addAll(result.getItems()); if (!isFollowersList) followModels.addAll(result.getItems());
if (result.isMoreAvailable()) { if (result.isMoreAvailable()) {
@ -78,7 +78,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
if (!isFollowersList) moreAvailable = false; if (!isFollowersList) moreAvailable = false;
showCompare(); showCompare();
} }
} else binding.swipeRefreshLayout.setRefreshing(false); } else if (isCompare) binding.swipeRefreshLayout.setRefreshing(false);
} }
@Override @Override
@ -94,7 +94,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
final ServiceCallback<FriendshipListFetchResponse> followersFetchCb = new ServiceCallback<FriendshipListFetchResponse>() { final ServiceCallback<FriendshipListFetchResponse> followersFetchCb = new ServiceCallback<FriendshipListFetchResponse>() {
@Override @Override
public void onSuccess(final FriendshipListFetchResponse result) { public void onSuccess(final FriendshipListFetchResponse result) {
if (result != null) { if (result != null && isCompare) {
followersModels.addAll(result.getItems()); followersModels.addAll(result.getItems());
if (isFollowersList) followModels.addAll(result.getItems()); if (isFollowersList) followModels.addAll(result.getItems());
if (result.isMoreAvailable()) { if (result.isMoreAvailable()) {
@ -107,7 +107,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
if (isFollowersList) moreAvailable = false; if (isFollowersList) moreAvailable = false;
showCompare(); showCompare();
} }
} } else if (isCompare) binding.swipeRefreshLayout.setRefreshing(false);
} }
@Override @Override
@ -237,12 +237,12 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
}; };
layoutManager = new LinearLayoutManager(getContext()); layoutManager = new LinearLayoutManager(getContext());
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (!TextUtils.isEmpty(endCursor)) { if (!TextUtils.isEmpty(endCursor) && !searching) {
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
layoutManager.setStackFromEnd(true); layoutManager.setStackFromEnd(true);
friendshipService.getList(isFollowersList, profileId, endCursor, cb); friendshipService.getList(isFollowersList, profileId, endCursor, cb);
endCursor = null;
} }
endCursor = null;
}); });
binding.rvFollow.addOnScrollListener(lazyLoader); binding.rvFollow.addOnScrollListener(lazyLoader);
binding.rvFollow.setLayoutManager(layoutManager); binding.rvFollow.setLayoutManager(layoutManager);
@ -303,68 +303,6 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
final SearchView searchView = (SearchView) menuSearch.getActionView(); final SearchView searchView = (SearchView) menuSearch.getActionView();
searchView.setQueryHint(getResources().getString(R.string.action_search)); searchView.setQueryHint(getResources().getString(R.string.action_search));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// private final Filter filter = new Filter() {
// private final ArrayList<FollowModel> searchFollowModels = new ArrayList<>(followModels.size() / 2);
// private final ArrayList<FollowModel> searchFollowingModels = new ArrayList<>(followingModels.size() / 2);
// private final ArrayList<FollowModel> searchFollowersModels = new ArrayList<>(followersModels.size() / 2);
// private final ArrayList<FollowModel> searchAllFollowing = new ArrayList<>(allFollowing.size() / 2);
//
// @Nullable
// @Override
// protected FilterResults performFiltering(@NonNull final CharSequence constraint) {
// searchFollowModels.clear();
// searchFollowingModels.clear();
// searchFollowersModels.clear();
// searchAllFollowing.clear();
//
// final int followModelsSize = followModels.size();
// final int followingModelsSize = followingModels.size();
// final int followersModelsSize = followersModels.size();
// final int allFollowingSize = allFollowing.size();
//
// int maxSize = followModelsSize;
// if (maxSize < followingModelsSize) maxSize = followingModelsSize;
// if (maxSize < followersModelsSize) maxSize = followersModelsSize;
// if (maxSize < allFollowingSize) maxSize = allFollowingSize;
//
// final String query = constraint.toString().toLowerCase();
// FollowModel followModel;
// while (maxSize != -1) {
// if (maxSize < followModelsSize) {
// followModel = followModels.get(maxSize);
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
// searchFollowModels.add(followModel);
// }
//
// if (maxSize < followingModelsSize) {
// followModel = followingModels.get(maxSize);
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
// searchFollowingModels.add(followModel);
// }
//
// if (maxSize < followersModelsSize) {
// followModel = followersModels.get(maxSize);
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
// searchFollowersModels.add(followModel);
// }
//
// if (maxSize < allFollowingSize) {
// followModel = allFollowing.get(maxSize);
// if (Utils.hasKey(query, followModel.getUsername(), followModel.getFullName()))
// searchAllFollowing.add(followModel);
// }
//
// --maxSize;
// }
//
// return null;
// }
//
// @Override
// protected void publishResults(final CharSequence query, final FilterResults results) {
// refreshAdapter(searchFollowModels, searchFollowingModels, searchFollowersModels, searchAllFollowing);
// }
// };
@Override @Override
public boolean onQueryTextSubmit(final String query) { public boolean onQueryTextSubmit(final String query) {
@ -373,9 +311,15 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
@Override @Override
public boolean onQueryTextChange(final String query) { public boolean onQueryTextChange(final String query) {
// if (Utils.isEmpty(query)) refreshAdapter(followModels, followingModels, followersModels, allFollowing); if (TextUtils.isEmpty(query)) {
searching = false;
// refreshAdapter(followModels, followingModels, followersModels, allFollowing);
}
// else filter.filter(query.toLowerCase()); // else filter.filter(query.toLowerCase());
if (adapter != null) adapter.getFilter().filter(query); if (adapter != null) {
searching = true;
adapter.getFilter().filter(query);
}
return true; return true;
} }
}); });

View File

@ -376,7 +376,8 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
final Context context = getContext(); final Context context = getContext();
if (context == null) return; if (context == null) return;
if (hashtagModel == null) { if (hashtagModel == null) {
Toast.makeText(context, R.string.error_loading_profile, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.error_loading_hashtag, Toast.LENGTH_SHORT).show();
binding.swipeRefreshLayout.setEnabled(false);
return; return;
} }
setTitle(); setTitle();

View File

@ -385,7 +385,8 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
if (locationModel == null) { if (locationModel == null) {
final Context context = getContext(); final Context context = getContext();
if (context == null) return; if (context == null) return;
Toast.makeText(context, R.string.error_loading_profile, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.error_loading_location, Toast.LENGTH_SHORT).show();
binding.swipeRefreshLayout.setEnabled(false);
return; return;
} }
setTitle(); setTitle();

View File

@ -216,10 +216,14 @@ public class StoryViewerFragment extends Fragment {
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(R.string.reply_story) .setTitle(R.string.reply_story)
.setView(input) .setView(input)
.setPositiveButton(R.string.confirm, (d, w) -> new CreateThreadAction(cookie, currentStory.getUserId(), threadId -> { .setPositiveButton(R.string.confirm, (d, w) -> new CreateThreadAction(cookie, currentStory.getUserId(), thread -> {
if (thread == null) {
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
return;
}
try { try {
final Call<DirectThreadBroadcastResponse> request = directMessagesService final Call<DirectThreadBroadcastResponse> request = directMessagesService
.broadcastStoryReply(BroadcastOptions.ThreadIdOrUserIds.of(threadId), .broadcastStoryReply(BroadcastOptions.ThreadIdOrUserIds.of(thread.getThreadId()),
input.getText().toString(), input.getText().toString(),
currentStory.getStoryMediaId(), currentStory.getStoryMediaId(),
String.valueOf(currentStory.getUserId())); String.valueOf(currentStory.getUserId()));

View File

@ -305,9 +305,9 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID); final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie); final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
fragmentActivity = (MainActivity) requireActivity(); fragmentActivity = (MainActivity) requireActivity();
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId); friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, userId) : null;
storiesService = StoriesService.getInstance(); storiesService = isLoggedIn ? StoriesService.getInstance() : null;
mediaService = MediaService.getInstance(null, null, 0); mediaService = isLoggedIn ? MediaService.getInstance(null, null, 0) : null;
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext())); accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext())); favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
setHasOptionsMenu(true); setHasOptionsMenu(true);
@ -538,10 +538,26 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private void fetchProfileDetails() { private void fetchProfileDetails() {
if (TextUtils.isEmpty(username)) return; if (TextUtils.isEmpty(username)) return;
new ProfileFetcher(username.trim().substring(1), isLoggedIn, profileModel -> { new ProfileFetcher(username.trim().substring(1), isLoggedIn, new FetchListener<User>() {
if (getContext() == null) return; @Override
this.profileModel = profileModel; public void onResult(final User user) {
setProfileDetails(); if (getContext() == null) return;
profileModel = user;
setProfileDetails();
}
@Override
public void onFailure(final Throwable t) {
Log.e(TAG, "Error fetching profile", t);
final Context context = getContext();
try {
if (t == null) Toast.makeText(context,
isLoggedIn ? R.string.error_loading_profile_loggedin : R.string.error_loading_profile,
Toast.LENGTH_LONG).show();
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
catch(final Throwable e) {}
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -786,18 +802,19 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
private void setupButtons(final long profileId, final long myId) { private void setupButtons(final long profileId, final long myId) {
profileDetailsBinding.btnTagged.setVisibility(isReallyPrivate() ? View.GONE : View.VISIBLE); profileDetailsBinding.btnTagged.setVisibility(isReallyPrivate() ? View.GONE : View.VISIBLE);
profileDetailsBinding.btnDM.setVisibility(View.GONE); // temporary measure
if (isLoggedIn) { if (isLoggedIn) {
if (Objects.equals(profileId, myId)) { if (Objects.equals(profileId, myId)) {
profileDetailsBinding.btnTagged.setVisibility(View.VISIBLE); profileDetailsBinding.btnTagged.setVisibility(View.VISIBLE);
profileDetailsBinding.btnSaved.setVisibility(View.VISIBLE); profileDetailsBinding.btnSaved.setVisibility(View.VISIBLE);
profileDetailsBinding.btnLiked.setVisibility(View.VISIBLE); profileDetailsBinding.btnLiked.setVisibility(View.VISIBLE);
profileDetailsBinding.btnDM.setVisibility(View.GONE); // profileDetailsBinding.btnDM.setVisibility(View.GONE);
profileDetailsBinding.btnSaved.setText(R.string.saved); profileDetailsBinding.btnSaved.setText(R.string.saved);
return; return;
} }
profileDetailsBinding.btnSaved.setVisibility(View.GONE); profileDetailsBinding.btnSaved.setVisibility(View.GONE);
profileDetailsBinding.btnLiked.setVisibility(View.GONE); profileDetailsBinding.btnLiked.setVisibility(View.GONE);
profileDetailsBinding.btnDM.setVisibility(View.VISIBLE); // maybe there is a judgment mechanism? // profileDetailsBinding.btnDM.setVisibility(View.VISIBLE);
profileDetailsBinding.btnFollow.setVisibility(View.VISIBLE); profileDetailsBinding.btnFollow.setVisibility(View.VISIBLE);
final Context context = getContext(); final Context context = getContext();
if (context == null) return; if (context == null) return;
@ -902,7 +919,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
@Override @Override
public void onSuccess(final FriendshipChangeResponse result) { public void onSuccess(final FriendshipChangeResponse result) {
// Log.d(TAG, "Unfollow success: " + result); // Log.d(TAG, "Unfollow success: " + result);
onRefresh(); fetchProfileDetails();
} }
@Override @Override
@ -920,7 +937,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
@Override @Override
public void onSuccess(final FriendshipChangeResponse result) { public void onSuccess(final FriendshipChangeResponse result) {
// Log.d(TAG, "Unfollow success: " + result); // Log.d(TAG, "Unfollow success: " + result);
onRefresh(); fetchProfileDetails();
} }
@Override @Override
@ -935,7 +952,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
@Override @Override
public void onSuccess(final FriendshipChangeResponse result) { public void onSuccess(final FriendshipChangeResponse result) {
// Log.d(TAG, "Follow success: " + result); // Log.d(TAG, "Follow success: " + result);
onRefresh(); fetchProfileDetails();
} }
@Override @Override
@ -961,17 +978,27 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
PostItemType.TAGGED); PostItemType.TAGGED);
NavHostFragment.findNavController(this).navigate(action); NavHostFragment.findNavController(this).navigate(action);
}); });
profileDetailsBinding.btnDM.setOnClickListener(v -> { // profileDetailsBinding.btnDM.setOnClickListener(v -> {
profileDetailsBinding.btnDM.setEnabled(false); // profileDetailsBinding.btnDM.setEnabled(false);
// new CreateThreadAction(cookie, profileModel.getPk(), threadId -> { // new CreateThreadAction(cookie, profileModel.getPk(), thread -> {
// if (isAdded()) { // if (thread == null) {
// final NavDirections action = ProfileFragmentDirections // Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
// .actionProfileFragmentToDMThreadFragment(threadId, profileModel.getUsername()); // profileDetailsBinding.btnDM.setEnabled(true);
// NavHostFragment.findNavController(this).navigate(action); // return;
// } // }
// profileDetailsBinding.btnDM.setEnabled(true); // if (isAdded()) {
// }).execute(); // final Bundle bundle = new Bundle();
}); // bundle.putString("threadId", thread.getThreadId());
// bundle.putString("title", thread.getThreadTitle());
// if (isAdded()) {
// final NavDirections action = ProfileFragmentDirections
// .actionProfileFragmentToDMThreadFragment(thread.getThreadId(), profileModel.getUsername());
// NavHostFragment.findNavController(this).navigate(action);
// }
// }
// profileDetailsBinding.btnDM.setEnabled(true);
// }).execute();
// });
profileDetailsBinding.mainProfileImage.setOnClickListener(v -> { profileDetailsBinding.mainProfileImage.setOnClickListener(v -> {
if (!hasStories) { if (!hasStories) {
// show profile pic // show profile pic

View File

@ -64,7 +64,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
screen.addPreference(accountCategory); screen.addPreference(accountCategory);
if (isLoggedIn) { if (isLoggedIn) {
accountCategory.setSummary(R.string.account_hint); accountCategory.setSummary(R.string.account_hint);
accountCategory.addPreference(getAccountSwitcherPreference(cookie)); accountCategory.addPreference(getAccountSwitcherPreference(cookie, context));
accountCategory.addPreference(getPreference(R.string.logout, R.string.logout_summary, R.drawable.ic_logout_24, preference -> { accountCategory.addPreference(getPreference(R.string.logout, R.string.logout_summary, R.drawable.ic_logout_24, preference -> {
if (getContext() == null) return false; if (getContext() == null) return false;
CookieUtils.setupCookies("LOGOUT"); CookieUtils.setupCookies("LOGOUT");
@ -79,7 +79,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
public void onSuccess(@NonNull final List<Account> accounts) { public void onSuccess(@NonNull final List<Account> accounts) {
if (!isLoggedIn) { if (!isLoggedIn) {
if (accounts.size() > 0) { if (accounts.size() > 0) {
accountCategory.addPreference(getAccountSwitcherPreference(null)); accountCategory.addPreference(getAccountSwitcherPreference(null, context));
} }
// Need to show something to trigger login activity // Need to show something to trigger login activity
accountCategory.addPreference(getPreference(R.string.add_account, R.drawable.ic_add, preference -> { accountCategory.addPreference(getPreference(R.string.add_account, R.drawable.ic_add, preference -> {
@ -235,8 +235,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
} }
} }
private AccountSwitcherPreference getAccountSwitcherPreference(final String cookie) { private AccountSwitcherPreference getAccountSwitcherPreference(final String cookie, final Context context) {
final Context context = getContext();
if (context == null) return null; if (context == null) return null;
return new AccountSwitcherPreference(context, cookie, accountRepository, v -> showAccountSwitcherDialog()); return new AccountSwitcherPreference(context, cookie, accountRepository, v -> showAccountSwitcherDialog());
} }

View File

@ -0,0 +1,16 @@
package awais.instagrabber.repositories.responses;
public class HdProfilePicUrlInfo {
private final String url;
private final int width, height;
public HdProfilePicUrlInfo(final String url, final int width, final int height) {
this.url = url;
this.width = width;
this.height = height;
}
public String getUrl() {
return url;
}
}

View File

@ -26,6 +26,7 @@ public class User implements Serializable {
private final String externalUrl; private final String externalUrl;
private final long usertagsCount; private final long usertagsCount;
private final String publicEmail; private final String publicEmail;
private final HdProfilePicUrlInfo hdProfilePicUrlInfo;
public User(final long pk, public User(final long pk,
@ -49,7 +50,8 @@ public class User implements Serializable {
final String biography, final String biography,
final String externalUrl, final String externalUrl,
final long usertagsCount, final long usertagsCount,
final String publicEmail) { final String publicEmail,
final HdProfilePicUrlInfo hdProfilePicUrlInfo) {
this.pk = pk; this.pk = pk;
this.username = username; this.username = username;
this.fullName = fullName; this.fullName = fullName;
@ -72,6 +74,7 @@ public class User implements Serializable {
this.externalUrl = externalUrl; this.externalUrl = externalUrl;
this.usertagsCount = usertagsCount; this.usertagsCount = usertagsCount;
this.publicEmail = publicEmail; this.publicEmail = publicEmail;
this.hdProfilePicUrlInfo = hdProfilePicUrlInfo;
} }
public long getPk() { public long getPk() {
@ -94,6 +97,10 @@ public class User implements Serializable {
return profilePicUrl; return profilePicUrl;
} }
public String getHDProfilePicUrl() {
return hdProfilePicUrlInfo.getUrl();
}
public String getProfilePicId() { public String getProfilePicId() {
return profilePicId; return profilePicId;
} }

View File

@ -781,7 +781,7 @@ public final class ResponseBodyUtils {
null, null,
friendshipStatus, friendshipStatus,
owner.optBoolean("is_verified"), owner.optBoolean("is_verified"),
false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null); false, false, false, false, null, null, 0, 0, 0, 0, null, null, 0, null, null);
} }
final String id = feedItem.getString(Constants.EXTRAS_ID); final String id = feedItem.getString(Constants.EXTRAS_ID);
final ImageVersions2 imageVersions2 = new ImageVersions2( final ImageVersions2 imageVersions2 = new ImageVersions2(

View File

@ -242,6 +242,7 @@ public class GraphQLService extends BaseService {
null, null,
null, null,
0, 0,
null,
null null
)); ));
// userModels.add(new ProfileModel(userObject.optBoolean("is_private"), // userModels.add(new ProfileModel(userObject.optBoolean("is_private"),
@ -332,6 +333,7 @@ public class GraphQLService extends BaseService {
userJson.getString("biography"), userJson.getString("biography"),
url, url,
0, 0,
null,
null)); null));
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, "onResponse", e); Log.e(TAG, "onResponse", e);

View File

@ -113,51 +113,55 @@ public class StoriesService extends BaseService {
for (int i = 0; i < feedStoriesReel.length(); ++i) { for (int i = 0; i < feedStoriesReel.length(); ++i) {
final JSONObject node = feedStoriesReel.getJSONObject(i); final JSONObject node = feedStoriesReel.getJSONObject(i);
final JSONObject userJson = node.getJSONObject(node.has("user") ? "user" : "owner"); final JSONObject userJson = node.getJSONObject(node.has("user") ? "user" : "owner");
final User user = new User(userJson.getLong("pk"), try {
userJson.getString("username"), final User user = new User(userJson.getLong("pk"),
userJson.optString("full_name"), userJson.getString("username"),
userJson.optBoolean("is_private"), userJson.optString("full_name"),
userJson.getString("profile_pic_url"), userJson.optBoolean("is_private"),
null, userJson.getString("profile_pic_url"),
new FriendshipStatus( null,
false, new FriendshipStatus(
false, false,
false, false,
false, false,
false, false,
false, false,
false, false,
false, false,
false, false,
false false,
), false
userJson.optBoolean("is_verified"), ),
false, userJson.optBoolean("is_verified"),
false, false,
false, false,
false, false,
null, false,
null, null,
0, null,
0, 0,
0, 0,
0, 0,
null, 0,
null, null,
0, null,
null 0,
); null,
final String id = node.getString("id"); null
final long timestamp = node.getLong("latest_reel_media"); );
final int mediaCount = node.getInt("media_count"); final String id = node.getString("id");
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp; final long timestamp = node.getLong("latest_reel_media");
final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null; final int mediaCount = node.getInt("media_count");
final boolean isBestie = node.optBoolean("has_besties_media", false); final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp;
StoryModel firstStoryModel = null; final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null;
if (itemJson != null) { final boolean isBestie = node.optBoolean("has_besties_media", false);
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, null); StoryModel firstStoryModel = null;
if (itemJson != null) {
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, null);
}
feedStoryModels.add(new FeedStoryModel(id, user, fullyRead, timestamp, firstStoryModel, mediaCount, false, isBestie));
} }
feedStoryModels.add(new FeedStoryModel(id, user, fullyRead, timestamp, firstStoryModel, mediaCount, false, isBestie)); catch (Exception e) {} // to cover promotional reels with non-long user pk's
} }
final JSONArray broadcasts = new JSONObject(body).getJSONArray("broadcasts"); final JSONArray broadcasts = new JSONObject(body).getJSONArray("broadcasts");
for (int i = 0; i < broadcasts.length(); ++i) { for (int i = 0; i < broadcasts.length(); ++i) {
@ -201,6 +205,7 @@ public class StoriesService extends BaseService {
null, null,
null, null,
0, 0,
null,
null null
); );
final String id = node.getString("id"); final String id = node.getString("id");

View File

@ -62,7 +62,7 @@ public class UserService extends BaseService {
public void onResponse(@NonNull final Call<WrappedUser> call, @NonNull final Response<WrappedUser> response) { public void onResponse(@NonNull final Call<WrappedUser> call, @NonNull final Response<WrappedUser> response) {
final WrappedUser user = response.body(); final WrappedUser user = response.body();
if (user == null) { if (user == null) {
callback.onSuccess(null); callback.onFailure(null);
return; return;
} }
callback.onSuccess(user.getUser()); callback.onSuccess(user.getUser());

View File

@ -36,7 +36,10 @@
<string name="dm_mark_as_seen_setting_summary">Other members will know you viewed it</string> <string name="dm_mark_as_seen_setting_summary">Other members will know you viewed it</string>
<string name="activity_setting">Enable activity notifications</string> <string name="activity_setting">Enable activity notifications</string>
<string name="story_sort_setting">Feed stories sort</string> <string name="story_sort_setting">Feed stories sort</string>
<string name="error_loading_profile">Error loading profile!\nTry logging in and search again.</string> <string name="error_loading_profile">Error loading profile! Is the username valid? If so, you may be ratelimited.</string>
<string name="error_loading_profile_loggedin">Error loading profile! Is the username valid? Or did they block you?</string>
<string name="error_loading_hashtag">Error loading hashtag! Is the name valid?</string>
<string name="error_loading_location">Error loading hashtag! Is the URL valid?</string>
<string name="error_creating_folders">Error creating Download folder(s).</string> <string name="error_creating_folders">Error creating Download folder(s).</string>
<string name="save_to_folder">Save to custom folder</string> <string name="save_to_folder">Save to custom folder</string>
<string name="select_folder">Select folder</string> <string name="select_folder">Select folder</string>

View File

@ -6,7 +6,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.2' classpath 'com.android.tools.build:gradle:4.1.2'
def nav_version = "2.3.2" def nav_version = "2.3.3"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
} }
} }

View File

@ -1,8 +1,9 @@
#Sun Feb 28 01:04:23 JST 2021
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
# https://gradle.org/releases/
# https://gradle.org/release-checksums/
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip
distributionSha256Sum=1433372d903ffba27496f8d5af24265310d2da0d78bf6b4e5138831d4fe066e9
# https://gradle.org/releases/
# https://gradle.org/release-checksums/