Austin Huang
4 years ago
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
29 changed files with 517 additions and 58 deletions
-
7app/src/main/java/awais/instagrabber/adapters/SavedCollectionsAdapter.java
-
2app/src/main/java/awais/instagrabber/adapters/viewholder/TopicClusterViewHolder.java
-
6app/src/main/java/awais/instagrabber/asyncs/DiscoverPostFetchService.java
-
73app/src/main/java/awais/instagrabber/fragments/CollectionPostsFragment.java
-
30app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java
-
38app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java
-
2app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
-
23app/src/main/java/awais/instagrabber/repositories/CollectionRepository.java
-
7app/src/main/java/awais/instagrabber/repositories/ProfileRepository.java
-
43app/src/main/java/awais/instagrabber/repositories/responses/WrappedFeedResponse.java
-
13app/src/main/java/awais/instagrabber/repositories/responses/WrappedMedia.java
-
7app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicalExploreFeedResponse.java
-
15app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicalExploreItem.java
-
8app/src/main/java/awais/instagrabber/repositories/responses/saved/SavedCollection.java
-
18app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.java
-
120app/src/main/java/awais/instagrabber/webservices/CollectionService.java
-
14app/src/main/java/awais/instagrabber/webservices/MediaService.java
-
30app/src/main/java/awais/instagrabber/webservices/ProfileService.java
-
21app/src/main/res/menu/collection_posts_menu.xml
-
22app/src/main/res/menu/saved_collection_select_menu.xml
-
10app/src/main/res/navigation/direct_messages_nav_graph.xml
-
10app/src/main/res/navigation/discover_nav_graph.xml
-
10app/src/main/res/navigation/feed_nav_graph.xml
-
10app/src/main/res/navigation/hashtag_nav_graph.xml
-
10app/src/main/res/navigation/location_nav_graph.xml
-
10app/src/main/res/navigation/notification_viewer_nav_graph.xml
-
6app/src/main/res/navigation/profile_nav_graph.xml
-
4app/src/main/res/navigation/saved_nav_graph.xml
-
6app/src/main/res/values/strings.xml
@ -0,0 +1,23 @@ |
|||
package awais.instagrabber.repositories; |
|||
|
|||
import java.util.Map; |
|||
|
|||
import awais.instagrabber.repositories.responses.UserFeedResponse; |
|||
import awais.instagrabber.repositories.responses.WrappedFeedResponse; |
|||
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse; |
|||
import retrofit2.Call; |
|||
import retrofit2.http.FieldMap; |
|||
import retrofit2.http.FormUrlEncoded; |
|||
import retrofit2.http.GET; |
|||
import retrofit2.http.POST; |
|||
import retrofit2.http.Path; |
|||
import retrofit2.http.QueryMap; |
|||
|
|||
public interface CollectionRepository { |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/collections/{id}/{action}/") |
|||
Call<String> changeCollection(@Path("id") String id, |
|||
@Path("action") String action, |
|||
@FieldMap Map<String, String> signedForm); |
|||
} |
@ -0,0 +1,43 @@ |
|||
package awais.instagrabber.repositories.responses; |
|||
|
|||
import java.util.List; |
|||
|
|||
public class WrappedFeedResponse { |
|||
private final int numResults; |
|||
private final String nextMaxId; |
|||
private final boolean moreAvailable; |
|||
private final String status; |
|||
private final List<WrappedMedia> items; |
|||
|
|||
public WrappedFeedResponse(final int numResults, |
|||
final String nextMaxId, |
|||
final boolean moreAvailable, |
|||
final String status, |
|||
final List<WrappedMedia> items) { |
|||
this.numResults = numResults; |
|||
this.nextMaxId = nextMaxId; |
|||
this.moreAvailable = moreAvailable; |
|||
this.status = status; |
|||
this.items = items; |
|||
} |
|||
|
|||
public int getNumResults() { |
|||
return numResults; |
|||
} |
|||
|
|||
public String getNextMaxId() { |
|||
return nextMaxId; |
|||
} |
|||
|
|||
public boolean isMoreAvailable() { |
|||
return moreAvailable; |
|||
} |
|||
|
|||
public String getStatus() { |
|||
return status; |
|||
} |
|||
|
|||
public List<WrappedMedia> getItems() { |
|||
return items; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
package awais.instagrabber.repositories.responses; |
|||
|
|||
public class WrappedMedia { |
|||
private final Media media; |
|||
|
|||
public WrappedMedia(final Media media) { |
|||
this.media = media; |
|||
} |
|||
|
|||
public Media getMedia() { |
|||
return media; |
|||
} |
|||
} |
@ -1,15 +0,0 @@ |
|||
package awais.instagrabber.repositories.responses.discover; |
|||
|
|||
import awais.instagrabber.repositories.responses.Media; |
|||
|
|||
public class TopicalExploreItem { |
|||
private final Media media; |
|||
|
|||
public TopicalExploreItem(final Media media) { |
|||
this.media = media; |
|||
} |
|||
|
|||
public Media getMedia() { |
|||
return media; |
|||
} |
|||
} |
@ -0,0 +1,120 @@ |
|||
package awais.instagrabber.webservices; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Objects; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import awais.instagrabber.repositories.CollectionRepository; |
|||
import awais.instagrabber.repositories.responses.Media; |
|||
import awais.instagrabber.utils.Utils; |
|||
import retrofit2.Call; |
|||
import retrofit2.Callback; |
|||
import retrofit2.Response; |
|||
import retrofit2.Retrofit; |
|||
|
|||
public class CollectionService extends BaseService { |
|||
private static final String TAG = "ProfileService"; |
|||
|
|||
private final CollectionRepository repository; |
|||
private final String deviceUuid, csrfToken; |
|||
private final long userId; |
|||
|
|||
private static CollectionService instance; |
|||
|
|||
private CollectionService(final String deviceUuid, |
|||
final String csrfToken, |
|||
final long userId) { |
|||
this.deviceUuid = deviceUuid; |
|||
this.csrfToken = csrfToken; |
|||
this.userId = userId; |
|||
final Retrofit retrofit = getRetrofitBuilder() |
|||
.baseUrl("https://i.instagram.com") |
|||
.build(); |
|||
repository = retrofit.create(CollectionRepository.class); |
|||
} |
|||
|
|||
public String getCsrfToken() { |
|||
return csrfToken; |
|||
} |
|||
|
|||
public String getDeviceUuid() { |
|||
return deviceUuid; |
|||
} |
|||
|
|||
public long getUserId() { |
|||
return userId; |
|||
} |
|||
|
|||
public static CollectionService getInstance(final String deviceUuid, final String csrfToken, final long userId) { |
|||
if (instance == null |
|||
|| !Objects.equals(instance.getCsrfToken(), csrfToken) |
|||
|| !Objects.equals(instance.getDeviceUuid(), deviceUuid) |
|||
|| !Objects.equals(instance.getUserId(), userId)) { |
|||
instance = new CollectionService(deviceUuid, csrfToken, userId); |
|||
} |
|||
return instance; |
|||
} |
|||
|
|||
public void addPostsToCollection(final String collectionId, |
|||
final List<Media> posts, |
|||
final ServiceCallback<String> callback) { |
|||
final Map<String, Object> form = new HashMap<>(2); |
|||
form.put("module_name", "feed_saved_add_to_collection"); |
|||
final List<String> ids; |
|||
ids = posts.stream() |
|||
.map(Media::getPk) |
|||
.filter(Objects::nonNull) |
|||
.collect(Collectors.toList()); |
|||
form.put("added_media_ids", "[" + String.join(",", ids) + "]"); |
|||
changeCollection(collectionId, "edit", form, callback); |
|||
} |
|||
|
|||
public void editCollectionName(final String collectionId, |
|||
final String name, |
|||
final ServiceCallback<String> callback) { |
|||
final Map<String, Object> form = new HashMap<>(1); |
|||
form.put("name", name); |
|||
changeCollection(collectionId, "edit", form, callback); |
|||
} |
|||
|
|||
public void deleteCollection(final String collectionId, |
|||
final ServiceCallback<String> callback) { |
|||
changeCollection(collectionId, "delete", null, callback); |
|||
} |
|||
|
|||
public void changeCollection(final String collectionId, |
|||
final String action, |
|||
final Map<String, Object> options, |
|||
final ServiceCallback<String> callback) { |
|||
final Map<String, Object> form = new HashMap<>(); |
|||
form.put("_csrftoken", csrfToken); |
|||
form.put("_uuid", deviceUuid); |
|||
form.put("_uid", userId); |
|||
if (options != null) form.putAll(options); |
|||
final Map<String, String> signedForm = Utils.sign(form); |
|||
final Call<String> request = repository.changeCollection(collectionId, action, signedForm); |
|||
request.enqueue(new Callback<String>() { |
|||
@Override |
|||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) { |
|||
if (callback == null) return; |
|||
final String collectionsListResponse = response.body(); |
|||
if (collectionsListResponse == null) { |
|||
callback.onSuccess(null); |
|||
return; |
|||
} |
|||
callback.onSuccess(collectionsListResponse); |
|||
} |
|||
|
|||
@Override |
|||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) { |
|||
if (callback != null) { |
|||
callback.onFailure(t); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto"> |
|||
|
|||
<item |
|||
android:id="@+id/edit" |
|||
android:icon="@android:drawable/ic_menu_edit" |
|||
android:title="@string/edit_collection" |
|||
app:showAsAction="always" /> |
|||
|
|||
<item |
|||
android:id="@+id/delete" |
|||
android:icon="@android:drawable/ic_menu_delete" |
|||
android:title="@string/delete_collection" |
|||
app:showAsAction="always" /> |
|||
|
|||
<item |
|||
android:id="@+id/layout" |
|||
android:title="@string/layout" |
|||
app:showAsAction="never" /> |
|||
</menu> |
@ -0,0 +1,22 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto"> |
|||
<item |
|||
android:id="@+id/action_add" |
|||
android:icon="@drawable/ic_add" |
|||
android:title="@string/add_to_collection" |
|||
android:titleCondensed="@string/action_download" |
|||
app:showAsAction="always" /> |
|||
<item |
|||
android:id="@+id/action_delete" |
|||
android:icon="@drawable/ic_cancel" |
|||
android:title="@string/remove_from_collection" |
|||
android:titleCondensed="@string/action_download" |
|||
app:showAsAction="always" /> |
|||
<item |
|||
android:id="@+id/action_download" |
|||
android:icon="@drawable/ic_download" |
|||
android:title="@string/action_download" |
|||
android:titleCondensed="@string/action_download" |
|||
app:showAsAction="always" /> |
|||
</menu> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue