mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-23 05:16:58 +00:00
Convert GraphQLRepository and GraphQLService to kotlin
This commit is contained in:
parent
dd3562116b
commit
143a0ce259
@ -49,7 +49,6 @@ import awais.instagrabber.models.IntentModel
|
||||
import awais.instagrabber.models.Resource
|
||||
import awais.instagrabber.models.Tab
|
||||
import awais.instagrabber.models.enums.IntentModelType
|
||||
import awais.instagrabber.repositories.responses.Media
|
||||
import awais.instagrabber.services.ActivityCheckerService
|
||||
import awais.instagrabber.services.DMSyncAlarmReceiver
|
||||
import awais.instagrabber.utils.*
|
||||
@ -61,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.ServiceCallback
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
@ -71,6 +69,7 @@ import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.Iterators
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
|
||||
@ -92,7 +91,6 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
|
||||
var currentTabs: List<Tab> = emptyList()
|
||||
private set
|
||||
private var showBottomViewDestinations: List<Int> = emptyList()
|
||||
private var graphQLService: GraphQLService? = null
|
||||
|
||||
private val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||
@ -633,39 +631,32 @@ class MainActivity : BaseLanguageActivity(), FragmentManager.OnBackStackChangedL
|
||||
.setCancelable(false)
|
||||
.setView(R.layout.dialog_opening_post)
|
||||
.create()
|
||||
if (graphQLService == null) graphQLService = GraphQLService.getInstance()
|
||||
val postCb: ServiceCallback<Media> = object : ServiceCallback<Media> {
|
||||
override fun onSuccess(feedModel: Media?) {
|
||||
if (feedModel != null) {
|
||||
val currentNavControllerLiveData = currentNavControllerLiveData ?: return
|
||||
alertDialog.show()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val media = if (isLoggedIn) MediaService.fetch(shortcodeToId(shortCode)) else GraphQLService.fetchPost(shortCode)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (media == null) {
|
||||
Toast.makeText(applicationContext, R.string.post_not_found, Toast.LENGTH_SHORT).show()
|
||||
return@withContext
|
||||
}
|
||||
val currentNavControllerLiveData = currentNavControllerLiveData ?: return@withContext
|
||||
val navController = currentNavControllerLiveData.value
|
||||
val bundle = Bundle()
|
||||
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel)
|
||||
bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, media)
|
||||
try {
|
||||
navController?.navigate(R.id.action_global_post_view, bundle)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "showPostView: ", e)
|
||||
}
|
||||
} else Toast.makeText(applicationContext, R.string.post_not_found, Toast.LENGTH_SHORT).show()
|
||||
alertDialog.dismiss()
|
||||
}
|
||||
|
||||
override fun onFailure(t: Throwable) {
|
||||
alertDialog.dismiss()
|
||||
}
|
||||
}
|
||||
alertDialog.show()
|
||||
if (isLoggedIn) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val media = MediaService.fetch(shortcodeToId(shortCode))
|
||||
postCb.onSuccess(media)
|
||||
} catch (e: Exception) {
|
||||
postCb.onFailure(e)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "showPostView: ", e)
|
||||
} finally {
|
||||
withContext(Dispatchers.Main) {
|
||||
alertDialog.dismiss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
graphQLService?.fetchPost(shortCode, postCb)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,11 @@ import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.TagsService;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final TagsService tagsService;
|
||||
@ -23,7 +25,7 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
this.hashtagModel = hashtagModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +50,17 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) tagsService.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||
else graphQLService.fetchHashtagPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||
else graphQLService.fetchHashtagPosts(
|
||||
hashtagModel.getName().toLowerCase(),
|
||||
nextMaxId,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,9 +7,11 @@ import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.LocationService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final LocationService locationService;
|
||||
@ -23,7 +25,7 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||
this.locationModel = locationModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +50,17 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) locationService.fetchPosts(locationModel.getPk(), nextMaxId, cb);
|
||||
else graphQLService.fetchLocationPosts(locationModel.getPk(), nextMaxId, cb);
|
||||
else graphQLService.fetchLocationPosts(
|
||||
locationModel.getPk(),
|
||||
nextMaxId,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,9 +7,11 @@ import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ProfileService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
||||
private static final String TAG = "ProfilePostFetchService";
|
||||
@ -23,7 +25,7 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
||||
public ProfilePostFetchService(final User profileModel, final boolean isLoggedIn) {
|
||||
this.profileModel = profileModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
||||
}
|
||||
|
||||
@ -49,7 +51,19 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) profileService.fetchPosts(profileModel.getPk(), nextMaxId, cb);
|
||||
else graphQLService.fetchProfilePosts(profileModel.getPk(), 30, nextMaxId, profileModel, cb);
|
||||
else graphQLService.fetchProfilePosts(
|
||||
profileModel.getPk(),
|
||||
30,
|
||||
nextMaxId,
|
||||
profileModel,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,9 +7,11 @@ import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.enums.PostItemType;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ProfileService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final ProfileService profileService;
|
||||
@ -27,7 +29,7 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
||||
this.type = type;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
this.collectionId = collectionId;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
||||
}
|
||||
|
||||
@ -58,7 +60,18 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
||||
break;
|
||||
case TAGGED:
|
||||
if (isLoggedIn) profileService.fetchTagged(profileId, nextMaxId, callback);
|
||||
else graphQLService.fetchTaggedPosts(profileId, 30, nextMaxId, callback);
|
||||
else graphQLService.fetchTaggedPosts(
|
||||
profileId,
|
||||
30,
|
||||
nextMaxId,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
callback.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
callback.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
);
|
||||
break;
|
||||
case COLLECTION:
|
||||
case SAVED:
|
||||
|
@ -63,8 +63,10 @@ import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
@ -72,6 +74,7 @@ import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.StoriesService;
|
||||
import awais.instagrabber.webservices.TagsService;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
|
||||
@ -218,20 +221,15 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
if (TextUtils.isEmpty(user.getUsername())) {
|
||||
// this only happens for anons
|
||||
opening = true;
|
||||
graphQLService.fetchPost(feedModel.getCode(), new ServiceCallback<Media>() {
|
||||
@Override
|
||||
public void onSuccess(final Media newFeedModel) {
|
||||
opening = false;
|
||||
if (newFeedModel == null) return;
|
||||
openPostDialog(newFeedModel, profilePicView, mainPostImage, position);
|
||||
graphQLService.fetchPost(feedModel.getCode(), CoroutineUtilsKt.getContinuation((media, throwable) -> {
|
||||
opening = false;
|
||||
if (throwable != null) {
|
||||
Log.e(TAG, "Error", throwable);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
opening = false;
|
||||
Log.e(TAG, "Error", t);
|
||||
}
|
||||
});
|
||||
if (media == null) return;
|
||||
AppExecutors.INSTANCE.getMainThread().execute(() -> openPostDialog(media, profilePicView, mainPostImage, position));
|
||||
}, Dispatchers.getIO()));
|
||||
return;
|
||||
}
|
||||
opening = true;
|
||||
@ -304,7 +302,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -385,7 +383,13 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private void fetchHashtagModel() {
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
if (isLoggedIn) tagsService.fetch(hashtag, cb);
|
||||
else graphQLService.fetchTag(hashtag, cb);
|
||||
else graphQLService.fetchTag(hashtag, CoroutineUtilsKt.getContinuation((hashtag1, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
AppExecutors.INSTANCE.getMainThread().execute(() -> cb.onSuccess(hashtag1));
|
||||
}, Dispatchers.getIO()));
|
||||
}
|
||||
|
||||
private void setupPosts() {
|
||||
|
@ -113,7 +113,7 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
if (csrfToken == null) return;
|
||||
mediaService = isLoggedIn ? MediaService.INSTANCE : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
// setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -135,7 +135,17 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme
|
||||
public void onRefresh() {
|
||||
if (isComment && !isLoggedIn) {
|
||||
lazyLoader.resetState();
|
||||
graphQLService.fetchCommentLikers(postId, null, anonCb);
|
||||
graphQLService.fetchCommentLikers(
|
||||
postId,
|
||||
null,
|
||||
CoroutineUtilsKt.getContinuation((response, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
anonCb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
anonCb.onSuccess(response);
|
||||
}), Dispatchers.getIO())
|
||||
);
|
||||
} else {
|
||||
mediaService.fetchLikes(
|
||||
postId,
|
||||
@ -164,8 +174,19 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme
|
||||
binding.rvLikes.setLayoutManager(layoutManager);
|
||||
binding.rvLikes.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.HORIZONTAL));
|
||||
lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
|
||||
if (!TextUtils.isEmpty(endCursor))
|
||||
graphQLService.fetchCommentLikers(postId, endCursor, anonCb);
|
||||
if (!TextUtils.isEmpty(endCursor)) {
|
||||
graphQLService.fetchCommentLikers(
|
||||
postId,
|
||||
endCursor,
|
||||
CoroutineUtilsKt.getContinuation((response, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
anonCb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
anonCb.onSuccess(response);
|
||||
}), Dispatchers.getIO())
|
||||
);
|
||||
}
|
||||
endCursor = null;
|
||||
});
|
||||
binding.rvLikes.addOnScrollListener(lazyLoader);
|
||||
|
@ -59,8 +59,10 @@ import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
@ -208,20 +210,18 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
if (user == null) return;
|
||||
if (TextUtils.isEmpty(user.getUsername())) {
|
||||
opening = true;
|
||||
graphQLService.fetchPost(feedModel.getCode(), new ServiceCallback<Media>() {
|
||||
@Override
|
||||
public void onSuccess(final Media newFeedModel) {
|
||||
opening = false;
|
||||
if (newFeedModel == null) return;
|
||||
openPostDialog(newFeedModel, profilePicView, mainPostImage, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
opening = false;
|
||||
Log.e(TAG, "Error", t);
|
||||
}
|
||||
});
|
||||
graphQLService.fetchPost(
|
||||
feedModel.getCode(),
|
||||
CoroutineUtilsKt.getContinuation((media, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
opening = false;
|
||||
if (throwable != null) {
|
||||
Log.e(TAG, "Error", throwable);
|
||||
return;
|
||||
}
|
||||
if (media == null) return;
|
||||
openPostDialog(media, profilePicView, mainPostImage, position);
|
||||
}))
|
||||
);
|
||||
return;
|
||||
}
|
||||
opening = true;
|
||||
@ -294,7 +294,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
||||
storiesService = StoriesService.getInstance(null, 0L, null);
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -402,7 +402,16 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
private void fetchLocationModel() {
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
if (isLoggedIn) locationService.fetch(locationId, cb);
|
||||
else graphQLService.fetchLocation(locationId, cb);
|
||||
else graphQLService.fetchLocation(
|
||||
locationId,
|
||||
CoroutineUtilsKt.getContinuation((location, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(location);
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
private void setupLocationDetails() {
|
||||
|
@ -339,7 +339,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
||||
mediaService = isLoggedIn ? MediaService.INSTANCE : null;
|
||||
userService = isLoggedIn ? UserService.INSTANCE : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.INSTANCE;
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(context));
|
||||
@ -618,25 +618,19 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
);
|
||||
return;
|
||||
}
|
||||
graphQLService.fetchUser(usernameTemp, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
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, R.string.error_loading_profile, Toast.LENGTH_LONG).show();
|
||||
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} catch (final Throwable ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
graphQLService.fetchUser(
|
||||
usernameTemp,
|
||||
CoroutineUtilsKt.getContinuation((user, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
Log.e(TAG, "Error fetching profile", throwable);
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
Toast.makeText(context, throwable.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
profileModel = user;
|
||||
setProfileDetails();
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
private void setProfileDetails() {
|
||||
|
@ -1,25 +1,22 @@
|
||||
package awais.instagrabber.repositories;
|
||||
package awais.instagrabber.repositories
|
||||
|
||||
import java.util.Map;
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.QueryMap
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.QueryMap;
|
||||
|
||||
public interface GraphQLRepository {
|
||||
interface GraphQLRepository {
|
||||
@GET("/graphql/query/")
|
||||
Call<String> fetch(@QueryMap(encoded = true) Map<String, String> queryParams);
|
||||
suspend fun fetch(@QueryMap(encoded = true) queryParams: Map<String, String>): String
|
||||
|
||||
@GET("/{username}/?__a=1")
|
||||
Call<String> getUser(@Path("username") String username);
|
||||
suspend fun getUser(@Path("username") username: String): String
|
||||
|
||||
@GET("/p/{shortcode}/?__a=1")
|
||||
Call<String> getPost(@Path("shortcode") String shortcode);
|
||||
suspend fun getPost(@Path("shortcode") shortcode: String): String
|
||||
|
||||
@GET("/explore/tags/{tag}/?__a=1")
|
||||
Call<String> getTag(@Path("tag") String tag);
|
||||
suspend fun getTag(@Path("tag") tag: String): String
|
||||
|
||||
@GET("/explore/locations/{locationId}/?__a=1")
|
||||
Call<String> getLocation(@Path("locationId") long locationId);
|
||||
}
|
||||
suspend fun getLocation(@Path("locationId") locationId: Long): String
|
||||
}
|
@ -30,13 +30,13 @@ import awais.instagrabber.repositories.responses.CommentsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.webservices.CommentService;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
@ -113,7 +113,7 @@ public class CommentsViewerViewModel extends ViewModel {
|
||||
};
|
||||
|
||||
public CommentsViewerViewModel() {
|
||||
graphQLService = GraphQLService.getInstance();
|
||||
graphQLService = GraphQLService.INSTANCE;
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
@ -165,8 +165,12 @@ public class CommentsViewerViewModel extends ViewModel {
|
||||
commentService.fetchComments(postId, rootCursor, ccb);
|
||||
return;
|
||||
}
|
||||
final Call<String> request = graphQLService.fetchComments(shortCode, true, rootCursor);
|
||||
enqueueRequest(request, true, shortCode, ccb);
|
||||
graphQLService.fetchComments(
|
||||
shortCode,
|
||||
true,
|
||||
rootCursor,
|
||||
enqueueRequest(true, shortCode, ccb)
|
||||
);
|
||||
}
|
||||
|
||||
public void fetchReplies() {
|
||||
@ -190,54 +194,49 @@ public class CommentsViewerViewModel extends ViewModel {
|
||||
commentService.fetchChildComments(postId, commentId, repliesCursor, rcb);
|
||||
return;
|
||||
}
|
||||
final Call<String> request = graphQLService.fetchComments(commentId, false, repliesCursor);
|
||||
enqueueRequest(request, false, commentId, rcb);
|
||||
graphQLService.fetchComments(commentId, false, repliesCursor, enqueueRequest(false, commentId, rcb));
|
||||
}
|
||||
|
||||
private void enqueueRequest(@NonNull final Call<String> request,
|
||||
final boolean root,
|
||||
final String shortCodeOrCommentId,
|
||||
final ServiceCallback callback) {
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql comments of " + shortCodeOrCommentId);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = root ? new JSONObject(rawBody).getJSONObject("data")
|
||||
.getJSONObject("shortcode_media")
|
||||
.getJSONObject("edge_media_to_parent_comment")
|
||||
: new JSONObject(rawBody).getJSONObject("data")
|
||||
.getJSONObject("comment")
|
||||
.getJSONObject("edge_threaded_comments");
|
||||
final int count = body.optInt("count");
|
||||
final JSONObject pageInfo = body.getJSONObject("page_info");
|
||||
final boolean hasNextPage = pageInfo.getBoolean("has_next_page");
|
||||
final String endCursor = pageInfo.isNull("end_cursor") || !hasNextPage ? null : pageInfo.optString("end_cursor");
|
||||
final JSONArray commentsJsonArray = body.getJSONArray("edges");
|
||||
final ImmutableList.Builder<Comment> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < commentsJsonArray.length(); i++) {
|
||||
final Comment commentModel = getComment(commentsJsonArray.getJSONObject(i).getJSONObject("node"), root);
|
||||
builder.add(commentModel);
|
||||
}
|
||||
callback.onSuccess(root ?
|
||||
new CommentsFetchResponse(count, endCursor, builder.build()) :
|
||||
new ChildCommentsFetchResponse(count, endCursor, builder.build()));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
callback.onFailure(e);
|
||||
}
|
||||
private Continuation<String> enqueueRequest(final boolean root,
|
||||
final String shortCodeOrCommentId,
|
||||
@SuppressWarnings("rawtypes") final ServiceCallback callback) {
|
||||
return CoroutineUtilsKt.getContinuation((response, throwable) -> {
|
||||
if (throwable != null) {
|
||||
callback.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
callback.onFailure(t);
|
||||
if (response == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql comments of " + shortCodeOrCommentId);
|
||||
//noinspection unchecked
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
});
|
||||
try {
|
||||
final JSONObject body = root ? new JSONObject(response).getJSONObject("data")
|
||||
.getJSONObject("shortcode_media")
|
||||
.getJSONObject("edge_media_to_parent_comment")
|
||||
: new JSONObject(response).getJSONObject("data")
|
||||
.getJSONObject("comment")
|
||||
.getJSONObject("edge_threaded_comments");
|
||||
final int count = body.optInt("count");
|
||||
final JSONObject pageInfo = body.getJSONObject("page_info");
|
||||
final boolean hasNextPage = pageInfo.getBoolean("has_next_page");
|
||||
final String endCursor = pageInfo.isNull("end_cursor") || !hasNextPage ? null : pageInfo.optString("end_cursor");
|
||||
final JSONArray commentsJsonArray = body.getJSONArray("edges");
|
||||
final ImmutableList.Builder<Comment> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < commentsJsonArray.length(); i++) {
|
||||
final Comment commentModel = getComment(commentsJsonArray.getJSONObject(i).getJSONObject("node"), root);
|
||||
builder.add(commentModel);
|
||||
}
|
||||
final Object result = root ? new CommentsFetchResponse(count, endCursor, builder.build())
|
||||
: new ChildCommentsFetchResponse(count, endCursor, builder.build());
|
||||
//noinspection unchecked
|
||||
callback.onSuccess(result);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}, Dispatchers.getIO());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -1,483 +1,266 @@
|
||||
package awais.instagrabber.webservices;
|
||||
package awais.instagrabber.webservices
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Log
|
||||
import awais.instagrabber.models.enums.FollowingType
|
||||
import awais.instagrabber.repositories.GraphQLRepository
|
||||
import awais.instagrabber.repositories.responses.*
|
||||
import awais.instagrabber.utils.Constants
|
||||
import awais.instagrabber.utils.ResponseBodyUtils
|
||||
import awais.instagrabber.utils.extensions.TAG
|
||||
import awais.instagrabber.webservices.RetrofitFactory.retrofitWeb
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.models.enums.FollowingType;
|
||||
import awais.instagrabber.repositories.GraphQLRepository;
|
||||
import awais.instagrabber.repositories.responses.FriendshipStatus;
|
||||
import awais.instagrabber.repositories.responses.GraphQLUserListFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class GraphQLService extends BaseService {
|
||||
private static final String TAG = "GraphQLService";
|
||||
|
||||
private final GraphQLRepository repository;
|
||||
|
||||
private static GraphQLService instance;
|
||||
|
||||
private GraphQLService() {
|
||||
repository = RetrofitFactory.INSTANCE
|
||||
.getRetrofitWeb()
|
||||
.create(GraphQLRepository.class);
|
||||
}
|
||||
|
||||
public static GraphQLService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GraphQLService();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
object GraphQLService : BaseService() {
|
||||
private val repository: GraphQLRepository = retrofitWeb.create(GraphQLRepository::class.java)
|
||||
|
||||
// TODO convert string response to a response class
|
||||
private void fetch(final String queryHash,
|
||||
final String variables,
|
||||
final String arg1,
|
||||
final String arg2,
|
||||
final User backup,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
final Map<String, String> queryMap = new HashMap<>();
|
||||
queryMap.put("query_hash", queryHash);
|
||||
queryMap.put("variables", variables);
|
||||
final Call<String> request = repository.fetch(queryMap);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
try {
|
||||
// Log.d(TAG, "onResponse: body: " + response.body());
|
||||
final PostsFetchResponse postsFetchResponse = parsePostResponse(response, arg1, arg2, backup);
|
||||
if (callback != null) {
|
||||
callback.onSuccess(postsFetchResponse);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
private suspend fun fetch(
|
||||
queryHash: String,
|
||||
variables: String,
|
||||
arg1: String,
|
||||
arg2: String,
|
||||
backup: User?,
|
||||
): PostsFetchResponse {
|
||||
val queryMap = mapOf(
|
||||
"query_hash" to queryHash,
|
||||
"variables" to variables,
|
||||
)
|
||||
val response = repository.fetch(queryMap)
|
||||
return parsePostResponse(response, arg1, arg2, backup)
|
||||
}
|
||||
|
||||
public void fetchLocationPosts(final long locationId,
|
||||
final String maxId,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
fetch("36bd0f2bf5911908de389b8ceaa3be6d",
|
||||
"{\"id\":\"" + locationId + "\"," +
|
||||
"\"first\":25," +
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_LOCATION,
|
||||
"edge_location_to_media",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
suspend fun fetchLocationPosts(
|
||||
locationId: Long,
|
||||
maxId: String?,
|
||||
): PostsFetchResponse = fetch(
|
||||
"36bd0f2bf5911908de389b8ceaa3be6d",
|
||||
"{\"id\":\"" + locationId + "\"," + "\"first\":25," + "\"after\":\"" + (maxId ?: "") + "\"}",
|
||||
Constants.EXTRAS_LOCATION,
|
||||
"edge_location_to_media",
|
||||
null
|
||||
)
|
||||
|
||||
public void fetchHashtagPosts(@NonNull final String tag,
|
||||
final String maxId,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
fetch("9b498c08113f1e09617a1703c22b2f32",
|
||||
"{\"tag_name\":\"" + tag + "\"," +
|
||||
"\"first\":25," +
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_HASHTAG,
|
||||
"edge_hashtag_to_media",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
suspend fun fetchHashtagPosts(
|
||||
tag: String,
|
||||
maxId: String?,
|
||||
): PostsFetchResponse = fetch(
|
||||
"9b498c08113f1e09617a1703c22b2f32",
|
||||
"{\"tag_name\":\"" + tag + "\"," + "\"first\":25," + "\"after\":\"" + (maxId ?: "") + "\"}",
|
||||
Constants.EXTRAS_HASHTAG,
|
||||
"edge_hashtag_to_media",
|
||||
null,
|
||||
)
|
||||
|
||||
public void fetchProfilePosts(final long profileId,
|
||||
final int postsPerPage,
|
||||
final String maxId,
|
||||
final User backup,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
fetch("02e14f6a7812a876f7d133c9555b1151",
|
||||
"{\"id\":\"" + profileId + "\"," +
|
||||
"\"first\":" + postsPerPage + "," +
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_owner_to_timeline_media",
|
||||
backup,
|
||||
callback);
|
||||
}
|
||||
suspend fun fetchProfilePosts(
|
||||
profileId: Long,
|
||||
postsPerPage: Int,
|
||||
maxId: String?,
|
||||
backup: User?,
|
||||
): PostsFetchResponse = fetch(
|
||||
"02e14f6a7812a876f7d133c9555b1151",
|
||||
"{\"id\":\"" + profileId + "\"," + "\"first\":" + postsPerPage + "," + "\"after\":\"" + (maxId ?: "") + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_owner_to_timeline_media",
|
||||
backup,
|
||||
)
|
||||
|
||||
public void fetchTaggedPosts(final long profileId,
|
||||
final int postsPerPage,
|
||||
final String maxId,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
fetch("31fe64d9463cbbe58319dced405c6206",
|
||||
"{\"id\":\"" + profileId + "\"," +
|
||||
"\"first\":" + postsPerPage + "," +
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_user_to_photos_of_you",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
suspend fun fetchTaggedPosts(
|
||||
profileId: Long,
|
||||
postsPerPage: Int,
|
||||
maxId: String?,
|
||||
): PostsFetchResponse = fetch(
|
||||
"31fe64d9463cbbe58319dced405c6206",
|
||||
"{\"id\":\"" + profileId + "\"," + "\"first\":" + postsPerPage + "," + "\"after\":\"" + (maxId ?: "") + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_user_to_photos_of_you",
|
||||
null,
|
||||
)
|
||||
|
||||
@NonNull
|
||||
private PostsFetchResponse parsePostResponse(@NonNull final Response<String> response,
|
||||
@NonNull final String arg1,
|
||||
@NonNull final String arg2,
|
||||
final User backup)
|
||||
throws JSONException {
|
||||
if (TextUtils.isEmpty(response.body())) {
|
||||
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
||||
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
||||
@Throws(JSONException::class)
|
||||
private fun parsePostResponse(
|
||||
response: String,
|
||||
arg1: String,
|
||||
arg2: String,
|
||||
backup: User?,
|
||||
): PostsFetchResponse {
|
||||
if (response.isBlank()) {
|
||||
Log.e(TAG, "parseResponse: feed response body is empty")
|
||||
return PostsFetchResponse(emptyList(), false, null)
|
||||
}
|
||||
return parseResponseBody(response.body(), arg1, arg2, backup);
|
||||
return parseResponseBody(response, arg1, arg2, backup)
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PostsFetchResponse parseResponseBody(@NonNull final String body,
|
||||
@NonNull final String arg1,
|
||||
@NonNull final String arg2,
|
||||
final User backup)
|
||||
throws JSONException {
|
||||
final List<Media> items = new ArrayList<>();
|
||||
final JSONObject timelineFeed = new JSONObject(body)
|
||||
.getJSONObject("data")
|
||||
.getJSONObject(arg1)
|
||||
.getJSONObject(arg2);
|
||||
final String endCursor;
|
||||
final boolean hasNextPage;
|
||||
|
||||
final JSONObject pageInfo = timelineFeed.getJSONObject("page_info");
|
||||
@Throws(JSONException::class)
|
||||
private fun parseResponseBody(
|
||||
body: String,
|
||||
arg1: String,
|
||||
arg2: String,
|
||||
backup: User?,
|
||||
): PostsFetchResponse {
|
||||
val items: MutableList<Media> = ArrayList()
|
||||
val timelineFeed = JSONObject(body)
|
||||
.getJSONObject("data")
|
||||
.getJSONObject(arg1)
|
||||
.getJSONObject(arg2)
|
||||
val endCursor: String?
|
||||
val hasNextPage: Boolean
|
||||
val pageInfo = timelineFeed.getJSONObject("page_info")
|
||||
if (pageInfo.has("has_next_page")) {
|
||||
hasNextPage = pageInfo.getBoolean("has_next_page");
|
||||
endCursor = hasNextPage ? pageInfo.getString("end_cursor") : null;
|
||||
hasNextPage = pageInfo.getBoolean("has_next_page")
|
||||
endCursor = if (hasNextPage) pageInfo.getString("end_cursor") else null
|
||||
} else {
|
||||
hasNextPage = false;
|
||||
endCursor = null;
|
||||
hasNextPage = false
|
||||
endCursor = null
|
||||
}
|
||||
|
||||
final JSONArray feedItems = timelineFeed.getJSONArray("edges");
|
||||
|
||||
for (int i = 0; i < feedItems.length(); ++i) {
|
||||
final JSONObject itemJson = feedItems.optJSONObject(i);
|
||||
if (itemJson == null) {
|
||||
continue;
|
||||
}
|
||||
final Media media = ResponseBodyUtils.parseGraphQLItem(itemJson, backup);
|
||||
val feedItems = timelineFeed.getJSONArray("edges")
|
||||
for (i in 0 until feedItems.length()) {
|
||||
val itemJson = feedItems.optJSONObject(i) ?: continue
|
||||
val media = ResponseBodyUtils.parseGraphQLItem(itemJson, backup)
|
||||
if (media != null) {
|
||||
items.add(media);
|
||||
items.add(media)
|
||||
}
|
||||
}
|
||||
return new PostsFetchResponse(items, hasNextPage, endCursor);
|
||||
return PostsFetchResponse(items, hasNextPage, endCursor)
|
||||
}
|
||||
|
||||
// TODO convert string response to a response class
|
||||
public void fetchCommentLikers(final String commentId,
|
||||
final String endCursor,
|
||||
final ServiceCallback<GraphQLUserListFetchResponse> callback) {
|
||||
final Map<String, String> queryMap = new HashMap<>();
|
||||
queryMap.put("query_hash", "5f0b1f6281e72053cbc07909c8d154ae");
|
||||
queryMap.put("variables", "{\"comment_id\":\"" + commentId + "\"," +
|
||||
"\"first\":30," +
|
||||
"\"after\":\"" + (endCursor == null ? "" : endCursor) + "\"}");
|
||||
final Call<String> request = repository.fetch(queryMap);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql comment likes of " + commentId);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody);
|
||||
final String status = body.getString("status");
|
||||
final JSONObject data = body.getJSONObject("data").getJSONObject("comment").getJSONObject("edge_liked_by");
|
||||
final JSONObject pageInfo = data.getJSONObject("page_info");
|
||||
final String endCursor = pageInfo.getBoolean("has_next_page") ? pageInfo.getString("end_cursor") : null;
|
||||
final JSONArray users = data.getJSONArray("edges");
|
||||
final int usersLen = users.length();
|
||||
final List<User> userModels = new ArrayList<>();
|
||||
for (int j = 0; j < usersLen; ++j) {
|
||||
final JSONObject userObject = users.getJSONObject(j).getJSONObject("node");
|
||||
userModels.add(new User(
|
||||
userObject.getLong("id"),
|
||||
userObject.getString("username"),
|
||||
userObject.optString("full_name"),
|
||||
userObject.optBoolean("is_private"),
|
||||
userObject.getString("profile_pic_url"),
|
||||
userObject.optBoolean("is_verified")
|
||||
));
|
||||
// userModels.add(new ProfileModel(userObject.optBoolean("is_private"),
|
||||
// false,
|
||||
// userObject.optBoolean("is_verified"),
|
||||
// userObject.getString("id"),
|
||||
// userObject.getString("username"),
|
||||
// userObject.optString("full_name"),
|
||||
// null, null,
|
||||
// userObject.getString("profile_pic_url"),
|
||||
// null, 0, 0, 0, false, false, false, false, false));
|
||||
}
|
||||
callback.onSuccess(new GraphQLUserListFetchResponse(endCursor, status, userModels));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
suspend fun fetchCommentLikers(
|
||||
commentId: String,
|
||||
endCursor: String?,
|
||||
): GraphQLUserListFetchResponse {
|
||||
val queryMap = mapOf(
|
||||
"query_hash" to "5f0b1f6281e72053cbc07909c8d154ae",
|
||||
"variables" to "{\"comment_id\":\"" + commentId + "\"," + "\"first\":30," + "\"after\":\"" + (endCursor ?: "") + "\"}"
|
||||
)
|
||||
val response = repository.fetch(queryMap)
|
||||
val body = JSONObject(response)
|
||||
val status = body.getString("status")
|
||||
val data = body.getJSONObject("data").getJSONObject("comment").getJSONObject("edge_liked_by")
|
||||
val pageInfo = data.getJSONObject("page_info")
|
||||
val newEndCursor = if (pageInfo.getBoolean("has_next_page")) pageInfo.getString("end_cursor") else null
|
||||
val users = data.getJSONArray("edges")
|
||||
val usersLen = users.length()
|
||||
val userModels: MutableList<User> = ArrayList()
|
||||
for (j in 0 until usersLen) {
|
||||
val userObject = users.getJSONObject(j).getJSONObject("node")
|
||||
userModels.add(User(
|
||||
userObject.getLong("id"),
|
||||
userObject.getString("username"),
|
||||
userObject.optString("full_name"),
|
||||
userObject.optBoolean("is_private"),
|
||||
userObject.getString("profile_pic_url"),
|
||||
userObject.optBoolean("is_verified")
|
||||
))
|
||||
}
|
||||
return GraphQLUserListFetchResponse(newEndCursor, status, userModels)
|
||||
}
|
||||
|
||||
public Call<String> fetchComments(final String shortCodeOrCommentId,
|
||||
final boolean root,
|
||||
final String cursor) {
|
||||
final Map<String, String> queryMap = new HashMap<>();
|
||||
queryMap.put("query_hash", root ? "bc3296d1ce80a24b1b6e40b1e72903f5" : "51fdd02b67508306ad4484ff574a0b62");
|
||||
final Map<String, Object> variables = ImmutableMap.of(
|
||||
root ? "shortcode" : "comment_id", shortCodeOrCommentId,
|
||||
"first", 50,
|
||||
"after", cursor == null ? "" : cursor
|
||||
);
|
||||
queryMap.put("variables", new JSONObject(variables).toString());
|
||||
return repository.fetch(queryMap);
|
||||
suspend fun fetchComments(
|
||||
shortCodeOrCommentId: String?,
|
||||
root: Boolean,
|
||||
cursor: String?,
|
||||
): String {
|
||||
val variables = mapOf(
|
||||
(if (root) "shortcode" else "comment_id") to shortCodeOrCommentId,
|
||||
"first" to 50,
|
||||
"after" to (cursor ?: "")
|
||||
)
|
||||
val queryMap = mapOf(
|
||||
"query_hash" to if (root) "bc3296d1ce80a24b1b6e40b1e72903f5" else "51fdd02b67508306ad4484ff574a0b62",
|
||||
"variables" to JSONObject(variables).toString()
|
||||
)
|
||||
return repository.fetch(queryMap)
|
||||
}
|
||||
|
||||
// TODO convert string response to a response class
|
||||
public void fetchUser(final String username,
|
||||
final ServiceCallback<User> callback) {
|
||||
final Call<String> request = repository.getUser(username);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql user of " + username);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody);
|
||||
final JSONObject userJson = body.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_USER);
|
||||
|
||||
boolean isPrivate = userJson.getBoolean("is_private");
|
||||
final long id = userJson.optLong(Constants.EXTRAS_ID, 0);
|
||||
final JSONObject timelineMedia = userJson.getJSONObject("edge_owner_to_timeline_media");
|
||||
// if (timelineMedia.has("edges")) {
|
||||
// final JSONArray edges = timelineMedia.getJSONArray("edges");
|
||||
// }
|
||||
|
||||
String url = userJson.optString("external_url");
|
||||
if (TextUtils.isEmpty(url)) url = null;
|
||||
|
||||
callback.onSuccess(new User(
|
||||
id,
|
||||
username,
|
||||
userJson.getString("full_name"),
|
||||
isPrivate,
|
||||
userJson.getString("profile_pic_url_hd"),
|
||||
userJson.getBoolean("is_verified"),
|
||||
null,
|
||||
new FriendshipStatus(
|
||||
userJson.optBoolean("followed_by_viewer"),
|
||||
userJson.optBoolean("follows_viewer"),
|
||||
userJson.optBoolean("blocked_by_viewer"),
|
||||
false,
|
||||
isPrivate,
|
||||
userJson.optBoolean("has_requested_viewer"),
|
||||
userJson.optBoolean("requested_by_viewer"),
|
||||
false,
|
||||
userJson.optBoolean("restricted_by_viewer"),
|
||||
false
|
||||
),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
timelineMedia.getLong("count"),
|
||||
userJson.getJSONObject("edge_followed_by").getLong("count"),
|
||||
userJson.getJSONObject("edge_follow").getLong("count"),
|
||||
0,
|
||||
userJson.getString("biography"),
|
||||
url,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
suspend fun fetchUser(
|
||||
username: String,
|
||||
): User {
|
||||
val response = repository.getUser(username)
|
||||
val body = JSONObject(response)
|
||||
val userJson = body.getJSONObject("graphql").getJSONObject(Constants.EXTRAS_USER)
|
||||
val isPrivate = userJson.getBoolean("is_private")
|
||||
val id = userJson.optLong(Constants.EXTRAS_ID, 0)
|
||||
val timelineMedia = userJson.getJSONObject("edge_owner_to_timeline_media")
|
||||
// if (timelineMedia.has("edges")) {
|
||||
// final JSONArray edges = timelineMedia.getJSONArray("edges");
|
||||
// }
|
||||
var url: String? = userJson.optString("external_url")
|
||||
if (url.isNullOrBlank()) url = null
|
||||
return User(
|
||||
id,
|
||||
username,
|
||||
userJson.getString("full_name"),
|
||||
isPrivate,
|
||||
userJson.getString("profile_pic_url_hd"),
|
||||
userJson.getBoolean("is_verified"),
|
||||
friendshipStatus = FriendshipStatus(
|
||||
userJson.optBoolean("followed_by_viewer"),
|
||||
userJson.optBoolean("follows_viewer"),
|
||||
userJson.optBoolean("blocked_by_viewer"),
|
||||
false,
|
||||
isPrivate,
|
||||
userJson.optBoolean("has_requested_viewer"),
|
||||
userJson.optBoolean("requested_by_viewer"),
|
||||
false,
|
||||
userJson.optBoolean("restricted_by_viewer"),
|
||||
false
|
||||
),
|
||||
mediaCount = timelineMedia.getLong("count"),
|
||||
followerCount = userJson.getJSONObject("edge_followed_by").getLong("count"),
|
||||
followingCount = userJson.getJSONObject("edge_follow").getLong("count"),
|
||||
biography = userJson.getString("biography"),
|
||||
externalUrl = url,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO convert string response to a response class
|
||||
public void fetchPost(final String shortcode,
|
||||
final ServiceCallback<Media> callback) {
|
||||
final Call<String> request = repository.getPost(shortcode);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql post of " + shortcode);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody);
|
||||
final JSONObject media = body.getJSONObject("graphql")
|
||||
.getJSONObject("shortcode_media");
|
||||
callback.onSuccess(ResponseBodyUtils.parseGraphQLItem(media, null));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
suspend fun fetchPost(
|
||||
shortcode: String,
|
||||
): Media {
|
||||
val response = repository.getPost(shortcode)
|
||||
val body = JSONObject(response)
|
||||
val media = body.getJSONObject("graphql").getJSONObject("shortcode_media")
|
||||
return ResponseBodyUtils.parseGraphQLItem(media, null)
|
||||
}
|
||||
|
||||
// TODO convert string response to a response class
|
||||
public void fetchTag(final String tag,
|
||||
final ServiceCallback<Hashtag> callback) {
|
||||
final Call<String> request = repository.getTag(tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql tag of " + tag);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_HASHTAG);
|
||||
final JSONObject timelineMedia = body.getJSONObject("edge_hashtag_to_media");
|
||||
callback.onSuccess(new Hashtag(
|
||||
body.getString(Constants.EXTRAS_ID),
|
||||
body.getString("name"),
|
||||
timelineMedia.getLong("count"),
|
||||
body.optBoolean("is_following") ? FollowingType.FOLLOWING : FollowingType.NOT_FOLLOWING,
|
||||
null));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
suspend fun fetchTag(
|
||||
tag: String,
|
||||
): Hashtag {
|
||||
val response = repository.getTag(tag)
|
||||
val body = JSONObject(response)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_HASHTAG)
|
||||
val timelineMedia = body.getJSONObject("edge_hashtag_to_media")
|
||||
return Hashtag(
|
||||
body.getString(Constants.EXTRAS_ID),
|
||||
body.getString("name"),
|
||||
timelineMedia.getLong("count"),
|
||||
if (body.optBoolean("is_following")) FollowingType.FOLLOWING else FollowingType.NOT_FOLLOWING,
|
||||
null)
|
||||
}
|
||||
|
||||
// TODO convert string response to a response class
|
||||
public void fetchLocation(final long locationId,
|
||||
final ServiceCallback<Location> callback) {
|
||||
final Call<String> request = repository.getLocation(locationId);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql location of " + locationId);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_LOCATION);
|
||||
final JSONObject timelineMedia = body.getJSONObject("edge_location_to_media");
|
||||
final JSONObject address = new JSONObject(body.getString("address_json"));
|
||||
callback.onSuccess(new Location(
|
||||
body.getLong(Constants.EXTRAS_ID),
|
||||
body.getString("slug"),
|
||||
body.getString("name"),
|
||||
address.optString("street_address"),
|
||||
address.optString("city_name"),
|
||||
body.optDouble("lng", 0d),
|
||||
body.optDouble("lat", 0d)
|
||||
));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
suspend fun fetchLocation(
|
||||
locationId: Long,
|
||||
): Location {
|
||||
val response = repository.getLocation(locationId)
|
||||
val body = JSONObject(response)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_LOCATION)
|
||||
// val timelineMedia = body.getJSONObject("edge_location_to_media")
|
||||
val address = JSONObject(body.getString("address_json"))
|
||||
return Location(
|
||||
body.getLong(Constants.EXTRAS_ID),
|
||||
body.getString("slug"),
|
||||
body.getString("name"),
|
||||
address.optString("street_address"),
|
||||
address.optString("city_name"),
|
||||
body.optDouble("lng", 0.0),
|
||||
body.optDouble("lat", 0.0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user