diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.kt b/app/src/main/java/awais/instagrabber/activities/MainActivity.kt index 0ae10cdd..c921b075 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.kt +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.kt @@ -60,7 +60,6 @@ import awais.instagrabber.viewmodels.AppStateViewModel import awais.instagrabber.viewmodels.DirectInboxViewModel import awais.instagrabber.webservices.GraphQLService import awais.instagrabber.webservices.MediaService -import awais.instagrabber.webservices.RetrofitFactory import awais.instagrabber.webservices.ServiceCallback import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior @@ -300,11 +299,11 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL Log.e(TAG, "onDestroy: ", e) } unbindActivityCheckerService() - try { - RetrofitFactory.getInstance().destroy() - } catch (e: Exception) { - Log.e(TAG, "onDestroy: ", e) - } + // try { + // RetrofitFactory.getInstance().destroy() + // } catch (e: Exception) { + // Log.e(TAG, "onDestroy: ", e) + // } instance = null } diff --git a/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.kt b/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.kt index 01500793..218e231c 100644 --- a/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.kt +++ b/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.kt @@ -1,155 +1,182 @@ -package awais.instagrabber.repositories; - -import java.util.Map; - -import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; -import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectItemSeenResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThread; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadDetailsChangeResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse; -import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse; -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.Query; -import retrofit2.http.QueryMap; - -public interface DirectMessagesRepository { +package awais.instagrabber.repositories +import awais.instagrabber.repositories.responses.directmessages.* +import retrofit2.Call +import retrofit2.http.* + +interface DirectMessagesRepository { @GET("/api/v1/direct_v2/inbox/") - Call fetchInbox(@QueryMap Map queryMap); + fun fetchInbox(@QueryMap queryMap: Map): Call @GET("/api/v1/direct_v2/pending_inbox/") - Call fetchPendingInbox(@QueryMap Map queryMap); + fun fetchPendingInbox(@QueryMap queryMap: Map): Call @GET("/api/v1/direct_v2/threads/{threadId}/") - Call fetchThread(@Path("threadId") String threadId, - @QueryMap Map queryMap); + fun fetchThread( + @Path("threadId") threadId: String, + @QueryMap queryMap: Map, + ): Call @GET("/api/v1/direct_v2/get_badge_count/?no_raven=1") - Call fetchUnseenCount(); + fun fetchUnseenCount(): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/broadcast/{item}/") - Call broadcast(@Path("item") String item, - @FieldMap final Map signedForm); + fun broadcast( + @Path("item") item: String, + @FieldMap signedForm: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/add_user/") - Call addUsers(@Path("threadId") String threadId, - @FieldMap final Map form); + fun addUsers( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/remove_users/") - Call removeUsers(@Path("threadId") String threadId, - @FieldMap final Map form); + fun removeUsers( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/update_title/") - Call updateTitle(@Path("threadId") String threadId, - @FieldMap final Map form); + fun updateTitle( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/add_admins/") - Call addAdmins(@Path("threadId") String threadId, - @FieldMap final Map form); + fun addAdmins( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/remove_admins/") - Call removeAdmins(@Path("threadId") String threadId, - @FieldMap final Map form); + fun removeAdmins( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/items/{itemId}/delete/") - Call deleteItem(@Path("threadId") String threadId, - @Path("itemId") String itemId, - @FieldMap final Map form); + fun deleteItem( + @Path("threadId") threadId: String, + @Path("itemId") itemId: String, + @FieldMap form: Map, + ): Call @GET("/api/v1/direct_v2/ranked_recipients/") - Call rankedRecipients(@QueryMap Map queryMap); + fun rankedRecipients(@QueryMap queryMap: Map): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/broadcast/forward/") - Call forward(@FieldMap final Map form); + fun forward(@FieldMap form: Map): Call @FormUrlEncoded @POST("/api/v1/direct_v2/create_group_thread/") - Call createThread(@FieldMap final Map signedForm); + fun createThread(@FieldMap signedForm: Map): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/mute/") - Call mute(@Path("threadId") String threadId, - @FieldMap final Map form); + fun mute( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/unmute/") - Call unmute(@Path("threadId") String threadId, - @FieldMap final Map form); + fun unmute( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/mute_mentions/") - Call muteMentions(@Path("threadId") String threadId, - @FieldMap final Map form); + fun muteMentions( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/unmute_mentions/") - Call unmuteMentions(@Path("threadId") String threadId, - @FieldMap final Map form); + fun unmuteMentions( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @GET("/api/v1/direct_v2/threads/{threadId}/participant_requests/") - Call participantRequests(@Path("threadId") String threadId, - @Query("page_size") int pageSize, - @Query("cursor") String cursor); + fun participantRequests( + @Path("threadId") threadId: String, + @Query("page_size") pageSize: Int, + @Query("cursor") cursor: String?, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/approve_participant_requests/") - Call approveParticipantRequests(@Path("threadId") String threadId, - @FieldMap final Map form); + fun approveParticipantRequests( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/deny_participant_requests/") - Call declineParticipantRequests(@Path("threadId") String threadId, - @FieldMap final Map form); + fun declineParticipantRequests( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/approval_required_for_new_members/") - Call approvalRequired(@Path("threadId") String threadId, - @FieldMap final Map form); + fun approvalRequired( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/approval_not_required_for_new_members/") - Call approvalNotRequired(@Path("threadId") String threadId, - @FieldMap final Map form); + fun approvalNotRequired( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/leave/") - Call leave(@Path("threadId") String threadId, - @FieldMap final Map form); + fun leave( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/remove_all_users/") - Call end(@Path("threadId") String threadId, - @FieldMap final Map form); + fun end( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/approve/") - Call approveRequest(@Path("threadId") String threadId, - @FieldMap final Map form); + fun approveRequest( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/decline/") - Call declineRequest(@Path("threadId") String threadId, - @FieldMap final Map form); + fun declineRequest( + @Path("threadId") threadId: String, + @FieldMap form: Map, + ): Call @FormUrlEncoded @POST("/api/v1/direct_v2/threads/{threadId}/items/{itemId}/seen/") - Call markItemSeen(@Path("threadId") String threadId, - @Path("itemId") String itemId, - @FieldMap final Map form); -} + fun markItemSeen( + @Path("threadId") threadId: String, + @Path("itemId") itemId: String, + @FieldMap form: Map, + ): Call +} \ 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 e0c50dc2..e4db2223 100644 --- a/app/src/main/java/awais/instagrabber/webservices/CollectionService.java +++ b/app/src/main/java/awais/instagrabber/webservices/CollectionService.java @@ -32,7 +32,7 @@ public class CollectionService extends BaseService { this.deviceUuid = deviceUuid; this.csrfToken = csrfToken; this.userId = userId; - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(CollectionRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt index c5ec9f8b..5be3c91d 100644 --- a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt +++ b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt @@ -1,476 +1,483 @@ -package awais.instagrabber.webservices; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.google.common.collect.ImmutableMap; - -import org.json.JSONArray; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -import awais.instagrabber.repositories.DirectMessagesRepository; -import awais.instagrabber.repositories.requests.directmessages.AnimatedMediaBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.LinkBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.MediaShareBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.PhotoBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.ReactionBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.StoryReplyBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.TextBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.ThreadIdOrUserIds; -import awais.instagrabber.repositories.requests.directmessages.VideoBroadcastOptions; -import awais.instagrabber.repositories.requests.directmessages.VoiceBroadcastOptions; -import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; -import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectItem; -import awais.instagrabber.repositories.responses.directmessages.DirectItemSeenResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThread; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadDetailsChangeResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse; -import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse; -import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse; -import awais.instagrabber.repositories.responses.giphy.GiphyGif; -import awais.instagrabber.utils.TextUtils; -import awais.instagrabber.utils.Utils; -import retrofit2.Call; - -public class DirectMessagesService extends BaseService { - private static final String TAG = "DiscoverService"; - - private static DirectMessagesService instance; - - private final DirectMessagesRepository repository; - private final String csrfToken; - private final long userId; - private final String deviceUuid; - - private DirectMessagesService(@NonNull final String csrfToken, - final long userId, - @NonNull final String deviceUuid) { - this.csrfToken = csrfToken; - this.userId = userId; - this.deviceUuid = deviceUuid; - repository = RetrofitFactory.getInstance() - .getRetrofit() - .create(DirectMessagesRepository.class); - } - - public String getCsrfToken() { - return csrfToken; - } - - public long getUserId() { - return userId; - } - - public String getDeviceUuid() { - return deviceUuid; - } - - public static DirectMessagesService getInstance(@NonNull final String csrfToken, - final long userId, - @NonNull final String deviceUuid) { - if (instance == null - || !Objects.equals(instance.getCsrfToken(), csrfToken) - || !Objects.equals(instance.getUserId(), userId) - || !Objects.equals(instance.getDeviceUuid(), deviceUuid)) { - instance = new DirectMessagesService(csrfToken, userId, deviceUuid); +package awais.instagrabber.webservices + +import awais.instagrabber.repositories.DirectMessagesRepository +import awais.instagrabber.repositories.requests.directmessages.* +import awais.instagrabber.repositories.responses.directmessages.* +import awais.instagrabber.repositories.responses.giphy.GiphyGif +import awais.instagrabber.utils.TextUtils.extractUrls +import awais.instagrabber.utils.TextUtils.isEmpty +import awais.instagrabber.utils.Utils +import org.json.JSONArray +import retrofit2.Call +import java.util.* + +class DirectMessagesService private constructor( + val csrfToken: String, + val userId: Long, + val deviceUuid: String, +) : BaseService() { + private val repository: DirectMessagesRepository = RetrofitFactory.retrofit.create(DirectMessagesRepository::class.java) + + fun fetchInbox( + cursor: String?, + seqId: Long, + ): Call { + val queryMap = mutableMapOf( + "visual_message_return_type" to "unseen", + "thread_message_limit" to 10.toString(), + "persistentBadging" to true.toString(), + "limit" to 10.toString(), + ) + if (!cursor.isNullOrBlank()) { + queryMap["cursor"] = cursor + queryMap["direction"] = "older" } - return instance; - } - - public Call fetchInbox(final String cursor, - final long seqId) { - final ImmutableMap.Builder queryMapBuilder = ImmutableMap.builder() - .put("visual_message_return_type", "unseen") - .put("thread_message_limit", 10) - .put("persistentBadging", true) - .put("limit", 10); - if (!TextUtils.isEmpty(cursor)) { - queryMapBuilder.put("cursor", cursor); - queryMapBuilder.put("direction", "older"); + if (seqId != 0L) { + queryMap["seq_id"] = seqId.toString() } - if (seqId != 0) { - queryMapBuilder.put("seq_id", seqId); + return repository.fetchInbox(queryMap) + } + + fun fetchThread( + threadId: String, + cursor: String?, + ): Call { + val queryMap = mutableMapOf( + "visual_message_return_type" to "unseen", + "limit" to 20.toString(), + "direction" to "older", + ) + if (!cursor.isNullOrBlank()) { + queryMap["cursor"] = cursor } - return repository.fetchInbox(queryMapBuilder.build()); + return repository.fetchThread(threadId, queryMap) } - public Call fetchThread(final String threadId, - final String cursor) { - final ImmutableMap.Builder queryMapBuilder = ImmutableMap.builder() - .put("visual_message_return_type", "unseen") - .put("limit", 20) - .put("direction", "older"); - if (!TextUtils.isEmpty(cursor)) { - queryMapBuilder.put("cursor", cursor); - } - return repository.fetchThread(threadId, queryMapBuilder.build()); - } - - public Call fetchUnseenCount() { - return repository.fetchUnseenCount(); + fun fetchUnseenCount(): Call { + return repository.fetchUnseenCount() } - public Call broadcastText(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String text, - @Nullable final String repliedToItemId, - @Nullable final String repliedToClientContext) { - final List urls = TextUtils.extractUrls(text); - if (!urls.isEmpty()) { - return broadcastLink(clientContext, threadIdOrUserIds, text, urls, repliedToItemId, repliedToClientContext); + fun broadcastText( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + text: String, + repliedToItemId: String?, + repliedToClientContext: String?, + ): Call { + val urls = extractUrls(text) + if (urls.isNotEmpty()) { + return broadcastLink(clientContext, threadIdOrUserIds, text, urls, repliedToItemId, repliedToClientContext) } - final TextBroadcastOptions broadcastOptions = new TextBroadcastOptions(clientContext, threadIdOrUserIds, text); - if (repliedToItemId != null && repliedToClientContext != null) { - broadcastOptions.setRepliedToItemId(repliedToItemId); - broadcastOptions.setRepliedToClientContext(repliedToClientContext); + val broadcastOptions = TextBroadcastOptions(clientContext, threadIdOrUserIds, text) + if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { + broadcastOptions.repliedToItemId = repliedToItemId + broadcastOptions.repliedToClientContext = repliedToClientContext } - return broadcast(broadcastOptions); - } - - public Call broadcastLink(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String linkText, - @NonNull final List urls, - @Nullable final String repliedToItemId, - @Nullable final String repliedToClientContext) { - final LinkBroadcastOptions broadcastOptions = new LinkBroadcastOptions(clientContext, threadIdOrUserIds, linkText, urls); - if (repliedToItemId != null && repliedToClientContext != null) { - broadcastOptions.setRepliedToItemId(repliedToItemId); - broadcastOptions.setRepliedToClientContext(repliedToClientContext); + return broadcast(broadcastOptions) + } + + private fun broadcastLink( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + linkText: String, + urls: List, + repliedToItemId: String?, + repliedToClientContext: String?, + ): Call { + val broadcastOptions = LinkBroadcastOptions(clientContext, threadIdOrUserIds, linkText, urls) + if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { + broadcastOptions.repliedToItemId = repliedToItemId + broadcastOptions.repliedToClientContext = repliedToClientContext } - return broadcast(broadcastOptions); - } - - public Call broadcastPhoto(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String uploadId) { - return broadcast(new PhotoBroadcastOptions(clientContext, threadIdOrUserIds, true, uploadId)); - } - - public Call broadcastVideo(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String uploadId, - @NonNull final String videoResult, - final boolean sampled) { - return broadcast(new VideoBroadcastOptions(clientContext, threadIdOrUserIds, videoResult, uploadId, sampled)); - } - - public Call broadcastVoice(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String uploadId, - @NonNull final List waveform, - final int samplingFreq) { - return broadcast(new VoiceBroadcastOptions(clientContext, threadIdOrUserIds, uploadId, waveform, samplingFreq)); - } - - public Call broadcastStoryReply(@NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String text, - @NonNull final String mediaId, - @NonNull final String reelId) { - return broadcast(new StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdOrUserIds, text, mediaId, reelId)); - } - - public Call broadcastReaction(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String itemId, - @Nullable final String emoji, - final boolean delete) { - return broadcast(new ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete)); - } - - public Call broadcastAnimatedMedia(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final GiphyGif giphyGif) { - return broadcast(new AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif)); - } - - public Call broadcastMediaShare(@NonNull final String clientContext, - @NonNull final ThreadIdOrUserIds threadIdOrUserIds, - @NonNull final String mediaId) { - return broadcast(new MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId)); - } - - private Call broadcast(@NonNull final BroadcastOptions broadcastOptions) { - if (TextUtils.isEmpty(broadcastOptions.getClientContext())) { - throw new IllegalArgumentException("Broadcast requires a valid client context value"); - } - final Map form = new HashMap<>(); - if (!TextUtils.isEmpty(broadcastOptions.getThreadId())) { - form.put("thread_id", broadcastOptions.getThreadId()); + return broadcast(broadcastOptions) + } + + fun broadcastPhoto( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + uploadId: String, + ): Call { + return broadcast(PhotoBroadcastOptions(clientContext, threadIdOrUserIds, true, uploadId)) + } + + fun broadcastVideo( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + uploadId: String, + videoResult: String, + sampled: Boolean, + ): Call { + return broadcast(VideoBroadcastOptions(clientContext, threadIdOrUserIds, videoResult, uploadId, sampled)) + } + + fun broadcastVoice( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + uploadId: String, + waveform: List, + samplingFreq: Int, + ): Call { + return broadcast(VoiceBroadcastOptions(clientContext, threadIdOrUserIds, uploadId, waveform, samplingFreq)) + } + + fun broadcastStoryReply( + threadIdOrUserIds: ThreadIdOrUserIds, + text: String, + mediaId: String, + reelId: String, + ): Call { + return broadcast(StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdOrUserIds, text, mediaId, reelId)) + } + + fun broadcastReaction( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + itemId: String, + emoji: String?, + delete: Boolean, + ): Call { + return broadcast(ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete)) + } + + fun broadcastAnimatedMedia( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + giphyGif: GiphyGif, + ): Call { + return broadcast(AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif)) + } + + fun broadcastMediaShare( + clientContext: String, + threadIdOrUserIds: ThreadIdOrUserIds, + mediaId: String, + ): Call { + return broadcast(MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId)) + } + + private fun broadcast(broadcastOptions: BroadcastOptions): Call { + require(!isEmpty(broadcastOptions.clientContext)) { "Broadcast requires a valid client context value" } + val form = mutableMapOf() + val threadId = broadcastOptions.threadId + if (!threadId.isNullOrBlank()) { + form["thread_id"] = threadId } else { - form.put("recipient_users", new JSONArray(broadcastOptions.getUserIds()).toString()); + val userIds = broadcastOptions.userIds + require(!userIds.isNullOrEmpty()) { + "Either provide a thread id or pass a list of user ids" + } + form["recipient_users"] = JSONArray(userIds).toString() } - form.put("_csrftoken", csrfToken); - form.put("_uid", userId); - form.put("__uuid", deviceUuid); - form.put("client_context", broadcastOptions.getClientContext()); - form.put("mutation_token", broadcastOptions.getClientContext()); - if (!TextUtils.isEmpty(broadcastOptions.getRepliedToItemId()) && !TextUtils.isEmpty(broadcastOptions.getRepliedToClientContext())) { - form.put("replied_to_item_id", broadcastOptions.getRepliedToItemId()); - form.put("replied_to_client_context", broadcastOptions.getRepliedToClientContext()); + form["_csrftoken"] = csrfToken + form["_uid"] = userId + form["__uuid"] = deviceUuid + form["client_context"] = broadcastOptions.clientContext + form["mutation_token"] = broadcastOptions.clientContext + val repliedToItemId = broadcastOptions.repliedToItemId + val repliedToClientContext = broadcastOptions.repliedToClientContext + if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { + form["replied_to_item_id"] = repliedToItemId + form["replied_to_client_context"] = repliedToClientContext } - form.putAll(broadcastOptions.getFormMap()); - form.put("action", "send_item"); - final Map signedForm = Utils.sign(form); - return repository.broadcast(broadcastOptions.getItemType().getValue(), signedForm); - } - - public Call addUsers(final String threadId, - final Collection userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - ); - return repository.addUsers(threadId, form); - } - - public Call removeUsers(final String threadId, - final Collection userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - ); - return repository.removeUsers(threadId, form); - } - - public Call updateTitle(final String threadId, - final String title) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "title", title - ); - return repository.updateTitle(threadId, form); - } - - public Call addAdmins(final String threadId, - final Collection userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - ); - return repository.addAdmins(threadId, form); - } - - public Call removeAdmins(final String threadId, - final Collection userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - ); - return repository.removeAdmins(threadId, form); - } - - public Call deleteItem(final String threadId, - final String itemId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.deleteItem(threadId, itemId, form); - } - - public Call rankedRecipients(@Nullable final String mode, - @Nullable final Boolean showThreads, - @Nullable final String query) { + form.putAll(broadcastOptions.formMap) + form["action"] = "send_item" + val signedForm = Utils.sign(form) + return repository.broadcast(broadcastOptions.itemType.value, signedForm) + } + + fun addUsers( + threadId: String, + userIds: Collection, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + ) + return repository.addUsers(threadId, form) + } + + fun removeUsers( + threadId: String, + userIds: Collection, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + ) + return repository.removeUsers(threadId, form) + } + + fun updateTitle( + threadId: String, + title: String, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "title" to title, + ) + return repository.updateTitle(threadId, form) + } + + fun addAdmins( + threadId: String, + userIds: Collection, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + ) + return repository.addAdmins(threadId, form) + } + + fun removeAdmins( + threadId: String, + userIds: Collection, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + ) + return repository.removeAdmins(threadId, form) + } + + fun deleteItem( + threadId: String, + itemId: String, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.deleteItem(threadId, itemId, form) + } + + fun rankedRecipients( + mode: String?, + showThreads: Boolean?, + query: String?, + ): Call { // String correctedMode = mode; // if (TextUtils.isEmpty(mode) || (!mode.equals("raven") && !mode.equals("reshare"))) { // correctedMode = "raven"; // } - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (mode != null) { - builder.put("mode", mode); + val queryMap = mutableMapOf() + if (!mode.isNullOrBlank()) { + queryMap["mode"] = mode } - if (query != null) { - builder.put("query", query); + if (!query.isNullOrBlank()) { + queryMap["query"] = query } if (showThreads != null) { - builder.put("showThreads", String.valueOf(showThreads)); + queryMap["showThreads"] = showThreads.toString() + } + return repository.rankedRecipients(queryMap) + } + + fun forward( + toThreadId: String, + itemType: String, + fromThreadId: String, + itemId: String, + ): Call { + val form = mapOf( + "action" to "forward_item", + "thread_id" to toThreadId, + "item_type" to itemType, + "forwarded_from_thread_id" to fromThreadId, + "forwarded_from_thread_item_id" to itemId, + ) + return repository.forward(form) + } + + fun createThread( + userIds: List, + threadTitle: String?, + ): Call { + val userIdStringList = userIds.asSequence() + .filterNotNull() + .map { it.toString() } + val form = mutableMapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "_uid" to userId, + "recipient_users" to JSONArray(userIdStringList).toString(), + ) + if (!threadTitle.isNullOrBlank()) { + form["thread_title"] = threadTitle } - return repository.rankedRecipients(builder.build()); - } - - public Call forward(@NonNull final String toThreadId, - @NonNull final String itemType, - @NonNull final String fromThreadId, - @NonNull final String itemId) { - final ImmutableMap form = ImmutableMap.of( - "action", "forward_item", - "thread_id", toThreadId, - "item_type", itemType, - "forwarded_from_thread_id", fromThreadId, - "forwarded_from_thread_item_id", itemId - ); - return repository.forward(form); - } - - public Call createThread(@NonNull final List userIds, - @Nullable final String threadTitle) { - final List userIdStringList = userIds.stream() - .filter(Objects::nonNull) - .map(String::valueOf) - .collect(Collectors.toList()); - final ImmutableMap.Builder formBuilder = ImmutableMap.builder() - .put("_csrftoken", csrfToken) - .put("_uuid", deviceUuid) - .put("_uid", userId) - .put("recipient_users", new JSONArray(userIdStringList).toString()); - if (threadTitle != null) { - formBuilder.put("thread_title", threadTitle); + val signedForm = Utils.sign(form) + return repository.createThread(signedForm) + } + + fun mute(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid + ) + return repository.mute(threadId, form) + } + + fun unmute(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.unmute(threadId, form) + } + + fun muteMentions(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.muteMentions(threadId, form) + } + + fun unmuteMentions(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.unmuteMentions(threadId, form) + } + + fun participantRequests( + threadId: String, + pageSize: Int, + cursor: String?, + ): Call { + return repository.participantRequests(threadId, pageSize, cursor) + } + + fun approveParticipantRequests( + threadId: String, + userIds: List, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + // "share_join_chat_story" to String.valueOf(true) + ) + return repository.approveParticipantRequests(threadId, form) + } + + fun declineParticipantRequests( + threadId: String, + userIds: List, + ): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "user_ids" to JSONArray(userIds).toString(), + ) + return repository.declineParticipantRequests(threadId, form) + } + + fun approvalRequired(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.approvalRequired(threadId, form) + } + + fun approvalNotRequired(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.approvalNotRequired(threadId, form) + } + + fun leave(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.leave(threadId, form) + } + + fun end(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.end(threadId, form) + } + + fun fetchPendingInbox(cursor: String?, seqId: Long): Call { + val queryMap = mutableMapOf( + "visual_message_return_type" to "unseen", + "thread_message_limit" to 20.toString(), + "persistentBadging" to true.toString(), + "limit" to 10.toString(), + ) + if (!cursor.isNullOrBlank()) { + queryMap["cursor"] = cursor + queryMap["direction"] = "older" } - final Map signedForm = Utils.sign(formBuilder.build()); - return repository.createThread(signedForm); - } - - public Call mute(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.mute(threadId, form); - } - - public Call unmute(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.unmute(threadId, form); - } - - public Call muteMentions(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.muteMentions(threadId, form); - } - - public Call unmuteMentions(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.unmuteMentions(threadId, form); - } - - public Call participantRequests(@NonNull final String threadId, - final int pageSize, - @Nullable final String cursor) { - return repository.participantRequests(threadId, pageSize, cursor); - } - - public Call approveParticipantRequests(@NonNull final String threadId, - @NonNull final List userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - // , "share_join_chat_story", String.valueOf(true) - ); - return repository.approveParticipantRequests(threadId, form); - } - - public Call declineParticipantRequests(@NonNull final String threadId, - @NonNull final List userIds) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid, - "user_ids", new JSONArray(userIds).toString() - ); - return repository.declineParticipantRequests(threadId, form); - } - - public Call approvalRequired(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.approvalRequired(threadId, form); - } - - public Call approvalNotRequired(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.approvalNotRequired(threadId, form); - } - - public Call leave(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.leave(threadId, form); - } - - public Call end(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.end(threadId, form); - } - - public Call fetchPendingInbox(final String cursor, final long seqId) { - final ImmutableMap.Builder queryMapBuilder = ImmutableMap.builder() - .put("visual_message_return_type", "unseen") - .put("thread_message_limit", 20) - .put("persistentBadging", true) - .put("limit", 10); - if (!TextUtils.isEmpty(cursor)) { - queryMapBuilder.put("cursor", cursor); - queryMapBuilder.put("direction", "older"); + if (seqId != 0L) { + queryMap["seq_id"] = seqId.toString() } - if (seqId != 0) { - queryMapBuilder.put("seq_id", seqId); + return repository.fetchPendingInbox(queryMap) + } + + fun approveRequest(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.approveRequest(threadId, form) + } + + fun declineRequest(threadId: String): Call { + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + ) + return repository.declineRequest(threadId, form) + } + + fun markAsSeen( + threadId: String, + directItem: DirectItem, + ): Call? { + val itemId = directItem.itemId ?: return null + val form = mapOf( + "_csrftoken" to csrfToken, + "_uuid" to deviceUuid, + "use_unified_inbox" to "true", + "action" to "mark_seen", + "thread_id" to threadId, + "item_id" to itemId, + ) + return repository.markItemSeen(threadId, itemId, form) + } + + companion object { + private lateinit var instance: DirectMessagesService + + @JvmStatic + fun getInstance( + csrfToken: String, + userId: Long, + deviceUuid: String, + ): DirectMessagesService { + if (!this::instance.isInitialized + || instance.csrfToken != csrfToken + || instance.userId != userId + || instance.deviceUuid != deviceUuid + ) { + instance = DirectMessagesService(csrfToken, userId, deviceUuid) + } + return instance } - return repository.fetchPendingInbox(queryMapBuilder.build()); - } - - public Call approveRequest(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.approveRequest(threadId, form); - } - - public Call declineRequest(@NonNull final String threadId) { - final ImmutableMap form = ImmutableMap.of( - "_csrftoken", csrfToken, - "_uuid", deviceUuid - ); - return repository.declineRequest(threadId, form); - } - - @Nullable - public Call markAsSeen(@NonNull final String threadId, - @NonNull final DirectItem directItem) { - if (directItem.getItemId() == null) return null; - final ImmutableMap form = ImmutableMap.builder() - .put("_csrftoken", csrfToken) - .put("_uuid", deviceUuid) - .put("use_unified_inbox", "true") - .put("action", "mark_seen") - .put("thread_id", threadId) - .put("item_id", directItem.getItemId()) - .build(); - return repository.markItemSeen(threadId, directItem.getItemId(), form); - } -} + } + +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/DiscoverService.java b/app/src/main/java/awais/instagrabber/webservices/DiscoverService.java index 6f00df93..f893a2fb 100644 --- a/app/src/main/java/awais/instagrabber/webservices/DiscoverService.java +++ b/app/src/main/java/awais/instagrabber/webservices/DiscoverService.java @@ -22,7 +22,7 @@ public class DiscoverService extends BaseService { private static DiscoverService instance; private DiscoverService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(DiscoverRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/FeedService.java b/app/src/main/java/awais/instagrabber/webservices/FeedService.java index 3ed9e7b6..330be0d7 100644 --- a/app/src/main/java/awais/instagrabber/webservices/FeedService.java +++ b/app/src/main/java/awais/instagrabber/webservices/FeedService.java @@ -31,7 +31,7 @@ public class FeedService extends BaseService { private static FeedService instance; private FeedService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(FeedRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/FriendshipService.java b/app/src/main/java/awais/instagrabber/webservices/FriendshipService.java index c363a865..ce20dd29 100644 --- a/app/src/main/java/awais/instagrabber/webservices/FriendshipService.java +++ b/app/src/main/java/awais/instagrabber/webservices/FriendshipService.java @@ -41,7 +41,7 @@ public class FriendshipService extends BaseService { this.deviceUuid = deviceUuid; this.csrfToken = csrfToken; this.userId = userId; - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(FriendshipRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/GifService.java b/app/src/main/java/awais/instagrabber/webservices/GifService.java index e783f689..3e66aa74 100644 --- a/app/src/main/java/awais/instagrabber/webservices/GifService.java +++ b/app/src/main/java/awais/instagrabber/webservices/GifService.java @@ -11,7 +11,7 @@ public class GifService extends BaseService { private static GifService instance; private GifService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(GifRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/GraphQLService.java b/app/src/main/java/awais/instagrabber/webservices/GraphQLService.java index 9c56110c..1283fdda 100644 --- a/app/src/main/java/awais/instagrabber/webservices/GraphQLService.java +++ b/app/src/main/java/awais/instagrabber/webservices/GraphQLService.java @@ -40,7 +40,7 @@ public class GraphQLService extends BaseService { private static GraphQLService instance; private GraphQLService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofitWeb() .create(GraphQLRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/LocationService.java b/app/src/main/java/awais/instagrabber/webservices/LocationService.java index aca6ef47..44059c89 100644 --- a/app/src/main/java/awais/instagrabber/webservices/LocationService.java +++ b/app/src/main/java/awais/instagrabber/webservices/LocationService.java @@ -22,7 +22,7 @@ public class LocationService extends BaseService { private static LocationService instance; private LocationService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(LocationRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/MediaService.java b/app/src/main/java/awais/instagrabber/webservices/MediaService.java index b2090d0f..2e9dd604 100644 --- a/app/src/main/java/awais/instagrabber/webservices/MediaService.java +++ b/app/src/main/java/awais/instagrabber/webservices/MediaService.java @@ -54,7 +54,7 @@ public class MediaService extends BaseService { this.deviceUuid = deviceUuid; this.csrfToken = csrfToken; this.userId = userId; - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(MediaRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/NewsService.java b/app/src/main/java/awais/instagrabber/webservices/NewsService.java index 580e2c04..eccdcf22 100644 --- a/app/src/main/java/awais/instagrabber/webservices/NewsService.java +++ b/app/src/main/java/awais/instagrabber/webservices/NewsService.java @@ -31,7 +31,7 @@ public class NewsService extends BaseService { private static NewsService instance; private NewsService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(NewsRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java b/app/src/main/java/awais/instagrabber/webservices/ProfileService.java index cc8199fd..1f83e1f9 100644 --- a/app/src/main/java/awais/instagrabber/webservices/ProfileService.java +++ b/app/src/main/java/awais/instagrabber/webservices/ProfileService.java @@ -32,7 +32,7 @@ public class ProfileService extends BaseService { private static ProfileService instance; private ProfileService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(ProfileRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/RetrofitFactory.kt b/app/src/main/java/awais/instagrabber/webservices/RetrofitFactory.kt index 6c0cc17d..876a89b9 100644 --- a/app/src/main/java/awais/instagrabber/webservices/RetrofitFactory.kt +++ b/app/src/main/java/awais/instagrabber/webservices/RetrofitFactory.kt @@ -1,98 +1,57 @@ -package awais.instagrabber.webservices; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import java.io.File; - -import awais.instagrabber.BuildConfig; -import awais.instagrabber.repositories.responses.Caption; -import awais.instagrabber.repositories.serializers.CaptionDeserializer; -import awais.instagrabber.utils.Utils; -import awais.instagrabber.webservices.interceptors.AddCookiesInterceptor; -import awais.instagrabber.webservices.interceptors.IgErrorsInterceptor; -import okhttp3.Cache; -import okhttp3.OkHttpClient; -import retrofit2.Retrofit; -import retrofit2.converter.gson.GsonConverterFactory; -import retrofit2.converter.scalars.ScalarsConverterFactory; - -public final class RetrofitFactory { - private static final Object LOCK = new Object(); - - private static RetrofitFactory instance; - - private final int cacheSize = 10 * 1024 * 1024; // 10 MB - private final Cache cache = new Cache(new File(Utils.cacheDir), cacheSize); - - private IgErrorsInterceptor igErrorsInterceptor; - private Retrofit.Builder builder; - private Retrofit retrofit; - private Retrofit retrofitWeb; - - public static RetrofitFactory getInstance() { - if (instance == null) { - synchronized (LOCK) { - if (instance == null) { - instance = new RetrofitFactory(); - } - } - } - return instance; - } - - private Retrofit.Builder getRetrofitBuilder() { - if (builder == null) { - igErrorsInterceptor = new IgErrorsInterceptor(); - final OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() - .followRedirects(false) - .followSslRedirects(false) - .cache(cache); +package awais.instagrabber.webservices + +import awais.instagrabber.BuildConfig +import awais.instagrabber.repositories.responses.Caption +import awais.instagrabber.repositories.serializers.CaptionDeserializer +import awais.instagrabber.utils.Utils +import awais.instagrabber.webservices.interceptors.AddCookiesInterceptor +import awais.instagrabber.webservices.interceptors.IgErrorsInterceptor +import com.google.gson.FieldNamingPolicy +import com.google.gson.GsonBuilder +import okhttp3.Cache +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.converter.scalars.ScalarsConverterFactory +import java.io.File + +object RetrofitFactory { + private const val cacheSize: Long = 10 * 1024 * 1024 // 10 MB + private val cache = Cache(File(Utils.cacheDir), cacheSize) + private val igErrorsInterceptor: IgErrorsInterceptor by lazy { IgErrorsInterceptor() } + + private val retrofitBuilder: Retrofit.Builder by lazy { + val clientBuilder = OkHttpClient.Builder().apply { + followRedirects(false) + followSslRedirects(false) + cache(cache) + addInterceptor(AddCookiesInterceptor()) + addInterceptor(igErrorsInterceptor) if (BuildConfig.DEBUG) { - // clientBuilder.addInterceptor(new LoggingInterceptor()); + // addInterceptor(new LoggingInterceptor()); } - clientBuilder.addInterceptor(new AddCookiesInterceptor()) - .addInterceptor(igErrorsInterceptor); - final Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .registerTypeAdapter(Caption.class, new CaptionDeserializer()) - .setLenient() - .create(); - builder = new Retrofit.Builder() - .addConverterFactory(ScalarsConverterFactory.create()) - .addConverterFactory(GsonConverterFactory.create(gson)) - .client(clientBuilder.build()); } - return builder; - } - - public Retrofit getRetrofit() { - if (retrofit == null) { - retrofit = getRetrofitBuilder() - .baseUrl("https://i.instagram.com") - .build(); + val gson = GsonBuilder().apply { + setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + registerTypeAdapter(Caption::class.java, CaptionDeserializer()) + setLenient() + }.create() + Retrofit.Builder().apply { + addConverterFactory(ScalarsConverterFactory.create()) + addConverterFactory(GsonConverterFactory.create(gson)) + client(clientBuilder.build()) } - return retrofit; } - public Retrofit getRetrofitWeb() { - if (retrofitWeb == null) { - retrofitWeb = getRetrofitBuilder() - .baseUrl("https://www.instagram.com") - .build(); - } - return retrofitWeb; + val retrofit: Retrofit by lazy { + retrofitBuilder + .baseUrl("https://i.instagram.com") + .build() } - public void destroy() { - if (igErrorsInterceptor != null) { - igErrorsInterceptor.destroy(); - } - igErrorsInterceptor = null; - retrofit = null; - retrofitWeb = null; - builder = null; - instance = null; + val retrofitWeb: Retrofit by lazy { + retrofitBuilder + .baseUrl("https://www.instagram.com") + .build() } -} +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/webservices/SearchService.java b/app/src/main/java/awais/instagrabber/webservices/SearchService.java index 4144f85d..71649cdc 100644 --- a/app/src/main/java/awais/instagrabber/webservices/SearchService.java +++ b/app/src/main/java/awais/instagrabber/webservices/SearchService.java @@ -14,7 +14,7 @@ public class SearchService extends BaseService { private static SearchService instance; private SearchService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofitWeb() .create(SearchRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java index 2b0fe81c..f72d8344 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java @@ -49,7 +49,7 @@ public class StoriesService extends BaseService { this.csrfToken = csrfToken; this.userId = userId; this.deviceUuid = deviceUuid; - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(StoriesRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/TagsService.java b/app/src/main/java/awais/instagrabber/webservices/TagsService.java index 276f0dc7..674c85c2 100644 --- a/app/src/main/java/awais/instagrabber/webservices/TagsService.java +++ b/app/src/main/java/awais/instagrabber/webservices/TagsService.java @@ -31,7 +31,7 @@ public class TagsService extends BaseService { private final TagsRepository repository; private TagsService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(TagsRepository.class); } diff --git a/app/src/main/java/awais/instagrabber/webservices/UserService.java b/app/src/main/java/awais/instagrabber/webservices/UserService.java index 1266662f..2537e6ee 100644 --- a/app/src/main/java/awais/instagrabber/webservices/UserService.java +++ b/app/src/main/java/awais/instagrabber/webservices/UserService.java @@ -21,7 +21,7 @@ public class UserService extends BaseService { private static UserService instance; private UserService() { - repository = RetrofitFactory.getInstance() + repository = RetrofitFactory.INSTANCE .getRetrofit() .create(UserRepository.class); }