Browse Source

retire LocationFetcher and enforce consistency

renovate/org.robolectric-robolectric-4.x
Austin Huang 4 years ago
parent
commit
fa1f5d2b72
No known key found for this signature in database GPG Key ID: 84C23AA04587A91F
  1. 5
      app/src/main/java/awais/instagrabber/activities/MainActivity.java
  2. 81
      app/src/main/java/awais/instagrabber/asyncs/LocationFetcher.java
  3. 10
      app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java
  4. 135
      app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
  5. 56
      app/src/main/java/awais/instagrabber/models/LocationModel.java
  6. 51
      app/src/main/java/awais/instagrabber/models/SuggestionModel.java
  7. 3
      app/src/main/java/awais/instagrabber/repositories/GraphQLRepository.java
  8. 3
      app/src/main/java/awais/instagrabber/repositories/LocationRepository.java
  9. 18
      app/src/main/java/awais/instagrabber/repositories/responses/Location.java
  10. 15
      app/src/main/java/awais/instagrabber/repositories/responses/Place.java
  11. 3
      app/src/main/java/awais/instagrabber/repositories/responses/search/SearchItem.java
  12. 45
      app/src/main/java/awais/instagrabber/webservices/GraphQLService.java
  13. 50
      app/src/main/java/awais/instagrabber/webservices/LocationService.java
  14. 56
      app/src/main/res/layout/layout_location_details.xml

5
app/src/main/java/awais/instagrabber/activities/MainActivity.java

@ -68,7 +68,6 @@ import awais.instagrabber.fragments.directmessages.DirectMessageInboxFragmentDir
import awais.instagrabber.fragments.main.FeedFragment; import awais.instagrabber.fragments.main.FeedFragment;
import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.fragments.settings.PreferenceKeys;
import awais.instagrabber.models.IntentModel; import awais.instagrabber.models.IntentModel;
import awais.instagrabber.models.SuggestionModel;
import awais.instagrabber.models.enums.SuggestionType; import awais.instagrabber.models.enums.SuggestionType;
import awais.instagrabber.repositories.responses.search.SearchItem; import awais.instagrabber.repositories.responses.search.SearchItem;
import awais.instagrabber.repositories.responses.search.SearchResponse; import awais.instagrabber.repositories.responses.search.SearchResponse;
@ -316,7 +315,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
switch (type) { switch (type) {
case TYPE_LOCATION: case TYPE_LOCATION:
bundle.putString("locationId", query);
bundle.putLong("locationId", Long.valueOf(query));
navController.navigate(R.id.action_global_locationFragment, bundle); navController.navigate(R.id.action_global_locationFragment, bundle);
break; break;
case TYPE_HASHTAG: case TYPE_HASHTAG:
@ -744,7 +743,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
final NavController navController = currentNavControllerLiveData.getValue(); final NavController navController = currentNavControllerLiveData.getValue();
if (navController == null) return; if (navController == null) return;
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putString("locationId", locationId);
bundle.putLong("locationId", Long.valueOf(locationId));
navController.navigate(R.id.action_global_locationFragment, bundle); navController.navigate(R.id.action_global_locationFragment, bundle);
} }

81
app/src/main/java/awais/instagrabber/asyncs/LocationFetcher.java

@ -1,81 +0,0 @@
package awais.instagrabber.asyncs;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import org.json.JSONObject;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.NetworkUtils;
//import awaisomereport.LogCollector;
//import static awais.instagrabber.utils.Utils.logCollector;
public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel> {
private static final String TAG = "LocationFetcher";
private final FetchListener<LocationModel> fetchListener;
private final long id;
public LocationFetcher(final long id, final FetchListener<LocationModel> fetchListener) {
// idSlug = id + "/" + slug UPDATE: slug can be ignored tbh
this.id = id;
this.fetchListener = fetchListener;
}
@Nullable
@Override
protected LocationModel doInBackground(final Void... voids) {
LocationModel result = null;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/locations/" + id + "/?__a=1")
.openConnection();
conn.setUseCaches(true);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject location = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql")
.getJSONObject(Constants.EXTRAS_LOCATION);
final JSONObject timelineMedia = location.getJSONObject("edge_location_to_media");
// if (timelineMedia.has("edges")) {
// final JSONArray edges = timelineMedia.getJSONArray("edges");
// }
result = new LocationModel(
location.getLong(Constants.EXTRAS_ID),
location.getString("name"),
location.getString("blurb"),
location.getString("website"),
location.getString("profile_pic_url"),
timelineMedia.getLong("count"),
BigDecimal.valueOf(location.optDouble("lat", 0d)).toString(),
BigDecimal.valueOf(location.optDouble("lng", 0d)).toString()
);
}
conn.disconnect();
} catch (final Exception e) {
// if (logCollector != null)
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_LOCATION_FETCHER, "doInBackground");
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}
}
return result;
}
@Override
protected void onPostExecute(final LocationModel result) {
if (fetchListener != null) fetchListener.onResult(result);
}
}

10
app/src/main/java/awais/instagrabber/asyncs/LocationPostFetchService.java

@ -4,7 +4,7 @@ import java.util.List;
import awais.instagrabber.customviews.helpers.PostFetcher; import awais.instagrabber.customviews.helpers.PostFetcher;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.PostsFetchResponse; import awais.instagrabber.repositories.responses.PostsFetchResponse;
import awais.instagrabber.webservices.GraphQLService; import awais.instagrabber.webservices.GraphQLService;
@ -14,12 +14,12 @@ import awais.instagrabber.webservices.ServiceCallback;
public class LocationPostFetchService implements PostFetcher.PostFetchService { public class LocationPostFetchService implements PostFetcher.PostFetchService {
private final LocationService locationService; private final LocationService locationService;
private final GraphQLService graphQLService; private final GraphQLService graphQLService;
private final LocationModel locationModel;
private final Location locationModel;
private String nextMaxId; private String nextMaxId;
private boolean moreAvailable; private boolean moreAvailable;
private final boolean isLoggedIn; private final boolean isLoggedIn;
public LocationPostFetchService(final LocationModel 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; locationService = isLoggedIn ? LocationService.getInstance() : null;
@ -47,8 +47,8 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
} }
} }
}; };
if (isLoggedIn) locationService.fetchPosts(locationModel.getId(), nextMaxId, cb);
else graphQLService.fetchLocationPosts(locationModel.getId(), nextMaxId, cb);
if (isLoggedIn) locationService.fetchPosts(locationModel.getPk(), nextMaxId, cb);
else graphQLService.fetchLocationPosts(locationModel.getPk(), nextMaxId, cb);
} }
@Override @Override

135
app/src/main/java/awais/instagrabber/fragments/LocationFragment.java

@ -3,14 +3,10 @@ package awais.instagrabber.fragments;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.Log; import android.util.Log;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -45,7 +41,6 @@ import java.util.Set;
import awais.instagrabber.R; import awais.instagrabber.R;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.adapters.FeedAdapterV2; import awais.instagrabber.adapters.FeedAdapterV2;
import awais.instagrabber.asyncs.LocationFetcher;
import awais.instagrabber.asyncs.LocationPostFetchService; import awais.instagrabber.asyncs.LocationPostFetchService;
import awais.instagrabber.asyncs.PostFetcher; import awais.instagrabber.asyncs.PostFetcher;
import awais.instagrabber.customviews.PrimaryActionModeCallback; import awais.instagrabber.customviews.PrimaryActionModeCallback;
@ -56,23 +51,24 @@ import awais.instagrabber.db.entities.Favorite;
import awais.instagrabber.db.repositories.FavoriteRepository; import awais.instagrabber.db.repositories.FavoriteRepository;
import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.db.repositories.RepositoryCallback;
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.repositories.requests.StoryViewerOptions; import awais.instagrabber.repositories.requests.StoryViewerOptions;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.CookieUtils;
import awais.instagrabber.utils.DownloadUtils; 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.GraphQLService;
import awais.instagrabber.webservices.LocationService;
import awais.instagrabber.webservices.ServiceCallback; import awais.instagrabber.webservices.ServiceCallback;
import awais.instagrabber.webservices.StoriesService; import awais.instagrabber.webservices.StoriesService;
//import awaisomereport.LogCollector; //import awaisomereport.LogCollector;
import static androidx.core.content.PermissionChecker.checkSelfPermission; import static androidx.core.content.PermissionChecker.checkSelfPermission;
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION; import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
//import static awais.instagrabber.utils.Utils.logCollector; //import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper; import static awais.instagrabber.utils.Utils.settingsHelper;
@ -89,9 +85,11 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
private boolean hasStories = false; private boolean hasStories = false;
private boolean opening = false; private boolean opening = false;
private long locationId; private long locationId;
private LocationModel locationModel;
private Location locationModel;
private ActionMode actionMode; private ActionMode actionMode;
private StoriesService storiesService; private StoriesService storiesService;
private GraphQLService graphQLService;
private LocationService locationService;
private AsyncTask<?, ?, ?> currentlyExecuting; private AsyncTask<?, ?, ?> currentlyExecuting;
private boolean isLoggedIn; private boolean isLoggedIn;
private boolean storiesFetching; private boolean storiesFetching;
@ -265,12 +263,29 @@ 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) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
fragmentActivity = (MainActivity) requireActivity(); fragmentActivity = (MainActivity) requireActivity();
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
locationService = isLoggedIn ? LocationService.getInstance() : null;
storiesService = StoriesService.getInstance(null, 0L, null); storiesService = StoriesService.getInstance(null, 0L, null);
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
setHasOptionsMenu(true); setHasOptionsMenu(true);
} }
@ -354,8 +369,6 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
private void init() { private void init() {
if (getArguments() == null) return; if (getArguments() == null) return;
final String cookie = settingsHelper.getString(Constants.COOKIE);
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments()); final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments());
locationId = fragmentArgs.getLocationId(); locationId = fragmentArgs.getLocationId();
locationDetailsBinding.favChip.setVisibility(View.GONE); locationDetailsBinding.favChip.setVisibility(View.GONE);
@ -377,42 +390,38 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
} }
private void fetchLocationModel() { private void fetchLocationModel() {
stopCurrentExecutor();
binding.swipeRefreshLayout.setRefreshing(true); binding.swipeRefreshLayout.setRefreshing(true);
currentlyExecuting = new LocationFetcher(locationId, result -> {
locationModel = result;
binding.swipeRefreshLayout.setRefreshing(false);
if (locationModel == null) {
final Context context = getContext();
if (context == null) return;
Toast.makeText(context, R.string.error_loading_location, Toast.LENGTH_SHORT).show();
binding.swipeRefreshLayout.setEnabled(false);
return;
}
setTitle();
setupLocationDetails();
setupPosts();
fetchStories();
// fetchPosts();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (isLoggedIn) locationService.fetch(locationId, cb);
else graphQLService.fetchLocation(locationId, cb);
} }
private void setupLocationDetails() { private void setupLocationDetails() {
final long locationId = locationModel.getId();
if (locationModel == null) {
try {
Toast.makeText(getContext(), R.string.error_loading_location, Toast.LENGTH_SHORT).show();
binding.swipeRefreshLayout.setEnabled(false);
}
catch (Exception ignored) {}
return;
}
setTitle();
setupPosts();
fetchStories();
final long locationId = locationModel.getPk();
// binding.swipeRefreshLayout.setRefreshing(true); // binding.swipeRefreshLayout.setRefreshing(true);
locationDetailsBinding.mainLocationImage.setImageURI(locationModel.getSdProfilePic());
final String postCount = String.valueOf(locationModel.getPostCount());
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
locationModel.getPostCount() > 2000000000L
? 2000000000
: locationModel.getPostCount().intValue(),
postCount));
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
locationDetailsBinding.mainLocPostCount.setText(span);
locationDetailsBinding.mainLocPostCount.setVisibility(View.VISIBLE);
locationDetailsBinding.mainLocationImage.setImageURI("res:/" + R.drawable.ic_location);
// final String postCount = String.valueOf(locationModel.getCount());
// final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
// locationModel.getPostCount() > 2000000000L
// ? 2000000000
// : locationModel.getPostCount().intValue(),
// postCount));
// span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
// span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
// locationDetailsBinding.mainLocPostCount.setText(span);
// locationDetailsBinding.mainLocPostCount.setVisibility(View.VISIBLE);
locationDetailsBinding.locationFullName.setText(locationModel.getName()); locationDetailsBinding.locationFullName.setText(locationModel.getName());
CharSequence biography = locationModel.getBio();
CharSequence biography = locationModel.getAddress() + "\n" + locationModel.getCity();
// binding.locationBiography.setCaptionIsExpandable(true); // binding.locationBiography.setCaptionIsExpandable(true);
// binding.locationBiography.setCaptionIsExpanded(true); // binding.locationBiography.setCaptionIsExpanded(true);
@ -423,22 +432,22 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
} else { } else {
locationDetailsBinding.locationBiography.setVisibility(View.VISIBLE); locationDetailsBinding.locationBiography.setVisibility(View.VISIBLE);
locationDetailsBinding.locationBiography.setText(biography); locationDetailsBinding.locationBiography.setText(biography);
locationDetailsBinding.locationBiography.addOnHashtagListener(autoLinkItem -> {
final NavController navController = NavHostFragment.findNavController(this);
final Bundle bundle = new Bundle();
final String originalText = autoLinkItem.getOriginalText().trim();
bundle.putString(ARG_HASHTAG, originalText);
navController.navigate(R.id.action_global_hashTagFragment, bundle);
});
locationDetailsBinding.locationBiography.addOnMentionClickListener(autoLinkItem -> {
final String originalText = autoLinkItem.getOriginalText().trim();
navigateToProfile(originalText);
});
locationDetailsBinding.locationBiography.addOnEmailClickListener(autoLinkItem -> Utils.openEmailAddress(context,
autoLinkItem.getOriginalText()
.trim()));
locationDetailsBinding.locationBiography
.addOnURLClickListener(autoLinkItem -> Utils.openURL(context, autoLinkItem.getOriginalText().trim()));
// locationDetailsBinding.locationBiography.addOnHashtagListener(autoLinkItem -> {
// final NavController navController = NavHostFragment.findNavController(this);
// final Bundle bundle = new Bundle();
// final String originalText = autoLinkItem.getOriginalText().trim();
// bundle.putString(ARG_HASHTAG, originalText);
// navController.navigate(R.id.action_global_hashTagFragment, bundle);
// });
// locationDetailsBinding.locationBiography.addOnMentionClickListener(autoLinkItem -> {
// final String originalText = autoLinkItem.getOriginalText().trim();
// navigateToProfile(originalText);
// });
// locationDetailsBinding.locationBiography.addOnEmailClickListener(autoLinkItem -> Utils.openEmailAddress(context,
// autoLinkItem.getOriginalText()
// .trim()));
// locationDetailsBinding.locationBiography
// .addOnURLClickListener(autoLinkItem -> Utils.openURL(context, autoLinkItem.getOriginalText().trim()));
locationDetailsBinding.locationBiography.setOnLongClickListener(v -> { locationDetailsBinding.locationBiography.setOnLongClickListener(v -> {
Utils.copyText(context, biography); Utils.copyText(context, biography);
return true; return true;
@ -457,16 +466,6 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
locationDetailsBinding.btnMap.setOnClickListener(null); locationDetailsBinding.btnMap.setOnClickListener(null);
} }
final String url = locationModel.getUrl();
if (TextUtils.isEmpty(url)) {
locationDetailsBinding.locationUrl.setVisibility(View.GONE);
} else if (!url.startsWith("http")) {
locationDetailsBinding.locationUrl.setVisibility(View.VISIBLE);
locationDetailsBinding.locationUrl.setText(TextUtils.getSpannableUrl("http://" + url));
} else {
locationDetailsBinding.locationUrl.setVisibility(View.VISIBLE);
locationDetailsBinding.locationUrl.setText(TextUtils.getSpannableUrl(url));
}
final FavoriteDataSource dataSource = FavoriteDataSource.getInstance(context); final FavoriteDataSource dataSource = FavoriteDataSource.getInstance(context);
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(dataSource); final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(dataSource);
locationDetailsBinding.favChip.setVisibility(View.VISIBLE); locationDetailsBinding.favChip.setVisibility(View.VISIBLE);
@ -481,7 +480,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
String.valueOf(locationId), String.valueOf(locationId),
FavoriteType.LOCATION, FavoriteType.LOCATION,
locationModel.getName(), locationModel.getName(),
locationModel.getSdProfilePic(),
"res:/" + R.drawable.ic_location,
result.getDateAdded() result.getDateAdded()
), new RepositoryCallback<Void>() { ), new RepositoryCallback<Void>() {
@Override @Override
@ -523,7 +522,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
String.valueOf(locationId), String.valueOf(locationId),
FavoriteType.LOCATION, FavoriteType.LOCATION,
locationModel.getName(), locationModel.getName(),
locationModel.getSdProfilePic(),
"res:/" + R.drawable.ic_location,
new Date() new Date()
), new RepositoryCallback<Void>() { ), new RepositoryCallback<Void>() {
@Override @Override

56
app/src/main/java/awais/instagrabber/models/LocationModel.java

@ -1,56 +0,0 @@
package awais.instagrabber.models;
import java.io.Serializable;
public final class LocationModel implements Serializable {
private final long postCount;
private final long id;
private final String name;
private final String bio;
private final String url;
private final String sdProfilePic;
private final String lat;
private final String lng;
public LocationModel(final long id,
final String name,
final String bio,
final String url,
final String sdProfilePic,
final long postCount,
final String lat,
final String lng) {
this.id = id;
this.name = name;
this.bio = bio;
this.url = url;
this.sdProfilePic = sdProfilePic;
this.postCount = postCount;
this.lat = lat;
this.lng = lng;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getBio() {
return bio;
}
public String getUrl() {
return url;
}
public String getGeo() { return "geo:" + lat + "," + lng + "?z=17&q=" + lat + "," + lng + "(" + name + ")"; }
public String getSdProfilePic() {
return sdProfilePic;
}
public Long getPostCount() { return postCount; }
}

51
app/src/main/java/awais/instagrabber/models/SuggestionModel.java

@ -1,51 +0,0 @@
package awais.instagrabber.models;
import androidx.annotation.NonNull;
import awais.instagrabber.models.enums.SuggestionType;
public final class SuggestionModel implements Comparable<SuggestionModel> {
private final int position;
private final boolean isVerified;
private final String username, name, profilePic;
private final SuggestionType suggestionType;
public SuggestionModel(final boolean isVerified, final String username, final String name, final String profilePic,
final SuggestionType suggestionType, final int position) {
this.isVerified = isVerified;
this.username = username;
this.name = name;
this.profilePic = profilePic;
this.suggestionType = suggestionType;
this.position = position;
}
public boolean isVerified() {
return isVerified;
}
public String getUsername() {
return username;
}
public String getName() {
return name;
}
public String getProfilePic() {
return profilePic;
}
public SuggestionType getSuggestionType() {
return suggestionType;
}
public int getPosition() {
return position;
}
@Override
public int compareTo(@NonNull final SuggestionModel model) {
return Integer.compare(getPosition(), model.getPosition());
}
}

3
app/src/main/java/awais/instagrabber/repositories/GraphQLRepository.java

@ -16,4 +16,7 @@ public interface GraphQLRepository {
@GET("/explore/tags/{tag}/?__a=1") @GET("/explore/tags/{tag}/?__a=1")
Call<String> getTag(@Path("tag") String tag); Call<String> getTag(@Path("tag") String tag);
@GET("/explore/locations/{locationId}/?__a=1")
Call<String> getLocation(@Path("locationId") long locationId);
} }

3
app/src/main/java/awais/instagrabber/repositories/LocationRepository.java

@ -3,12 +3,15 @@ package awais.instagrabber.repositories;
import java.util.Map; import java.util.Map;
import awais.instagrabber.repositories.responses.LocationFeedResponse; import awais.instagrabber.repositories.responses.LocationFeedResponse;
import awais.instagrabber.repositories.responses.Place;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.GET; import retrofit2.http.GET;
import retrofit2.http.Path; import retrofit2.http.Path;
import retrofit2.http.QueryMap; import retrofit2.http.QueryMap;
public interface LocationRepository { public interface LocationRepository {
@GET("/api/v1/locations/{location}/info/")
Call<Place> fetch(@Path("location") final long locationId);
@GET("/api/v1/feed/location/{location}/") @GET("/api/v1/feed/location/{location}/")
Call<LocationFeedResponse> fetchPosts(@Path("location") final long locationId, Call<LocationFeedResponse> fetchPosts(@Path("location") final long locationId,

18
app/src/main/java/awais/instagrabber/repositories/responses/Location.java

@ -9,16 +9,16 @@ public class Location implements Serializable {
private final String name; private final String name;
private final String address; private final String address;
private final String city; private final String city;
private final float lng;
private final float lat;
private final double lng;
private final double lat;
public Location(final long pk, public Location(final long pk,
final String shortName, final String shortName,
final String name, final String name,
final String address, final String address,
final String city, final String city,
final float lng,
final float lat) {
final double lng,
final double lat) {
this.pk = pk; this.pk = pk;
this.shortName = shortName; this.shortName = shortName;
this.name = name; this.name = name;
@ -48,22 +48,24 @@ public class Location implements Serializable {
return city; return city;
} }
public float getLng() {
public double getLng() {
return lng; return lng;
} }
public float getLat() {
public double getLat() {
return lat; return lat;
} }
public String getGeo() { return "geo:" + lat + "," + lng + "?z=17&q=" + lat + "," + lng + "(" + name + ")"; }
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
final Location location = (Location) o; final Location location = (Location) o;
return pk == location.pk && return pk == location.pk &&
Float.compare(location.lng, lng) == 0 &&
Float.compare(location.lat, lat) == 0 &&
Double.compare(location.lng, lng) == 0 &&
Double.compare(location.lat, lat) == 0 &&
Objects.equals(shortName, location.shortName) && Objects.equals(shortName, location.shortName) &&
Objects.equals(name, location.name) && Objects.equals(name, location.name) &&
Objects.equals(address, location.address) && Objects.equals(address, location.address) &&

15
app/src/main/java/awais/instagrabber/repositories/responses/search/Place.java → app/src/main/java/awais/instagrabber/repositories/responses/Place.java

@ -1,21 +1,24 @@
package awais.instagrabber.repositories.responses.search;
import awais.instagrabber.repositories.responses.Location;
package awais.instagrabber.repositories.responses;
public class Place { public class Place {
private final Location location; private final Location location;
// for search
private final String title; // those are repeated within location private final String title; // those are repeated within location
private final String subtitle; // address private final String subtitle; // address
private final String slug; // browser only; for end of address private final String slug; // browser only; for end of address
// for location info
private final String status;
public Place(final Location location, public Place(final Location location,
final String title, final String title,
final String subtitle, final String subtitle,
final String slug) {
final String slug,
final String status) {
this.location = location; this.location = location;
this.title = title; this.title = title;
this.subtitle = subtitle; this.subtitle = subtitle;
this.slug = slug; this.slug = slug;
this.status = status;
} }
public Location getLocation() { public Location getLocation() {
@ -33,4 +36,8 @@ public class Place {
public String getSlug() { public String getSlug() {
return slug; return slug;
} }
public String getStatus() {
return status;
}
} }

3
app/src/main/java/awais/instagrabber/repositories/responses/search/SearchItem.java

@ -1,8 +1,7 @@
package awais.instagrabber.repositories.responses.search; package awais.instagrabber.repositories.responses.search;
import java.util.List;
import awais.instagrabber.repositories.responses.Hashtag; import awais.instagrabber.repositories.responses.Hashtag;
import awais.instagrabber.repositories.responses.Place;
import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.User;
public class SearchItem { public class SearchItem {

45
app/src/main/java/awais/instagrabber/webservices/GraphQLService.java

@ -19,6 +19,7 @@ import awais.instagrabber.repositories.GraphQLRepository;
import awais.instagrabber.repositories.responses.FriendshipStatus; import awais.instagrabber.repositories.responses.FriendshipStatus;
import awais.instagrabber.repositories.responses.GraphQLUserListFetchResponse; import awais.instagrabber.repositories.responses.GraphQLUserListFetchResponse;
import awais.instagrabber.repositories.responses.Hashtag; import awais.instagrabber.repositories.responses.Hashtag;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.Media;
import awais.instagrabber.repositories.responses.PostsFetchResponse; import awais.instagrabber.repositories.responses.PostsFetchResponse;
import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.User;
@ -413,4 +414,48 @@ public class GraphQLService extends BaseService {
} }
}); });
} }
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);
}
}
});
}
} }

50
app/src/main/java/awais/instagrabber/webservices/LocationService.java

@ -5,7 +5,9 @@ import androidx.annotation.NonNull;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import awais.instagrabber.repositories.LocationRepository; import awais.instagrabber.repositories.LocationRepository;
import awais.instagrabber.repositories.responses.Location;
import awais.instagrabber.repositories.responses.LocationFeedResponse; import awais.instagrabber.repositories.responses.LocationFeedResponse;
import awais.instagrabber.repositories.responses.Place;
import awais.instagrabber.repositories.responses.PostsFetchResponse; import awais.instagrabber.repositories.responses.PostsFetchResponse;
import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.TextUtils;
import retrofit2.Call; import retrofit2.Call;
@ -69,34 +71,24 @@ public class LocationService extends BaseService {
}); });
} }
// private PostsFetchResponse parseResponse(@NonNull final String body) throws JSONException {
// final JSONObject root = new JSONObject(body);
// final boolean moreAvailable = root.optBoolean("more_available");
// final String nextMaxId = root.optString("next_max_id");
// final JSONArray itemsJson = root.optJSONArray("items");
// final List<FeedModel> items = parseItems(itemsJson);
// return new PostsFetchResponse(
// items,
// moreAvailable,
// nextMaxId
// );
// }
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());
}
// private List<FeedModel> parseItems(final JSONArray items) throws JSONException {
// if (items == null) {
// return Collections.emptyList();
// }
// final List<FeedModel> feedModels = new ArrayList<>();
// for (int i = 0; i < items.length(); i++) {
// final JSONObject itemJson = items.optJSONObject(i);
// if (itemJson == null) {
// continue;
// }
// final FeedModel feedModel = ResponseBodyUtils.parseItem(itemJson);
// if (feedModel != null) {
// feedModels.add(feedModel);
// }
// }
// return feedModels;
// }
@Override
public void onFailure(@NonNull final Call<Place> call, @NonNull final Throwable t) {
if (callback != null) {
callback.onFailure(t);
}
}
});
}
} }

56
app/src/main/res/layout/layout_location_details.xml

@ -15,25 +15,25 @@
android:layout_height="@dimen/profile_picture_size" android:layout_height="@dimen/profile_picture_size"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
app:actualImageScaleType="centerCrop" app:actualImageScaleType="centerCrop"
app:layout_constraintEnd_toStartOf="@id/mainLocPostCount"
app:layout_constraintEnd_toStartOf="@id/btnMap"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:background="@mipmap/ic_launcher" /> tools:background="@mipmap/ic_launcher" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mainLocPostCount"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:textAppearance="@style/TextAppearance.AppCompat"
app:layout_constraintBottom_toTopOf="@id/btnMap"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/mainLocationImage"
app:layout_constraintTop_toTopOf="parent"
tools:text="35 Posts" />
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/mainLocPostCount"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:gravity="center_vertical"-->
<!-- android:maxLines="1"-->
<!-- android:paddingStart="12dp"-->
<!-- android:paddingEnd="12dp"-->
<!-- android:textAppearance="@style/TextAppearance.AppCompat"-->
<!-- app:layout_constraintBottom_toTopOf="@id/btnMap"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toEndOf="@id/mainLocationImage"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:text="35 Posts" />-->
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/btnMap" android:id="@+id/btnMap"
@ -44,9 +44,8 @@
app:chipBackgroundColor="@null" app:chipBackgroundColor="@null"
app:chipIcon="@drawable/ic_outline_map_24" app:chipIcon="@drawable/ic_outline_map_24"
app:chipIconTint="@color/green_500" app:chipIconTint="@color/green_500"
app:layout_constraintBottom_toTopOf="@id/locationFullName"
app:layout_constraintTop_toTopOf="@id/mainLocationImage"
app:layout_constraintStart_toEndOf="@id/mainLocationImage" app:layout_constraintStart_toEndOf="@id/mainLocationImage"
app:layout_constraintTop_toBottomOf="@id/mainLocPostCount"
app:rippleColor="@color/grey_500" app:rippleColor="@color/grey_500"
tools:visibility="visible" /> tools:visibility="visible" />
@ -60,8 +59,8 @@
app:chipIcon="@drawable/ic_outline_star_plus_24" app:chipIcon="@drawable/ic_outline_star_plus_24"
app:chipIconTint="@color/yellow_800" app:chipIconTint="@color/yellow_800"
app:layout_constraintBottom_toBottomOf="@id/mainLocationImage" app:layout_constraintBottom_toBottomOf="@id/mainLocationImage"
app:layout_constraintStart_toEndOf="@id/btnMap"
app:layout_constraintTop_toBottomOf="@id/mainLocPostCount"
app:layout_constraintStart_toEndOf="@id/mainLocationImage"
app:layout_constraintTop_toBottomOf="@id/btnMap"
app:rippleColor="@color/yellow_400" /> app:rippleColor="@color/yellow_400" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
@ -90,27 +89,10 @@
android:padding="8dp" android:padding="8dp"
android:background="?android:selectableItemBackground" android:background="?android:selectableItemBackground"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintBottom_toTopOf="@id/locationUrl"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/locationFullName" app:layout_constraintTop_toBottomOf="@id/locationFullName"
tools:text="IN THE MIDDLE OF OUR STREET" /> tools:text="IN THE MIDDLE OF OUR STREET" />
<awais.instagrabber.customviews.RamboTextViewV2
android:id="@+id/locationUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/locationBiography"
android:ellipsize="marquee"
android:padding="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/locationBiography"
tools:text="https://austinhuang.me/"
tools:textColor="@android:color/holo_blue_dark"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save