mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 06:37:30 +00:00
hashtag and location fixes
1. convert api to kotlin 2. fix follow button for hashtags
This commit is contained in:
parent
e26d9db6bf
commit
94a5fdc6fe
@ -9,12 +9,13 @@ import awais.instagrabber.repositories.responses.Media;
|
|||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
|
import awais.instagrabber.webservices.HashtagRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
import awais.instagrabber.webservices.TagsService;
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final TagsService tagsService;
|
private final HashtagRepository hashtagRepository;
|
||||||
private final GraphQLRepository graphQLRepository;
|
private final GraphQLRepository graphQLRepository;
|
||||||
private final Hashtag hashtagModel;
|
private final Hashtag hashtagModel;
|
||||||
private String nextMaxId;
|
private String nextMaxId;
|
||||||
@ -24,42 +25,31 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
public HashtagPostFetchService(final Hashtag hashtagModel, final boolean isLoggedIn) {
|
public HashtagPostFetchService(final Hashtag hashtagModel, final boolean isLoggedIn) {
|
||||||
this.hashtagModel = hashtagModel;
|
this.hashtagModel = hashtagModel;
|
||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
hashtagRepository = isLoggedIn ? HashtagRepository.Companion.getInstance() : null;
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||||
final ServiceCallback<PostsFetchResponse> cb = new ServiceCallback<PostsFetchResponse>() {
|
final Continuation<PostsFetchResponse> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
|
||||||
if (result == null) return;
|
|
||||||
nextMaxId = result.getNextCursor();
|
|
||||||
moreAvailable = result.getHasNextPage();
|
|
||||||
if (fetchListener != null) {
|
|
||||||
fetchListener.onResult(result.getFeedModels());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onFailure(t);
|
fetchListener.onFailure(t);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
if (result == null) return;
|
||||||
if (isLoggedIn) tagsService.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
nextMaxId = result.getNextCursor();
|
||||||
|
moreAvailable = result.getHasNextPage();
|
||||||
|
if (fetchListener != null) {
|
||||||
|
fetchListener.onResult(result.getFeedModels());
|
||||||
|
}
|
||||||
|
}, Dispatchers.getIO());
|
||||||
|
if (isLoggedIn) hashtagRepository.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||||
else graphQLRepository.fetchHashtagPosts(
|
else graphQLRepository.fetchHashtagPosts(
|
||||||
hashtagModel.getName().toLowerCase(),
|
hashtagModel.getName().toLowerCase(),
|
||||||
nextMaxId,
|
nextMaxId,
|
||||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
cb
|
||||||
if (throwable != null) {
|
|
||||||
cb.onFailure(throwable);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cb.onSuccess(postsFetchResponse);
|
|
||||||
}, Dispatchers.getIO())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,12 +9,13 @@ import awais.instagrabber.repositories.responses.Media;
|
|||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
import awais.instagrabber.webservices.LocationService;
|
import awais.instagrabber.webservices.LocationRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final LocationService locationService;
|
private final LocationRepository locationRepository;
|
||||||
private final GraphQLRepository graphQLRepository;
|
private final GraphQLRepository graphQLRepository;
|
||||||
private final Location locationModel;
|
private final Location locationModel;
|
||||||
private String nextMaxId;
|
private String nextMaxId;
|
||||||
@ -24,42 +25,31 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
public LocationPostFetchService(final Location locationModel, final boolean isLoggedIn) {
|
public LocationPostFetchService(final Location locationModel, final boolean isLoggedIn) {
|
||||||
this.locationModel = locationModel;
|
this.locationModel = locationModel;
|
||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
locationRepository = isLoggedIn ? LocationRepository.Companion.getInstance() : null;
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||||
final ServiceCallback<PostsFetchResponse> cb = new ServiceCallback<PostsFetchResponse>() {
|
final Continuation<PostsFetchResponse> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
|
||||||
if (result == null) return;
|
|
||||||
nextMaxId = result.getNextCursor();
|
|
||||||
moreAvailable = result.getHasNextPage();
|
|
||||||
if (fetchListener != null) {
|
|
||||||
fetchListener.onResult(result.getFeedModels());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onFailure(t);
|
fetchListener.onFailure(t);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
if (result == null) return;
|
||||||
if (isLoggedIn) locationService.fetchPosts(locationModel.getPk(), nextMaxId, cb);
|
nextMaxId = result.getNextCursor();
|
||||||
|
moreAvailable = result.getHasNextPage();
|
||||||
|
if (fetchListener != null) {
|
||||||
|
fetchListener.onResult(result.getFeedModels());
|
||||||
|
}
|
||||||
|
}, Dispatchers.getIO());
|
||||||
|
if (isLoggedIn) locationRepository.fetchPosts(locationModel.getPk(), nextMaxId, cb);
|
||||||
else graphQLRepository.fetchLocationPosts(
|
else graphQLRepository.fetchLocationPosts(
|
||||||
locationModel.getPk(),
|
locationModel.getPk(),
|
||||||
nextMaxId,
|
nextMaxId,
|
||||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
cb
|
||||||
if (throwable != null) {
|
|
||||||
cb.onFailure(throwable);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cb.onSuccess(postsFetchResponse);
|
|
||||||
}, Dispatchers.getIO())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ import awais.instagrabber.db.repositories.FavoriteRepository;
|
|||||||
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
|
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
|
||||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||||
import awais.instagrabber.models.enums.FavoriteType;
|
import awais.instagrabber.models.enums.FavoriteType;
|
||||||
import awais.instagrabber.models.enums.FollowingType;
|
|
||||||
import awais.instagrabber.repositories.responses.Hashtag;
|
import awais.instagrabber.repositories.responses.Hashtag;
|
||||||
import awais.instagrabber.repositories.responses.Location;
|
import awais.instagrabber.repositories.responses.Location;
|
||||||
import awais.instagrabber.repositories.responses.Media;
|
import awais.instagrabber.repositories.responses.Media;
|
||||||
@ -61,8 +60,9 @@ import awais.instagrabber.utils.DownloadUtils;
|
|||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
|
import awais.instagrabber.webservices.HashtagRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
import awais.instagrabber.webservices.TagsService;
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
@ -80,7 +80,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
// private StoriesRepository storiesRepository;
|
// private StoriesRepository storiesRepository;
|
||||||
private boolean isLoggedIn;
|
private boolean isLoggedIn;
|
||||||
private TagsService tagsService;
|
private HashtagRepository hashtagRepository;
|
||||||
private GraphQLRepository graphQLRepository;
|
private GraphQLRepository graphQLRepository;
|
||||||
// private boolean storiesFetching;
|
// private boolean storiesFetching;
|
||||||
private Set<Media> selectedFeedModels;
|
private Set<Media> selectedFeedModels;
|
||||||
@ -264,19 +264,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final ServiceCallback<Hashtag> cb = new ServiceCallback<Hashtag>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(final Hashtag result) {
|
|
||||||
hashtagModel = result;
|
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
|
||||||
setHashtagDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
setHashtagDetails();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
@ -284,7 +271,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
fragmentActivity = (MainActivity) requireActivity();
|
fragmentActivity = (MainActivity) requireActivity();
|
||||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
hashtagRepository = isLoggedIn ? HashtagRepository.Companion.getInstance() : null;
|
||||||
// storiesRepository = isLoggedIn ? StoriesRepository.Companion.getInstance() : null;
|
// storiesRepository = isLoggedIn ? StoriesRepository.Companion.getInstance() : null;
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
@ -349,19 +336,20 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
||||||
hashtag = fragmentArgs.getHashtag();
|
hashtag = fragmentArgs.getHashtag();
|
||||||
if (hashtag.charAt(0) == '#') hashtag = hashtag.substring(1);
|
if (hashtag.charAt(0) == '#') hashtag = hashtag.substring(1);
|
||||||
fetchHashtagModel();
|
fetchHashtagModel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchHashtagModel() {
|
private void fetchHashtagModel(final boolean init) {
|
||||||
binding.swipeRefreshLayout.setRefreshing(true);
|
binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
if (isLoggedIn) tagsService.fetch(hashtag, cb);
|
final Continuation<Hashtag> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
else graphQLRepository.fetchTag(hashtag, CoroutineUtilsKt.getContinuation((hashtag1, throwable) -> {
|
hashtagModel = result;
|
||||||
if (throwable != null) {
|
AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||||
cb.onFailure(throwable);
|
setHashtagDetails(init);
|
||||||
return;
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
});
|
||||||
AppExecutors.INSTANCE.getMainThread().execute(() -> cb.onSuccess(hashtag1));
|
}, Dispatchers.getIO());
|
||||||
}, Dispatchers.getIO()));
|
if (isLoggedIn) hashtagRepository.fetch(hashtag, cb);
|
||||||
|
else graphQLRepository.fetchTag(hashtag, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupPosts() {
|
private void setupPosts() {
|
||||||
@ -386,7 +374,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHashtagDetails() {
|
private void setHashtagDetails(final boolean init) {
|
||||||
if (hashtagModel == null) {
|
if (hashtagModel == null) {
|
||||||
try {
|
try {
|
||||||
Toast.makeText(getContext(), R.string.error_loading_hashtag, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), R.string.error_loading_hashtag, Toast.LENGTH_SHORT).show();
|
||||||
@ -394,14 +382,16 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTitle();
|
if (init) {
|
||||||
setupPosts();
|
setTitle();
|
||||||
|
setupPosts();
|
||||||
|
}
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
hashtagDetailsBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
hashtagDetailsBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
||||||
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollowing() == FollowingType.FOLLOWING
|
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollow()
|
||||||
? R.string.unfollow
|
? R.string.unfollow
|
||||||
: R.string.follow);
|
: R.string.follow);
|
||||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(hashtagModel.getFollowing() == FollowingType.FOLLOWING
|
hashtagDetailsBinding.btnFollowTag.setChipIconResource(hashtagModel.getFollow()
|
||||||
? R.drawable.ic_outline_person_add_disabled_24
|
? R.drawable.ic_outline_person_add_disabled_24
|
||||||
: R.drawable.ic_outline_person_add_24);
|
: R.drawable.ic_outline_person_add_24);
|
||||||
hashtagDetailsBinding.btnFollowTag.setOnClickListener(v -> {
|
hashtagDetailsBinding.btnFollowTag.setOnClickListener(v -> {
|
||||||
@ -411,29 +401,15 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||||
if (csrfToken != null && userId != 0) {
|
if (csrfToken != null && userId != 0) {
|
||||||
hashtagDetailsBinding.btnFollowTag.setClickable(false);
|
hashtagDetailsBinding.btnFollowTag.setClickable(false);
|
||||||
tagsService.changeFollow(
|
hashtagRepository.changeFollow(
|
||||||
hashtagModel.getFollowing() == FollowingType.FOLLOWING ? "unfollow" : "follow",
|
hashtagModel.getFollow() ? "unfollow" : "follow",
|
||||||
hashtag,
|
hashtag,
|
||||||
csrfToken,
|
csrfToken,
|
||||||
userId,
|
userId,
|
||||||
deviceUuid,
|
deviceUuid,
|
||||||
new ServiceCallback<Boolean>() {
|
CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||||
public void onSuccess(final Boolean result) {
|
if (t != null) {
|
||||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
|
||||||
if (!result) {
|
|
||||||
Log.e(TAG, "onSuccess: result is false");
|
|
||||||
Snackbar.make(root, R.string.downloader_unknown_error, BaseTransientBottomBar.LENGTH_LONG)
|
|
||||||
.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hashtagDetailsBinding.btnFollowTag.setText(R.string.unfollow);
|
|
||||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Throwable t) {
|
|
||||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
|
||||||
Log.e(TAG, "onFailure: ", t);
|
Log.e(TAG, "onFailure: ", t);
|
||||||
final String message = t.getMessage();
|
final String message = t.getMessage();
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
@ -441,8 +417,17 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
message != null ? message : getString(R.string.downloader_unknown_error),
|
message != null ? message : getString(R.string.downloader_unknown_error),
|
||||||
BaseTransientBottomBar.LENGTH_LONG)
|
BaseTransientBottomBar.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
if (result != true) {
|
||||||
|
Log.e(TAG, "onSuccess: result is false");
|
||||||
|
Snackbar.make(root, R.string.downloader_unknown_error, BaseTransientBottomBar.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchHashtagModel(false);
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -451,6 +436,18 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
if (context == null) return;
|
if (context == null) return;
|
||||||
|
final String postCount = String.valueOf(hashtagModel.getMediaCount());
|
||||||
|
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(
|
||||||
|
R.plurals.main_posts_count_inline,
|
||||||
|
hashtagModel.getMediaCount() > 2000000000L ? 2000000000
|
||||||
|
: Long.valueOf(hashtagModel.getMediaCount()).intValue(),
|
||||||
|
postCount)
|
||||||
|
);
|
||||||
|
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
||||||
|
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
||||||
|
hashtagDetailsBinding.mainTagPostCount.setText(span);
|
||||||
|
hashtagDetailsBinding.mainTagPostCount.setVisibility(View.VISIBLE);
|
||||||
|
if (!init) return;
|
||||||
final FavoriteRepository favoriteRepository = FavoriteRepository.Companion.getInstance(context);
|
final FavoriteRepository favoriteRepository = FavoriteRepository.Companion.getInstance(context);
|
||||||
favoriteRepository.getFavorite(
|
favoriteRepository.getFavorite(
|
||||||
hashtag,
|
hashtag,
|
||||||
@ -528,17 +525,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
hashtagDetailsBinding.mainHashtagImage.setImageURI("res:/" + R.drawable.ic_hashtag);
|
hashtagDetailsBinding.mainHashtagImage.setImageURI("res:/" + R.drawable.ic_hashtag);
|
||||||
final String postCount = String.valueOf(hashtagModel.getMediaCount());
|
|
||||||
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(
|
|
||||||
R.plurals.main_posts_count_inline,
|
|
||||||
hashtagModel.getMediaCount() > 2000000000L ? 2000000000
|
|
||||||
: Long.valueOf(hashtagModel.getMediaCount()).intValue(),
|
|
||||||
postCount)
|
|
||||||
);
|
|
||||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
|
||||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
|
||||||
hashtagDetailsBinding.mainTagPostCount.setText(span);
|
|
||||||
hashtagDetailsBinding.mainTagPostCount.setVisibility(View.VISIBLE);
|
|
||||||
// hashtagDetailsBinding.mainHashtagImage.setOnClickListener(v -> {
|
// hashtagDetailsBinding.mainHashtagImage.setOnClickListener(v -> {
|
||||||
// if (!hasStories) return;
|
// if (!hasStories) return;
|
||||||
// // show stories
|
// // show stories
|
||||||
|
@ -58,8 +58,8 @@ import awais.instagrabber.utils.DownloadUtils;
|
|||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
import awais.instagrabber.webservices.LocationService;
|
import awais.instagrabber.webservices.LocationRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
@ -76,7 +76,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
private Location locationModel;
|
private Location locationModel;
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
private GraphQLRepository graphQLRepository;
|
private GraphQLRepository graphQLRepository;
|
||||||
private LocationService locationService;
|
private LocationRepository locationRepository;
|
||||||
private boolean isLoggedIn;
|
private boolean isLoggedIn;
|
||||||
private Set<Media> selectedFeedModels;
|
private Set<Media> selectedFeedModels;
|
||||||
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_LOCATION_POSTS_LAYOUT);
|
private PostsLayoutPreferences layoutPreferences = Utils.getPostsLayoutPreferences(Constants.PREF_LOCATION_POSTS_LAYOUT);
|
||||||
@ -257,19 +257,6 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final ServiceCallback<Location> cb = new ServiceCallback<Location>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(final Location result) {
|
|
||||||
locationModel = result;
|
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
|
||||||
setupLocationDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
setupLocationDetails();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
@ -277,7 +264,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
fragmentActivity = (MainActivity) requireActivity();
|
fragmentActivity = (MainActivity) requireActivity();
|
||||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
locationRepository = isLoggedIn ? LocationRepository.Companion.getInstance() : null;
|
||||||
// storiesRepository = StoriesRepository.Companion.getInstance();
|
// storiesRepository = StoriesRepository.Companion.getInstance();
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
@ -372,17 +359,15 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
|||||||
|
|
||||||
private void fetchLocationModel() {
|
private void fetchLocationModel() {
|
||||||
binding.swipeRefreshLayout.setRefreshing(true);
|
binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
if (isLoggedIn) locationService.fetch(locationId, cb);
|
final Continuation<Location> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
else graphQLRepository.fetchLocation(
|
locationModel = result;
|
||||||
locationId,
|
AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||||
CoroutineUtilsKt.getContinuation((location, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
setupLocationDetails();
|
||||||
if (throwable != null) {
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
cb.onFailure(throwable);
|
});
|
||||||
return;
|
}, Dispatchers.getIO());
|
||||||
}
|
if (isLoggedIn) locationRepository.fetch(locationId, cb);
|
||||||
cb.onSuccess(location);
|
else graphQLRepository.fetchLocation(locationId, cb);
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupLocationDetails() {
|
private void setupLocationDetails() {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package awais.instagrabber.models.enums
|
|
||||||
|
|
||||||
import java.io.Serializable
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
enum class FollowingType(val id: Int) : Serializable {
|
|
||||||
FOLLOWING(1),
|
|
||||||
NOT_FOLLOWING(0);
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val map: MutableMap<Int, FollowingType> = mutableMapOf()
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun valueOf(id: Int): FollowingType? {
|
|
||||||
return map[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
for (type in values()) {
|
|
||||||
map[type.id] = type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
package awais.instagrabber.repositories
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.responses.Hashtag
|
||||||
|
import awais.instagrabber.repositories.responses.TagFeedResponse
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.*
|
||||||
|
|
||||||
|
interface HashtagService {
|
||||||
|
@GET("/api/v1/tags/{tag}/info/")
|
||||||
|
suspend fun fetch(@Path("tag") tag: String?): Hashtag?
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/tags/{action}/{tag}/")
|
||||||
|
suspend fun changeFollow(
|
||||||
|
@FieldMap signedForm: Map<String?, String?>?,
|
||||||
|
@Path("action") action: String?,
|
||||||
|
@Path("tag") tag: String?
|
||||||
|
): String?
|
||||||
|
|
||||||
|
@GET("/api/v1/feed/tag/{tag}/")
|
||||||
|
suspend fun fetchPosts(
|
||||||
|
@Path("tag") tag: String?,
|
||||||
|
@QueryMap queryParams: Map<String?, String?>?
|
||||||
|
): TagFeedResponse?
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
package awais.instagrabber.repositories;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.responses.LocationFeedResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.Place;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.http.GET;
|
|
||||||
import retrofit2.http.Path;
|
|
||||||
import retrofit2.http.QueryMap;
|
|
||||||
|
|
||||||
public interface LocationRepository {
|
|
||||||
@GET("/api/v1/locations/{location}/info/")
|
|
||||||
Call<Place> fetch(@Path("location") final long locationId);
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/location/{location}/")
|
|
||||||
Call<LocationFeedResponse> fetchPosts(@Path("location") final long locationId,
|
|
||||||
@QueryMap Map<String, String> queryParams);
|
|
||||||
}
|
|
@ -0,0 +1,19 @@
|
|||||||
|
package awais.instagrabber.repositories
|
||||||
|
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import awais.instagrabber.repositories.responses.Place
|
||||||
|
import awais.instagrabber.repositories.responses.LocationFeedResponse
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.Path
|
||||||
|
import retrofit2.http.QueryMap
|
||||||
|
|
||||||
|
interface LocationService {
|
||||||
|
@GET("/api/v1/locations/{location}/info/")
|
||||||
|
suspend fun fetch(@Path("location") locationId: Long): Place?
|
||||||
|
|
||||||
|
@GET("/api/v1/feed/location/{location}/")
|
||||||
|
suspend fun fetchPosts(
|
||||||
|
@Path("location") locationId: Long,
|
||||||
|
@QueryMap queryParams: Map<String?, String?>?
|
||||||
|
): LocationFeedResponse?
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
package awais.instagrabber.repositories;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.responses.Hashtag;
|
|
||||||
import awais.instagrabber.repositories.responses.TagFeedResponse;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.http.FieldMap;
|
|
||||||
import retrofit2.http.FormUrlEncoded;
|
|
||||||
import retrofit2.http.GET;
|
|
||||||
import retrofit2.http.Header;
|
|
||||||
import retrofit2.http.POST;
|
|
||||||
import retrofit2.http.Path;
|
|
||||||
import retrofit2.http.QueryMap;
|
|
||||||
|
|
||||||
public interface TagsRepository {
|
|
||||||
@GET("/api/v1/tags/{tag}/info/")
|
|
||||||
Call<Hashtag> fetch(@Path("tag") final String tag);
|
|
||||||
|
|
||||||
@FormUrlEncoded
|
|
||||||
@POST("/api/v1/tags/{action}/{tag}/")
|
|
||||||
Call<String> changeFollow(@FieldMap final Map<String, String> signedForm,
|
|
||||||
@Path("action") String action,
|
|
||||||
@Path("tag") String tag);
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/tag/{tag}/")
|
|
||||||
Call<TagFeedResponse> fetchPosts(@Path("tag") final String tag,
|
|
||||||
@QueryMap Map<String, String> queryParams);
|
|
||||||
}
|
|
@ -1,12 +1,14 @@
|
|||||||
package awais.instagrabber.repositories.responses
|
package awais.instagrabber.repositories.responses
|
||||||
|
|
||||||
import awais.instagrabber.models.enums.FollowingType
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
data class Hashtag(
|
data class Hashtag(
|
||||||
val id: String,
|
val id: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val mediaCount: Long,
|
val mediaCount: Long,
|
||||||
val following: FollowingType?, // 0 false 1 true; not on search results
|
val following: Int?, // 0 false 1 true; not on search results
|
||||||
val searchResultSubtitle: String? // shows how many posts there are on search results
|
val searchResultSubtitle: String? // shows how many posts there are on search results
|
||||||
) : Serializable
|
) : Serializable {
|
||||||
|
val follow: Boolean
|
||||||
|
get() = following == 1
|
||||||
|
}
|
@ -3,9 +3,9 @@ package awais.instagrabber.repositories.responses
|
|||||||
data class LocationFeedResponse(
|
data class LocationFeedResponse(
|
||||||
val numResults: Int,
|
val numResults: Int,
|
||||||
val nextMaxId: String?,
|
val nextMaxId: String?,
|
||||||
val moreAvailable: Boolean?,
|
val moreAvailable: Boolean,
|
||||||
val mediaCount: Long?,
|
val mediaCount: Long?,
|
||||||
val status: String,
|
val status: String,
|
||||||
val items: List<Media>?,
|
val items: List<Media>,
|
||||||
val location: Location
|
val location: Location
|
||||||
)
|
)
|
@ -262,7 +262,7 @@ open class GraphQLRepository(private val service: GraphQLService) {
|
|||||||
body.getString(Constants.EXTRAS_ID),
|
body.getString(Constants.EXTRAS_ID),
|
||||||
body.getString("name"),
|
body.getString("name"),
|
||||||
timelineMedia.getLong("count"),
|
timelineMedia.getLong("count"),
|
||||||
if (body.optBoolean("is_following")) FollowingType.FOLLOWING else FollowingType.NOT_FOLLOWING,
|
if (body.optBoolean("is_following")) 1 else 0,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package awais.instagrabber.webservices
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import awais.instagrabber.repositories.HashtagService
|
||||||
|
import awais.instagrabber.repositories.responses.Hashtag
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse
|
||||||
|
import awais.instagrabber.repositories.responses.TagFeedResponse
|
||||||
|
import awais.instagrabber.utils.TextUtils.isEmpty
|
||||||
|
import awais.instagrabber.utils.Utils
|
||||||
|
import awais.instagrabber.webservices.RetrofitFactory.retrofit
|
||||||
|
import com.google.common.collect.ImmutableMap
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
open class HashtagRepository(private val repository: HashtagService) {
|
||||||
|
suspend fun fetch(tag: String): Hashtag? {
|
||||||
|
return repository.fetch(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun changeFollow(
|
||||||
|
action: String,
|
||||||
|
tag: String,
|
||||||
|
csrfToken: String,
|
||||||
|
userId: Long,
|
||||||
|
deviceUuid: String
|
||||||
|
): Boolean {
|
||||||
|
val form: MutableMap<String, Any> = HashMap(3)
|
||||||
|
form["_csrftoken"] = csrfToken
|
||||||
|
form["_uid"] = userId
|
||||||
|
form["_uuid"] = deviceUuid
|
||||||
|
val signedForm = Utils.sign(form)
|
||||||
|
val body = repository.changeFollow(signedForm, action, tag) ?: return false
|
||||||
|
val jsonObject = JSONObject(body)
|
||||||
|
return jsonObject.optString("status") == "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchPosts(tag: String, maxId: String?): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!isEmpty(maxId)) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val body = repository.fetchPosts(tag, builder.build()) ?: return null
|
||||||
|
return PostsFetchResponse(
|
||||||
|
body.items,
|
||||||
|
body.moreAvailable,
|
||||||
|
body.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: HashtagRepository? = null
|
||||||
|
|
||||||
|
fun getInstance(): HashtagRepository {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
val service = RetrofitFactory.retrofit.create(HashtagService::class.java)
|
||||||
|
HashtagRepository(service).also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package awais.instagrabber.webservices
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.HashtagService
|
||||||
|
import awais.instagrabber.repositories.responses.Location
|
||||||
|
import awais.instagrabber.repositories.responses.LocationFeedResponse
|
||||||
|
import awais.instagrabber.repositories.responses.Place
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse
|
||||||
|
import awais.instagrabber.utils.TextUtils.isEmpty
|
||||||
|
import awais.instagrabber.repositories.LocationService
|
||||||
|
import awais.instagrabber.webservices.RetrofitFactory.retrofit
|
||||||
|
import com.google.common.collect.ImmutableMap
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
open class LocationRepository(private val repository: LocationService) {
|
||||||
|
suspend fun fetchPosts(locationId: Long, maxId: String): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String, String>()
|
||||||
|
if (!isEmpty(maxId)) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val body = repository.fetchPosts(locationId, builder.build()) ?: return null
|
||||||
|
return PostsFetchResponse(
|
||||||
|
body.items,
|
||||||
|
body.moreAvailable,
|
||||||
|
body.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetch(locationId: Long): Location? {
|
||||||
|
val place = repository.fetch(locationId) ?: return null
|
||||||
|
return place.location
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: LocationRepository? = null
|
||||||
|
|
||||||
|
fun getInstance(): LocationRepository {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
val service = RetrofitFactory.retrofit.create(LocationService::class.java)
|
||||||
|
LocationRepository(service).also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,92 +0,0 @@
|
|||||||
package awais.instagrabber.webservices;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.LocationRepository;
|
|
||||||
import awais.instagrabber.repositories.responses.Location;
|
|
||||||
import awais.instagrabber.repositories.responses.LocationFeedResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.Place;
|
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
|
||||||
import awais.instagrabber.utils.TextUtils;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
public class LocationService {
|
|
||||||
private static final String TAG = "LocationService";
|
|
||||||
|
|
||||||
private final LocationRepository repository;
|
|
||||||
|
|
||||||
private static LocationService instance;
|
|
||||||
|
|
||||||
private LocationService() {
|
|
||||||
repository = RetrofitFactory.INSTANCE
|
|
||||||
.getRetrofit()
|
|
||||||
.create(LocationRepository.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LocationService getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new LocationService();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchPosts(final long locationId,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
final Call<LocationFeedResponse> request = repository.fetchPosts(locationId, builder.build());
|
|
||||||
request.enqueue(new Callback<LocationFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<LocationFeedResponse> call, @NonNull final Response<LocationFeedResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final LocationFeedResponse body = response.body();
|
|
||||||
if (body == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final PostsFetchResponse postsFetchResponse = new PostsFetchResponse(
|
|
||||||
body.getItems(),
|
|
||||||
body.getMoreAvailable(),
|
|
||||||
body.getNextMaxId()
|
|
||||||
);
|
|
||||||
callback.onSuccess(postsFetchResponse);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<LocationFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetch(@NonNull final long locationId,
|
|
||||||
final ServiceCallback<Location> callback) {
|
|
||||||
final Call<Place> request = repository.fetch(locationId);
|
|
||||||
request.enqueue(new Callback<Place>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<Place> call, @NonNull final Response<Place> response) {
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(response.body() == null ? null : response.body().getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<Place> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
package awais.instagrabber.webservices;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.TagsRepository;
|
|
||||||
import awais.instagrabber.repositories.responses.Hashtag;
|
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.TagFeedResponse;
|
|
||||||
import awais.instagrabber.utils.TextUtils;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
public class TagsService {
|
|
||||||
|
|
||||||
private static final String TAG = "TagsService";
|
|
||||||
|
|
||||||
private static TagsService instance;
|
|
||||||
|
|
||||||
private final TagsRepository repository;
|
|
||||||
|
|
||||||
private TagsService() {
|
|
||||||
repository = RetrofitFactory.INSTANCE
|
|
||||||
.getRetrofit()
|
|
||||||
.create(TagsRepository.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TagsService getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new TagsService();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetch(@NonNull final String tag,
|
|
||||||
final ServiceCallback<Hashtag> callback) {
|
|
||||||
final Call<Hashtag> request = repository.fetch(tag);
|
|
||||||
request.enqueue(new Callback<Hashtag>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<Hashtag> call, @NonNull final Response<Hashtag> response) {
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<Hashtag> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changeFollow(@NonNull final String action,
|
|
||||||
@NonNull final String tag,
|
|
||||||
@NonNull final String csrfToken,
|
|
||||||
@NonNull final long userId,
|
|
||||||
@NonNull final String deviceUuid,
|
|
||||||
final ServiceCallback<Boolean> callback) {
|
|
||||||
final Map<String, Object> form = new HashMap<>(3);
|
|
||||||
form.put("_csrftoken", csrfToken);
|
|
||||||
form.put("_uid", userId);
|
|
||||||
form.put("_uuid", deviceUuid);
|
|
||||||
final Map<String, String> signedForm = Utils.sign(form);
|
|
||||||
final Call<String> request = repository.changeFollow(signedForm, action, tag);
|
|
||||||
request.enqueue(new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
||||||
final String body = response.body();
|
|
||||||
if (body == null) {
|
|
||||||
callback.onFailure(new RuntimeException("body is null"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final JSONObject jsonObject = new JSONObject(body);
|
|
||||||
final String status = jsonObject.optString("status");
|
|
||||||
callback.onSuccess(status.equals("ok"));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "onResponse: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchPosts(@NonNull final String tag,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
final Call<TagFeedResponse> request = repository.fetchPosts(tag, builder.build());
|
|
||||||
request.enqueue(new Callback<TagFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<TagFeedResponse> call, @NonNull final Response<TagFeedResponse> response) {
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final TagFeedResponse body = response.body();
|
|
||||||
if (body == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(new PostsFetchResponse(
|
|
||||||
body.getItems(),
|
|
||||||
body.getMoreAvailable(),
|
|
||||||
body.getNextMaxId()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<TagFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user