Browse Source

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

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
e4741d3f7c
  1. 16
      app/build.gradle
  2. 6
      app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java
  3. 95
      app/src/main/java/awais/instagrabber/asyncs/CreateThreadAction.java
  4. 13
      app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java
  5. 7
      app/src/main/java/awais/instagrabber/dialogs/ProfilePicDialogFragment.java
  6. 10
      app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java
  7. 20
      app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java
  8. 86
      app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java
  9. 3
      app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
  10. 3
      app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
  11. 8
      app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
  12. 73
      app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
  13. 7
      app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java
  14. 16
      app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.java
  15. 9
      app/src/main/java/awais/instagrabber/repositories/responses/User.java
  16. 2
      app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java
  17. 2
      app/src/main/java/awais/instagrabber/webservices/GraphQLService.java
  18. 93
      app/src/main/java/awais/instagrabber/webservices/StoriesService.java
  19. 2
      app/src/main/java/awais/instagrabber/webservices/UserService.java
  20. 5
      app/src/main/res/values/strings.xml
  21. 2
      build.gradle
  22. 9
      gradle/wrapper/gradle-wrapper.properties

16
app/build.gradle

@ -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"

6
app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java

@ -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),

95
app/src/main/java/awais/instagrabber/asyncs/CreateThreadAction.java

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

13
app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java

@ -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

7
app/src/main/java/awais/instagrabber/dialogs/ProfilePicDialogFragment.java

@ -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();
} }
}); });

10
app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java

@ -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) {}
} }
}); });
}) })

20
app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java

@ -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;

86
app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java

@ -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;
} }
}); });

3
app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java

@ -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();

3
app/src/main/java/awais/instagrabber/fragments/LocationFragment.java

@ -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();

8
app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java

@ -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()));

73
app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java

@ -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);
storiesService = StoriesService.getInstance();
mediaService = MediaService.getInstance(null, null, 0);
friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, userId) : null;
storiesService = isLoggedIn ? StoriesService.getInstance() : null;
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 -> {
if (getContext() == null) return;
this.profileModel = profileModel;
setProfileDetails();
new ProfileFetcher(username.trim().substring(1), isLoggedIn, new FetchListener<User>() {
@Override
public void onResult(final User user) {
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.setEnabled(false);
// new CreateThreadAction(cookie, profileModel.getPk(), threadId -> {
// if (isAdded()) {
// final NavDirections action = ProfileFragmentDirections
// .actionProfileFragmentToDMThreadFragment(threadId, profileModel.getUsername());
// NavHostFragment.findNavController(this).navigate(action);
// }
// profileDetailsBinding.btnDM.setEnabled(true);
// }).execute();
});
// profileDetailsBinding.btnDM.setOnClickListener(v -> {
// profileDetailsBinding.btnDM.setEnabled(false);
// new CreateThreadAction(cookie, profileModel.getPk(), thread -> {
// if (thread == null) {
// Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
// profileDetailsBinding.btnDM.setEnabled(true);
// return;
// }
// if (isAdded()) {
// 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

7
app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java

@ -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) {
final Context context = getContext();
private AccountSwitcherPreference getAccountSwitcherPreference(final String cookie, final Context context) {
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());
} }

16
app/src/main/java/awais/instagrabber/repositories/responses/HdProfilePicUrlInfo.java

@ -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;
}
}

9
app/src/main/java/awais/instagrabber/repositories/responses/User.java

@ -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;
} }

2
app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java

@ -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(

2
app/src/main/java/awais/instagrabber/webservices/GraphQLService.java

@ -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);

93
app/src/main/java/awais/instagrabber/webservices/StoriesService.java

@ -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"),
userJson.getString("username"),
userJson.optString("full_name"),
userJson.optBoolean("is_private"),
userJson.getString("profile_pic_url"),
null,
new FriendshipStatus(
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
),
userJson.optBoolean("is_verified"),
false,
false,
false,
false,
null,
null,
0,
0,
0,
0,
null,
null,
0,
null
);
final String id = node.getString("id");
final long timestamp = node.getLong("latest_reel_media");
final int mediaCount = node.getInt("media_count");
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp;
final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null;
final boolean isBestie = node.optBoolean("has_besties_media", false);
StoryModel firstStoryModel = null;
if (itemJson != null) {
firstStoryModel = ResponseBodyUtils.parseStoryItem(itemJson, false, false, null);
try {
final User user = new User(userJson.getLong("pk"),
userJson.getString("username"),
userJson.optString("full_name"),
userJson.optBoolean("is_private"),
userJson.getString("profile_pic_url"),
null,
new FriendshipStatus(
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
),
userJson.optBoolean("is_verified"),
false,
false,
false,
false,
null,
null,
0,
0,
0,
0,
null,
null,
0,
null,
null
);
final String id = node.getString("id");
final long timestamp = node.getLong("latest_reel_media");
final int mediaCount = node.getInt("media_count");
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == timestamp;
final JSONObject itemJson = node.has("items") ? node.getJSONArray("items").optJSONObject(0) : null;
final boolean isBestie = node.optBoolean("has_besties_media", false);
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");

2
app/src/main/java/awais/instagrabber/webservices/UserService.java

@ -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());

5
app/src/main/res/values/strings.xml

@ -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>

2
build.gradle

@ -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"
} }
} }

9
gradle/wrapper/gradle-wrapper.properties

@ -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/
Loading…
Cancel
Save