mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-22 13:06:58 +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.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLRepository;
|
||||
import awais.instagrabber.webservices.HashtagRepository;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.TagsService;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final TagsService tagsService;
|
||||
private final HashtagRepository hashtagRepository;
|
||||
private final GraphQLRepository graphQLRepository;
|
||||
private final Hashtag hashtagModel;
|
||||
private String nextMaxId;
|
||||
@ -24,42 +25,31 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
public HashtagPostFetchService(final Hashtag hashtagModel, final boolean isLoggedIn) {
|
||||
this.hashtagModel = hashtagModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||
hashtagRepository = isLoggedIn ? HashtagRepository.Companion.getInstance() : null;
|
||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||
final ServiceCallback<PostsFetchResponse> cb = new ServiceCallback<PostsFetchResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final PostsFetchResponse result) {
|
||||
if (result == null) return;
|
||||
nextMaxId = result.getNextCursor();
|
||||
moreAvailable = result.getHasNextPage();
|
||||
if (fetchListener != null) {
|
||||
fetchListener.onResult(result.getFeedModels());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
// Log.e(TAG, "onFailure: ", t);
|
||||
final Continuation<PostsFetchResponse> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||
if (t != null) {
|
||||
if (fetchListener != null) {
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) tagsService.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||
if (result == null) return;
|
||||
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(
|
||||
hashtagModel.getName().toLowerCase(),
|
||||
nextMaxId,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
cb
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,13 @@ import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||
import awais.instagrabber.webservices.GraphQLRepository;
|
||||
import awais.instagrabber.webservices.LocationService;
|
||||
import awais.instagrabber.webservices.LocationRepository;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final LocationService locationService;
|
||||
private final LocationRepository locationRepository;
|
||||
private final GraphQLRepository graphQLRepository;
|
||||
private final Location locationModel;
|
||||
private String nextMaxId;
|
||||
@ -24,42 +25,31 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||
public LocationPostFetchService(final Location locationModel, final boolean isLoggedIn) {
|
||||
this.locationModel = locationModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
||||
locationRepository = isLoggedIn ? LocationRepository.Companion.getInstance() : null;
|
||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||
final ServiceCallback<PostsFetchResponse> cb = new ServiceCallback<PostsFetchResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final PostsFetchResponse result) {
|
||||
if (result == null) return;
|
||||
nextMaxId = result.getNextCursor();
|
||||
moreAvailable = result.getHasNextPage();
|
||||
if (fetchListener != null) {
|
||||
fetchListener.onResult(result.getFeedModels());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
// Log.e(TAG, "onFailure: ", t);
|
||||
final Continuation<PostsFetchResponse> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||
if (t != null) {
|
||||
if (fetchListener != null) {
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) locationService.fetchPosts(locationModel.getPk(), nextMaxId, cb);
|
||||
if (result == null) return;
|
||||
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(
|
||||
locationModel.getPk(),
|
||||
nextMaxId,
|
||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(postsFetchResponse);
|
||||
}, Dispatchers.getIO())
|
||||
cb
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ import awais.instagrabber.db.repositories.FavoriteRepository;
|
||||
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
|
||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.models.enums.FollowingType;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
@ -61,8 +60,9 @@ import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.webservices.GraphQLRepository;
|
||||
import awais.instagrabber.webservices.HashtagRepository;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.TagsService;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
@ -80,7 +80,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private ActionMode actionMode;
|
||||
// private StoriesRepository storiesRepository;
|
||||
private boolean isLoggedIn;
|
||||
private TagsService tagsService;
|
||||
private HashtagRepository hashtagRepository;
|
||||
private GraphQLRepository graphQLRepository;
|
||||
// private boolean storiesFetching;
|
||||
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
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
@ -284,7 +271,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
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;
|
||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||
setHasOptionsMenu(true);
|
||||
@ -349,19 +336,20 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
||||
hashtag = fragmentArgs.getHashtag();
|
||||
if (hashtag.charAt(0) == '#') hashtag = hashtag.substring(1);
|
||||
fetchHashtagModel();
|
||||
fetchHashtagModel(true);
|
||||
}
|
||||
|
||||
private void fetchHashtagModel() {
|
||||
private void fetchHashtagModel(final boolean init) {
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
if (isLoggedIn) tagsService.fetch(hashtag, cb);
|
||||
else graphQLRepository.fetchTag(hashtag, CoroutineUtilsKt.getContinuation((hashtag1, throwable) -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
AppExecutors.INSTANCE.getMainThread().execute(() -> cb.onSuccess(hashtag1));
|
||||
}, Dispatchers.getIO()));
|
||||
final Continuation<Hashtag> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||
hashtagModel = result;
|
||||
AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
setHashtagDetails(init);
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}, Dispatchers.getIO());
|
||||
if (isLoggedIn) hashtagRepository.fetch(hashtag, cb);
|
||||
else graphQLRepository.fetchTag(hashtag, cb);
|
||||
}
|
||||
|
||||
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) {
|
||||
try {
|
||||
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) {}
|
||||
return;
|
||||
}
|
||||
setTitle();
|
||||
setupPosts();
|
||||
if (init) {
|
||||
setTitle();
|
||||
setupPosts();
|
||||
}
|
||||
if (isLoggedIn) {
|
||||
hashtagDetailsBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
||||
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollowing() == FollowingType.FOLLOWING
|
||||
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollow()
|
||||
? R.string.unfollow
|
||||
: 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_24);
|
||||
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);
|
||||
if (csrfToken != null && userId != 0) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(false);
|
||||
tagsService.changeFollow(
|
||||
hashtagModel.getFollowing() == FollowingType.FOLLOWING ? "unfollow" : "follow",
|
||||
hashtagRepository.changeFollow(
|
||||
hashtagModel.getFollow() ? "unfollow" : "follow",
|
||||
hashtag,
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceUuid,
|
||||
new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
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);
|
||||
CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
if (t != null) {
|
||||
Log.e(TAG, "onFailure: ", t);
|
||||
final String message = t.getMessage();
|
||||
Snackbar.make(
|
||||
@ -441,8 +417,17 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
message != null ? message : getString(R.string.downloader_unknown_error),
|
||||
BaseTransientBottomBar.LENGTH_LONG)
|
||||
.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 {
|
||||
@ -451,6 +436,18 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||
final Context context = getContext();
|
||||
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);
|
||||
favoriteRepository.getFavorite(
|
||||
hashtag,
|
||||
@ -528,17 +525,6 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
)
|
||||
);
|
||||
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 -> {
|
||||
// if (!hasStories) return;
|
||||
// // show stories
|
||||
|
@ -58,8 +58,8 @@ import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.webservices.GraphQLRepository;
|
||||
import awais.instagrabber.webservices.LocationService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.LocationRepository;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
@ -76,7 +76,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
private Location locationModel;
|
||||
private ActionMode actionMode;
|
||||
private GraphQLRepository graphQLRepository;
|
||||
private LocationService locationService;
|
||||
private LocationRepository locationRepository;
|
||||
private boolean isLoggedIn;
|
||||
private Set<Media> selectedFeedModels;
|
||||
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
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
@ -277,7 +264,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
||||
locationRepository = isLoggedIn ? LocationRepository.Companion.getInstance() : null;
|
||||
// storiesRepository = StoriesRepository.Companion.getInstance();
|
||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||
setHasOptionsMenu(true);
|
||||
@ -372,17 +359,15 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
|
||||
private void fetchLocationModel() {
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
if (isLoggedIn) locationService.fetch(locationId, cb);
|
||||
else graphQLRepository.fetchLocation(
|
||||
locationId,
|
||||
CoroutineUtilsKt.getContinuation((location, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
if (throwable != null) {
|
||||
cb.onFailure(throwable);
|
||||
return;
|
||||
}
|
||||
cb.onSuccess(location);
|
||||
}))
|
||||
);
|
||||
final Continuation<Location> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||
locationModel = result;
|
||||
AppExecutors.INSTANCE.getMainThread().execute(() -> {
|
||||
setupLocationDetails();
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}, Dispatchers.getIO());
|
||||
if (isLoggedIn) locationRepository.fetch(locationId, cb);
|
||||
else graphQLRepository.fetchLocation(locationId, cb);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import awais.instagrabber.models.enums.FollowingType
|
||||
import java.io.Serializable
|
||||
|
||||
data class Hashtag(
|
||||
val id: String,
|
||||
val name: String,
|
||||
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
|
||||
) : Serializable
|
||||
) : Serializable {
|
||||
val follow: Boolean
|
||||
get() = following == 1
|
||||
}
|
@ -3,9 +3,9 @@ package awais.instagrabber.repositories.responses
|
||||
data class LocationFeedResponse(
|
||||
val numResults: Int,
|
||||
val nextMaxId: String?,
|
||||
val moreAvailable: Boolean?,
|
||||
val moreAvailable: Boolean,
|
||||
val mediaCount: Long?,
|
||||
val status: String,
|
||||
val items: List<Media>?,
|
||||
val items: List<Media>,
|
||||
val location: Location
|
||||
)
|
@ -262,7 +262,7 @@ open class GraphQLRepository(private val service: GraphQLService) {
|
||||
body.getString(Constants.EXTRAS_ID),
|
||||
body.getString("name"),
|
||||
timelineMedia.getLong("count"),
|
||||
if (body.optBoolean("is_following")) FollowingType.FOLLOWING else FollowingType.NOT_FOLLOWING,
|
||||
if (body.optBoolean("is_following")) 1 else 0,
|
||||
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