diff --git a/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java index 9bff389e..a710cd55 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ProfilePostFetchService.java @@ -9,13 +9,14 @@ import awais.instagrabber.repositories.responses.PostsFetchResponse; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.webservices.GraphQLRepository; -import awais.instagrabber.webservices.ProfileService; +import awais.instagrabber.webservices.ProfileRepository; import awais.instagrabber.webservices.ServiceCallback; +import kotlin.coroutines.Continuation; import kotlinx.coroutines.Dispatchers; public class ProfilePostFetchService implements PostFetcher.PostFetchService { private static final String TAG = "ProfilePostFetchService"; - private final ProfileService profileService; + private final ProfileRepository profileRepository; private final GraphQLRepository graphQLRepository; private final User profileModel; private final boolean isLoggedIn; @@ -26,43 +27,32 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService { this.profileModel = profileModel; this.isLoggedIn = isLoggedIn; graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance(); - profileService = isLoggedIn ? ProfileService.getInstance() : null; + profileRepository = isLoggedIn ? ProfileRepository.Companion.getInstance() : null; } @Override public void fetch(final FetchListener> fetchListener) { - final ServiceCallback cb = new ServiceCallback() { - @Override - public void onSuccess(final PostsFetchResponse result) { - if (result == null) return; - nextMaxId = result.getNextCursor(); - moreAvailable = result.getHasNextPage(); - if (fetchListener != null) { - fetchListener.onResult(result.getFeedModels()); - } - } - - @Override - public void onFailure(final Throwable t) { - // Log.e(TAG, "onFailure: ", t); + final Continuation cb = CoroutineUtilsKt.getContinuation((result, t) -> { + if (t != null) { if (fetchListener != null) { fetchListener.onFailure(t); } + return; } - }; - if (isLoggedIn) profileService.fetchPosts(profileModel.getPk(), nextMaxId, cb); + if (result == null) return; + nextMaxId = result.getNextCursor(); + moreAvailable = result.getHasNextPage(); + if (fetchListener != null) { + fetchListener.onResult(result.getFeedModels()); + } + }, Dispatchers.getIO()); + if (isLoggedIn) profileRepository.fetchPosts(profileModel.getPk(), nextMaxId, cb); else graphQLRepository.fetchProfilePosts( profileModel.getPk(), 30, nextMaxId, profileModel, - CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> { - if (throwable != null) { - cb.onFailure(throwable); - return; - } - cb.onSuccess(postsFetchResponse); - }, Dispatchers.getIO()) + cb ); } diff --git a/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java b/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java index e4650a77..935ea158 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java +++ b/app/src/main/java/awais/instagrabber/asyncs/SavedPostFetchService.java @@ -9,12 +9,12 @@ import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.PostsFetchResponse; import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.webservices.GraphQLRepository; -import awais.instagrabber.webservices.ProfileService; -import awais.instagrabber.webservices.ServiceCallback; +import awais.instagrabber.webservices.ProfileRepository; +import kotlin.coroutines.Continuation; import kotlinx.coroutines.Dispatchers; public class SavedPostFetchService implements PostFetcher.PostFetchService { - private final ProfileService profileService; + private final ProfileRepository profileRepository; private final GraphQLRepository graphQLRepository; private final long profileId; private final PostItemType type; @@ -30,55 +30,42 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService { this.isLoggedIn = isLoggedIn; this.collectionId = collectionId; graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance(); - profileService = isLoggedIn ? ProfileService.getInstance() : null; + profileRepository = isLoggedIn ? ProfileRepository.Companion.getInstance() : null; } @Override public void fetch(final FetchListener> fetchListener) { - final ServiceCallback callback = new ServiceCallback() { - @Override - public void onSuccess(final PostsFetchResponse result) { - if (result == null) return; - nextMaxId = result.getNextCursor(); - moreAvailable = result.getHasNextPage(); - if (fetchListener != null) { - fetchListener.onResult(result.getFeedModels()); - } - } - - @Override - public void onFailure(final Throwable t) { - // Log.e(TAG, "onFailure: ", t); + final Continuation callback = CoroutineUtilsKt.getContinuation((result, t) -> { + if (t != null) { if (fetchListener != null) { fetchListener.onFailure(t); } + return; } - }; + if (result == null) return; + nextMaxId = result.getNextCursor(); + moreAvailable = result.getHasNextPage(); + if (fetchListener != null) { + fetchListener.onResult(result.getFeedModels()); + } + }, Dispatchers.getIO()); switch (type) { case LIKED: - profileService.fetchLiked(nextMaxId, callback); + profileRepository.fetchLiked(nextMaxId, callback); break; case TAGGED: - if (isLoggedIn) profileService.fetchTagged(profileId, nextMaxId, callback); + if (isLoggedIn) profileRepository.fetchTagged(profileId, nextMaxId, callback); else graphQLRepository.fetchTaggedPosts( profileId, 30, nextMaxId, - CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> { - if (throwable != null) { - callback.onFailure(throwable); - return; - } - callback.onSuccess(postsFetchResponse); - }, Dispatchers.getIO()) + callback ); break; case COLLECTION: case SAVED: - profileService.fetchSaved(nextMaxId, collectionId, callback); + profileRepository.fetchSaved(nextMaxId, collectionId, callback); break; - default: - callback.onFailure(null); } } diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java index af756f56..504d5883 100644 --- a/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/SavedCollectionsFragment.java @@ -34,9 +34,10 @@ import awais.instagrabber.databinding.FragmentSavedCollectionsBinding; import awais.instagrabber.repositories.responses.saved.CollectionsListResponse; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.SavedCollectionsViewModel; -import awais.instagrabber.webservices.ProfileService; +import awais.instagrabber.webservices.ProfileRepository; import awais.instagrabber.webservices.ServiceCallback; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -51,14 +52,14 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa private SavedCollectionsViewModel savedCollectionsViewModel; private boolean shouldRefresh = true; private boolean isSaving; - private ProfileService profileService; + private ProfileRepository profileRepository; private SavedCollectionsAdapter adapter; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); fragmentActivity = (MainActivity) requireActivity(); - profileService = ProfileService.getInstance(); + profileRepository = ProfileRepository.Companion.getInstance(); savedCollectionsViewModel = new ViewModelProvider(fragmentActivity).get(SavedCollectionsViewModel.class); setHasOptionsMenu(true); } @@ -106,23 +107,20 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa .setView(input) .setPositiveButton(R.string.confirm, (d, w) -> { final String cookie = settingsHelper.getString(Constants.COOKIE); - profileService.createCollection( + profileRepository.createCollection( input.getText().toString(), settingsHelper.getString(Constants.DEVICE_UUID), CookieUtils.getUserIdFromCookie(cookie), CookieUtils.getCsrfTokenFromCookie(cookie), - new ServiceCallback() { - @Override - public void onSuccess(final String result) { - onRefresh(); - } - - @Override - public void onFailure(final Throwable t) { + CoroutineUtilsKt.getContinuation((result, t) -> { + if (t != null) { Log.e(TAG, "Error creating collection", t); Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); + return; } - }); + onRefresh(); + }) + ); }) .setNegativeButton(R.string.cancel, null) .show(); @@ -174,20 +172,16 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa private void fetchTopics(final String maxId) { binding.swipeRefreshLayout.setRefreshing(true); - profileService.fetchCollections(maxId, new ServiceCallback() { - @Override - public void onSuccess(final CollectionsListResponse result) { - if (result == null) return; - savedCollectionsViewModel.getList().postValue(result.getItems()); - binding.swipeRefreshLayout.setRefreshing(false); - } - - @Override - public void onFailure(final Throwable t) { + profileRepository.fetchCollections(maxId, CoroutineUtilsKt.getContinuation((result, t) -> { + if (t != null) { Log.e(TAG, "onFailure", t); binding.swipeRefreshLayout.setRefreshing(false); + return; } - }); + if (result == null) return; + savedCollectionsViewModel.getList().postValue(result.getItems()); + binding.swipeRefreshLayout.setRefreshing(false); + })); } private void setNavControllerResult(@NonNull final NavController navController, final String result) { diff --git a/app/src/main/java/awais/instagrabber/repositories/ProfileRepository.java b/app/src/main/java/awais/instagrabber/repositories/ProfileRepository.java deleted file mode 100644 index 38fdffc7..00000000 --- a/app/src/main/java/awais/instagrabber/repositories/ProfileRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package awais.instagrabber.repositories; - -import java.util.Map; - -import awais.instagrabber.repositories.responses.WrappedFeedResponse; -import awais.instagrabber.repositories.responses.saved.CollectionsListResponse; -import awais.instagrabber.repositories.responses.UserFeedResponse; -import retrofit2.Call; -import retrofit2.http.FieldMap; -import retrofit2.http.FormUrlEncoded; -import retrofit2.http.GET; -import retrofit2.http.Path; -import retrofit2.http.POST; -import retrofit2.http.QueryMap; - -public interface ProfileRepository { - - @GET("/api/v1/feed/user/{uid}/") - Call fetch(@Path("uid") final long uid, @QueryMap Map queryParams); - - @GET("/api/v1/feed/saved/") - Call fetchSaved(@QueryMap Map queryParams); - - @GET("/api/v1/feed/collection/{collectionId}/") - Call fetchSavedCollection(@Path("collectionId") final String collectionId, - @QueryMap Map queryParams); - - @GET("/api/v1/feed/liked/") - Call fetchLiked(@QueryMap Map queryParams); - - @GET("/api/v1/usertags/{profileId}/feed/") - Call fetchTagged(@Path("profileId") final long profileId, @QueryMap Map queryParams); - - @GET("/api/v1/collections/list/") - Call fetchCollections(@QueryMap Map queryParams); - - @FormUrlEncoded - @POST("/api/v1/collections/create/") - Call createCollection(@FieldMap Map signedForm); -} diff --git a/app/src/main/java/awais/instagrabber/repositories/ProfileService.kt b/app/src/main/java/awais/instagrabber/repositories/ProfileService.kt new file mode 100644 index 00000000..1ffe7adf --- /dev/null +++ b/app/src/main/java/awais/instagrabber/repositories/ProfileService.kt @@ -0,0 +1,40 @@ +package awais.instagrabber.repositories + +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.* + +interface ProfileService { + @GET("/api/v1/feed/user/{uid}/") + suspend fun fetch( + @Path("uid") uid: Long, + @QueryMap queryParams: Map? + ): UserFeedResponse? + + @GET("/api/v1/feed/saved/") + suspend fun fetchSaved(@QueryMap queryParams: Map?): WrappedFeedResponse? + + @GET("/api/v1/feed/collection/{collectionId}/") + suspend fun fetchSavedCollection( + @Path("collectionId") collectionId: String?, + @QueryMap queryParams: Map? + ): WrappedFeedResponse? + + @GET("/api/v1/feed/liked/") + suspend fun fetchLiked(@QueryMap queryParams: Map?): UserFeedResponse? + + @GET("/api/v1/usertags/{profileId}/feed/") + suspend fun fetchTagged( + @Path("profileId") profileId: Long, + @QueryMap queryParams: Map? + ): UserFeedResponse? + + @GET("/api/v1/collections/list/") + suspend fun fetchCollections(@QueryMap queryParams: Map?): CollectionsListResponse? + + @FormUrlEncoded + @POST("/api/v1/collections/create/") + suspend fun createCollection(@FieldMap signedForm: Map?): String? +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/CollectionService.java b/app/src/main/java/awais/instagrabber/webservices/CollectionService.java index b237367a..d2fd7de7 100644 --- a/app/src/main/java/awais/instagrabber/webservices/CollectionService.java +++ b/app/src/main/java/awais/instagrabber/webservices/CollectionService.java @@ -18,7 +18,7 @@ import retrofit2.Callback; import retrofit2.Response; public class CollectionService { - private static final String TAG = "ProfileService"; + private static final String TAG = "CollectionService"; private final CollectionRepository repository; private final String deviceUuid, csrfToken; diff --git a/app/src/main/java/awais/instagrabber/webservices/ProfileRepository.kt b/app/src/main/java/awais/instagrabber/webservices/ProfileRepository.kt new file mode 100644 index 00000000..ea3558f1 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/webservices/ProfileRepository.kt @@ -0,0 +1,121 @@ +package awais.instagrabber.webservices + +import awais.instagrabber.repositories.ProfileService +import awais.instagrabber.repositories.responses.Media +import awais.instagrabber.repositories.responses.PostsFetchResponse +import awais.instagrabber.repositories.responses.WrappedMedia +import awais.instagrabber.repositories.responses.saved.CollectionsListResponse +import awais.instagrabber.utils.Utils +import com.google.common.collect.ImmutableMap +import java.util.* +import java.util.stream.Collectors + +class ProfileRepository private constructor(private val repository: ProfileService) { + suspend fun fetchPosts( + userId: Long, + maxId: String? + ): PostsFetchResponse? { + val builder = ImmutableMap.builder() + if (!maxId.isNullOrEmpty()) { + builder.put("max_id", maxId) + } + val body = repository.fetch(userId, builder.build()) ?: return null + return PostsFetchResponse( + body.items, + body.moreAvailable, + body.nextMaxId + ) + } + + suspend fun fetchSaved(maxId: String?, collectionId: String): PostsFetchResponse? { + val builder = ImmutableMap.builder() + if (!maxId.isNullOrEmpty()) { + builder.put("max_id", maxId) + } + val userFeedResponse = if (collectionId.isNullOrEmpty() || collectionId == "ALL_MEDIA_AUTO_COLLECTION") + (repository.fetchSaved(builder.build()) ?: return null) + else repository.fetchSavedCollection(collectionId, builder.build()) ?: return null + val items = userFeedResponse.items + val posts: List = if (items == null) { + emptyList() + } else { + items.stream() + .map(WrappedMedia::media) + .filter { obj: Media? -> Objects.nonNull(obj) } + .collect(Collectors.toList()) + } + return PostsFetchResponse( + posts, + userFeedResponse.isMoreAvailable, + userFeedResponse.nextMaxId + ) + } + + suspend fun fetchCollections(maxId: String?): CollectionsListResponse? { + val builder = ImmutableMap.builder() + if (!maxId.isNullOrEmpty()) { + builder.put("max_id", maxId) + } + builder.put( + "collection_types", + "[\"ALL_MEDIA_AUTO_COLLECTION\",\"MEDIA\",\"PRODUCT_AUTO_COLLECTION\"]" + ) + return repository.fetchCollections(builder.build()) + } + + suspend fun createCollection( + name: String, + deviceUuid: String, + userId: Long, + csrfToken: String + ): String? { + val form: MutableMap = HashMap(6) + form["_csrftoken"] = csrfToken + form["_uuid"] = deviceUuid + form["_uid"] = userId + form["collection_visibility"] = + "0" // 1 for public, planned for future but currently inexistant + form["module_name"] = "collection_create" + form["name"] = name + val signedForm = Utils.sign(form) + return repository.createCollection(signedForm) + } + + suspend fun fetchLiked(maxId: String?): PostsFetchResponse? { + val builder = ImmutableMap.builder() + if (!maxId.isNullOrEmpty()) { + builder.put("max_id", maxId) + } + val userFeedResponse = repository.fetchLiked(builder.build()) ?: return null + return PostsFetchResponse( + userFeedResponse.items, + userFeedResponse.moreAvailable, + userFeedResponse.nextMaxId + ) + } + + suspend fun fetchTagged(profileId: Long, maxId: String?): PostsFetchResponse? { + val builder = ImmutableMap.builder() + if (!maxId.isNullOrEmpty()) { + builder.put("max_id", maxId) + } + val userFeedResponse = repository.fetchTagged(profileId, builder.build()) ?: return null + return PostsFetchResponse( + userFeedResponse.items, + userFeedResponse.moreAvailable, + userFeedResponse.nextMaxId + ) + } + + companion object { + @Volatile + private var INSTANCE: ProfileRepository? = null + + fun getInstance(): ProfileRepository { + return INSTANCE ?: synchronized(this) { + val service: ProfileService = RetrofitFactory.retrofit.create(ProfileService::class.java) + ProfileRepository(service).also { INSTANCE = it } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java b/app/src/main/java/awais/instagrabber/webservices/ProfileService.java deleted file mode 100644 index e8f6884c..00000000 --- a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java +++ /dev/null @@ -1,299 +0,0 @@ -package awais.instagrabber.webservices; - -import androidx.annotation.NonNull; - -import com.google.common.collect.ImmutableMap; - -import java.util.Collections; -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.ProfileRepository; -import awais.instagrabber.repositories.responses.Media; -import awais.instagrabber.repositories.responses.PostsFetchResponse; -import awais.instagrabber.repositories.responses.UserFeedResponse; -import awais.instagrabber.repositories.responses.WrappedFeedResponse; -import awais.instagrabber.repositories.responses.WrappedMedia; -import awais.instagrabber.repositories.responses.saved.CollectionsListResponse; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; - -public class ProfileService { - private static final String TAG = "ProfileService"; - - private final ProfileRepository repository; - - private static ProfileService instance; - - private ProfileService() { - repository = RetrofitFactory.INSTANCE - .getRetrofit() - .create(ProfileRepository.class); - } - - public static ProfileService getInstance() { - if (instance == null) { - instance = new ProfileService(); - } - return instance; - } - - public void fetchPosts(final long userId, - final String maxId, - final ServiceCallback callback) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!TextUtils.isEmpty(maxId)) { - builder.put("max_id", maxId); - } - final Call request = repository.fetch(userId, builder.build()); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response response) { - if (callback == null) return; - final UserFeedResponse body = response.body(); - if (body == null) { - callback.onSuccess(null); - return; - } - callback.onSuccess(new PostsFetchResponse( - body.getItems(), - body.getMoreAvailable(), - body.getNextMaxId() - )); - } - - @Override - public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - public void fetchSaved(final String maxId, - final String collectionId, - final ServiceCallback callback) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - Call request = null; - if (!TextUtils.isEmpty(maxId)) { - builder.put("max_id", maxId); - } - if (TextUtils.isEmpty(collectionId) || collectionId.equals("ALL_MEDIA_AUTO_COLLECTION")) request = repository.fetchSaved(builder.build()); - else request = repository.fetchSavedCollection(collectionId, builder.build()); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response response) { - if (callback == null) return; - final WrappedFeedResponse userFeedResponse = response.body(); - if (userFeedResponse == null) { - callback.onSuccess(null); - return; - } - final List items = userFeedResponse.getItems(); - final List posts; - if (items == null) { - posts = Collections.emptyList(); - } else { - posts = items.stream() - .map(WrappedMedia::getMedia) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } - callback.onSuccess(new PostsFetchResponse( - posts, - userFeedResponse.isMoreAvailable(), - userFeedResponse.getNextMaxId() - )); - } - - @Override - public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - public void fetchCollections(final String maxId, - final ServiceCallback callback) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!TextUtils.isEmpty(maxId)) { - builder.put("max_id", maxId); - } - builder.put("collection_types", "[\"ALL_MEDIA_AUTO_COLLECTION\",\"MEDIA\",\"PRODUCT_AUTO_COLLECTION\"]"); - final Call request = repository.fetchCollections(builder.build()); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response response) { - if (callback == null) return; - final CollectionsListResponse collectionsListResponse = response.body(); - if (collectionsListResponse == null) { - callback.onSuccess(null); - return; - } - callback.onSuccess(collectionsListResponse); - } - - @Override - public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - public void createCollection(final String name, - final String deviceUuid, - final long userId, - final String csrfToken, - final ServiceCallback callback) { - final Map form = new HashMap<>(6); - form.put("_csrftoken", csrfToken); - form.put("_uuid", deviceUuid); - form.put("_uid", userId); - form.put("collection_visibility", "0"); // 1 for public, planned for future but currently inexistant - form.put("module_name", "collection_create"); - form.put("name", name); - final Map signedForm = Utils.sign(form); - final Call request = repository.createCollection(signedForm); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response 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 call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - public void fetchLiked(final String maxId, - final ServiceCallback callback) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!TextUtils.isEmpty(maxId)) { - builder.put("max_id", maxId); - } - final Call request = repository.fetchLiked(builder.build()); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response response) { - if (callback == null) return; - final UserFeedResponse userFeedResponse = response.body(); - if (userFeedResponse == null) { - callback.onSuccess(null); - return; - } - callback.onSuccess(new PostsFetchResponse( - userFeedResponse.getItems(), - userFeedResponse.getMoreAvailable(), - userFeedResponse.getNextMaxId() - )); - } - - @Override - public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - public void fetchTagged(final long profileId, - final String maxId, - final ServiceCallback callback) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!TextUtils.isEmpty(maxId)) { - builder.put("max_id", maxId); - } - final Call request = repository.fetchTagged(profileId, builder.build()); - request.enqueue(new Callback() { - @Override - public void onResponse(@NonNull final Call call, @NonNull final Response response) { - if (callback == null) return; - final UserFeedResponse userFeedResponse = response.body(); - if (userFeedResponse == null) { - callback.onSuccess(null); - return; - } - callback.onSuccess(new PostsFetchResponse( - userFeedResponse.getItems(), - userFeedResponse.getMoreAvailable(), - userFeedResponse.getNextMaxId() - )); - } - - @Override - public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { - if (callback != null) { - callback.onFailure(t); - } - } - }); - } - - // private PostsFetchResponse parseProfilePostsResponse(final String body) throws JSONException { - // final JSONObject root = new JSONObject(body); - // final boolean moreAvailable = root.optBoolean("more_available"); - // final String nextMaxId = root.optString("next_max_id"); - // final JSONArray itemsJson = root.optJSONArray("items"); - // final List items = parseItems(itemsJson, false); - // return new PostsFetchResponse( - // items, - // moreAvailable, - // nextMaxId - // ); - // } - - // private PostsFetchResponse parseSavedPostsResponse(final String body, final boolean isInMedia) throws JSONException { - // final JSONObject root = new JSONObject(body); - // final boolean moreAvailable = root.optBoolean("more_available"); - // final String nextMaxId = root.optString("next_max_id"); - // final int numResults = root.optInt("num_results"); - // final String status = root.optString("status"); - // final JSONArray itemsJson = root.optJSONArray("items"); - // final List items = parseItems(itemsJson, isInMedia); - // return new PostsFetchResponse( - // items, - // moreAvailable, - // nextMaxId - // ); - // } - - // private List parseItems(final JSONArray items, final boolean isInMedia) throws JSONException { - // if (items == null) { - // return Collections.emptyList(); - // } - // final List feedModels = new ArrayList<>(); - // for (int i = 0; i < items.length(); i++) { - // final JSONObject itemJson = items.optJSONObject(i); - // if (itemJson == null) { - // continue; - // } - // final FeedModel feedModel = ResponseBodyUtils.parseItem(isInMedia ? itemJson.optJSONObject("media") : itemJson); - // if (feedModel != null) { - // feedModels.add(feedModel); - // } - // } - // return feedModels; - // } -}