geotag time part 2

This commit is contained in:
Austin Huang 2020-07-28 15:30:57 -04:00
parent e71faf3f20
commit 73795dac08
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
31 changed files with 593 additions and 101 deletions

View File

@ -10,9 +10,9 @@ android {
targetSdkVersion 29
// REMEMBER TO CHANGE versionCode AS WELL
// 16.7 is 32
// 16.7 is 32, 16.9 is 35 (34 is public beta)
versionCode 34
versionCode 35
versionName '16.9'
multiDexEnabled true

View File

@ -59,7 +59,10 @@ public final class InstaApp extends MultiDexApplication {
clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
if (datetimeParser == null)
datetimeParser = new SimpleDateFormat(settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
datetimeParser = new SimpleDateFormat(
settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED) ?
settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT) :
settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
changeTheme();
}

View File

@ -56,6 +56,7 @@ import awais.instagrabber.asyncs.FeedFetcher;
import awais.instagrabber.asyncs.FeedStoriesFetcher;
import awais.instagrabber.asyncs.HashtagFetcher;
import awais.instagrabber.asyncs.HighlightsFetcher;
import awais.instagrabber.asyncs.LocationFetcher;
import awais.instagrabber.asyncs.PostsFetcher;
import awais.instagrabber.asyncs.ProfileFetcher;
import awais.instagrabber.asyncs.StoryStatusFetcher;
@ -109,8 +110,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
final String username;
final String postFix;
if (!isHashtag) {
username = main.profileModel.getUsername();
if (!isHashtag && !isLocation) {
username = "@"+main.profileModel.getUsername();
postFix = "/" + main.profileModel.getPostCount() + ')';
} else {
username = null;
@ -119,6 +120,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (isHashtag)
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
else if (isLocation)
main.mainBinding.toolbar.toolbar.setTitle(main.locationModel.getName());
else main.mainBinding.toolbar.toolbar.setTitle(username + " (" + main.allItems.size() + postFix);
final PostModel model = result[result.length - 1];
@ -143,7 +146,6 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
.setUsername(main.profileModel.getUsername()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
main.mainBinding.swipeRefreshLayout.setRefreshing(false);
main.mainBinding.tagToolbar.setVisibility(View.VISIBLE);
}
model.setPageCursor(false, null);
}
@ -252,7 +254,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
private final Resources resources;
private final View collapsingToolbar;
private final RecyclerLazyLoader lazyLoader;
private boolean isHashtag;
private boolean isHashtag, isUser, isLocation;
private PostsAdapter postsAdapter;
private FeedAdapter feedAdapter;
private RecyclerLazyLoader feedLazyLoader, discoverLazyLoader;
@ -599,7 +601,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
.putExtra(Constants.EXTRAS_POST, new PostModel(modelText)), 9629);
} else {
main.addToStack();
main.userQuery = modelType == IntentModelType.HASHTAG ? '#' + modelText : modelText;
main.userQuery = modelType == IntentModelType.HASHTAG ? '#' + modelText : ("@"+modelText);
onRefresh();
}
}
@ -623,22 +625,36 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.privatePage.setVisibility(View.GONE);
main.mainBinding.mainProfileImage.setImageBitmap(null);
main.mainBinding.mainHashtagImage.setImageBitmap(null);
main.mainBinding.mainLocationImage.setImageBitmap(null);
main.mainBinding.mainUrl.setText(null);
main.mainBinding.locationUrl.setText(null);
main.mainBinding.mainFullName.setText(null);
main.mainBinding.locationFullName.setText(null);
main.mainBinding.mainPostCount.setText(null);
main.mainBinding.mainLocPostCount.setText(null);
main.mainBinding.mainTagPostCount.setText(null);
main.mainBinding.mainFollowers.setText(null);
main.mainBinding.mainFollowing.setText(null);
main.mainBinding.mainBiography.setText(null);
main.mainBinding.locationBiography.setText(null);
main.mainBinding.mainBiography.setEnabled(false);
main.mainBinding.locationBiography.setEnabled(false);
main.mainBinding.mainProfileImage.setEnabled(false);
main.mainBinding.mainLocationImage.setEnabled(false);
main.mainBinding.mainHashtagImage.setEnabled(false);
main.mainBinding.mainBiography.setMentionClickListener(null);
main.mainBinding.locationBiography.setMentionClickListener(null);
main.mainBinding.mainUrl.setVisibility(View.GONE);
main.mainBinding.mainTagPostCount.setVisibility(View.GONE);
main.mainBinding.locationUrl.setVisibility(View.GONE);
main.mainBinding.isVerified.setVisibility(View.GONE);
main.mainBinding.btnFollow.setVisibility(View.GONE);
main.mainBinding.btnRestrict.setVisibility(View.GONE);
main.mainBinding.btnBlock.setVisibility(View.GONE);
main.mainBinding.btnMap.setVisibility(View.GONE);
main.mainBinding.infoContainer.setVisibility(View.GONE);
main.mainBinding.tagInfoContainer.setVisibility(View.GONE);
main.mainBinding.locInfoContainer.setVisibility(View.GONE);
main.mainBinding.mainPosts.setNestedScrollingEnabled(false);
main.mainBinding.highlightsList.setVisibility(View.GONE);
@ -652,12 +668,14 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
}
isHashtag = main.userQuery.charAt(0) == '#';
collapsingToolbar.setVisibility(isHashtag ? View.GONE : View.VISIBLE);
isUser = main.userQuery.charAt(0) == '@';
isLocation = main.userQuery.contains("/");
collapsingToolbar.setVisibility(isUser ? View.VISIBLE : View.GONE);
if (isHashtag) {
main.profileModel = null;
main.locationModel = null;
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
main.mainBinding.infoContainer.setVisibility(View.GONE);
main.mainBinding.tagInfoContainer.setVisibility(View.VISIBLE);
main.mainBinding.btnFollowTag.setVisibility(View.GONE);
@ -683,7 +701,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.btnFollowTag.setOnClickListener(profileActionListener);
if (isLoggedIn) {
new StoryStatusFetcher(profileId, hashtagModel.getName(), result -> {
new StoryStatusFetcher(profileId, hashtagModel.getName(), false, result -> {
main.storyModels = result;
if (result != null && result.length > 0) main.mainBinding.mainHashtagImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -723,13 +741,14 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.mainTagPostCount.setText(span);
main.mainBinding.mainTagPostCount.setVisibility(View.VISIBLE);
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
} else if (isUser) {
main.hashtagModel = null;
main.mainBinding.tagInfoContainer.setVisibility(View.GONE);
main.locationModel = null;
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
main.mainBinding.infoContainer.setVisibility(View.VISIBLE);
main.mainBinding.btnFollowTag.setVisibility(View.GONE);
currentlyExecuting = new ProfileFetcher(main.userQuery, profileModel -> {
currentlyExecuting = new ProfileFetcher(main.userQuery.substring(1), profileModel -> {
main.profileModel = profileModel;
if (profileModel == null) {
@ -745,7 +764,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
final boolean isLoggedIn = !Utils.isEmpty(cookie);
if (isLoggedIn) {
new StoryStatusFetcher(profileId, "", result -> {
new StoryStatusFetcher(profileId, "", false, result -> {
main.storyModels = result;
if (result != null && result.length > 0) main.mainBinding.mainProfileImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -907,7 +926,110 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
main.mainBinding.privatePage.setVisibility(View.VISIBLE);
main.mainBinding.mainPosts.setVisibility(View.GONE);
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else if (isLocation) {
main.profileModel = null;
main.hashtagModel = null;
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
main.mainBinding.locInfoContainer.setVisibility(View.VISIBLE);
currentlyExecuting = new LocationFetcher(main.userQuery, locationModel -> {
main.locationModel = locationModel;
main.mainBinding.toolbar.toolbar.setTitle(locationModel.getName());
if (locationModel == null) {
main.mainBinding.swipeRefreshLayout.setRefreshing(false);
Toast.makeText(main, R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
main.mainBinding.toolbar.toolbar.setTitle(R.string.app_name);
return;
}
final String profileId = locationModel.getId();
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
final boolean isLoggedIn = !Utils.isEmpty(cookie);
if (isLoggedIn) {
new StoryStatusFetcher(profileId, "", true, result -> {
main.storyModels = result;
if (result != null && result.length > 0) main.mainBinding.mainLocationImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
main.mainBinding.mainLocationImage.setEnabled(false);
new MyTask().execute();
main.mainBinding.mainLocationImage.setEnabled(true);
final String postCount = String.valueOf(locationModel.getPostCount());
SpannableStringBuilder span = new SpannableStringBuilder(resources.getString(R.string.main_posts_count, postCount));
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
main.mainBinding.mainLocPostCount.setText(span);
main.mainBinding.locationFullName.setText(locationModel.getName());
CharSequence biography = locationModel.getBio();
main.mainBinding.locationBiography.setCaptionIsExpandable(true);
main.mainBinding.locationBiography.setCaptionIsExpanded(true);
if (Utils.isEmpty(biography)) {
main.mainBinding.locationBiography.setVisibility(View.GONE);
}
else if (Utils.hasMentions(biography)) {
main.mainBinding.locationBiography.setVisibility(View.VISIBLE);
biography = Utils.getMentionText(biography);
main.mainBinding.locationBiography.setText(biography, TextView.BufferType.SPANNABLE);
main.mainBinding.locationBiography.setMentionClickListener(mentionClickListener);
} else {
main.mainBinding.locationBiography.setVisibility(View.VISIBLE);
main.mainBinding.locationBiography.setText(biography);
main.mainBinding.locationBiography.setMentionClickListener(null);
}
if (!locationModel.getGeo().startsWith("geo:0.0,0.0?z=17")) {
main.mainBinding.btnMap.setVisibility(View.VISIBLE);
main.mainBinding.btnMap.setOnClickListener(v -> {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(locationModel.getGeo()));
main.startActivity(intent);
});
}
else {
main.mainBinding.btnMap.setVisibility(View.GONE);
main.mainBinding.btnMap.setOnClickListener(null);
}
final String url = locationModel.getUrl();
if (Utils.isEmpty(url)) {
main.mainBinding.locationUrl.setVisibility(View.GONE);
} else if (!url.startsWith("http")) {
main.mainBinding.locationUrl.setVisibility(View.VISIBLE);
main.mainBinding.locationUrl.setText(Utils.getSpannableUrl("http://"+url));
} else {
main.mainBinding.locationUrl.setVisibility(View.VISIBLE);
main.mainBinding.locationUrl.setText(Utils.getSpannableUrl(url));
}
main.mainBinding.locationFullName.setSelected(true);
main.mainBinding.locationBiography.setEnabled(true);
if (locationModel.getPostCount() == 0) {
main.mainBinding.swipeRefreshLayout.setRefreshing(false);
main.mainBinding.privatePage1.setImageResource(R.drawable.ic_cancel);
main.mainBinding.privatePage2.setText(R.string.empty_acc);
main.mainBinding.privatePage.setVisibility(View.VISIBLE);
}
else {
main.mainBinding.swipeRefreshLayout.setRefreshing(true);
main.mainBinding.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(locationModel.getName())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@ -1020,7 +1142,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
protected Void doInBackground(Void... voids) {
try {
mIcon_val = BitmapFactory.decodeStream((InputStream) new URL(
(main.hashtagModel != null) ? main.hashtagModel.getSdProfilePic() : main.profileModel.getSdProfilePic()
(main.hashtagModel != null) ? main.hashtagModel.getSdProfilePic() : (
(main.locationModel != null) ? main.locationModel.getSdProfilePic() :
main.profileModel.getSdProfilePic())
).getContent());
} catch (Throwable ex) {
Log.e("austin_debug", "bitmap: " + ex);
@ -1031,6 +1155,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
@Override
protected void onPostExecute(Void result) {
if (main.hashtagModel != null) main.mainBinding.mainHashtagImage.setImageBitmap(mIcon_val);
else if (main.locationModel != null) main.mainBinding.mainLocationImage.setImageBitmap(mIcon_val);
else main.mainBinding.mainProfileImage.setImageBitmap(mIcon_val);
}
}
@ -1040,10 +1165,12 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
public void onClick(final View v) {
if (!isLoggedIn && Utils.dataBox.getFavorite(main.userQuery) != null) {
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(main.userQuery,
Long.parseLong(Utils.dataBox.getFavorite(main.userQuery).split("/")[1])));
Long.parseLong(Utils.dataBox.getFavorite(main.userQuery).split("/")[1]),
main.locationModel != null ? main.locationModel.getName() : main.userQuery));
onRefresh();
} else if (!isLoggedIn) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(main.userQuery, System.currentTimeMillis()));
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(main.userQuery, System.currentTimeMillis(),
main.locationModel != null ? main.locationModel.getName() : main.userQuery));
onRefresh();
} else if (v == main.mainBinding.btnFollow) {
new ProfileAction().execute("follow");
@ -1096,7 +1223,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
ok = true;
}
else Toast.makeText(main, R.string.downloader_unknown_error, Toast.LENGTH_SHORT);
else Toast.makeText(main, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
urlConnection.disconnect();
} catch (Throwable ex) {
Log.e("austin_debug", action+": " + ex);

View File

@ -69,8 +69,6 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
return;
}
Log.d("austin_debug", "f:"+postId);
commentsBinding.swipeRefreshLayout.setRefreshing(true);
setSupportActionBar(commentsBinding.toolbar.toolbar);
commentsBinding.toolbar.toolbar.setTitle(R.string.title_comments);
@ -253,7 +251,6 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
final String action = rawAction[0];
final String url = "https://www.instagram.com/web/comments/"+postId+"/"+action+"/";
try {
Log.d("austin_debug", url);
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);

View File

@ -9,6 +9,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.provider.BaseColumns;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -43,6 +44,7 @@ import awais.instagrabber.models.DiscoverItemModel;
import awais.instagrabber.models.FeedModel;
import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.HighlightModel;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel;
@ -91,6 +93,7 @@ public final class Main extends BaseLanguageActivity {
public MainHelper mainHelper;
public ProfileModel profileModel;
public HashtagModel hashtagModel;
public LocationModel locationModel;
private AutoCompleteTextView searchAutoComplete;
private ArrayAdapter<String> profileDialogAdapter;
private DialogInterface.OnClickListener profileDialogListener;
@ -139,7 +142,7 @@ public final class Main extends BaseLanguageActivity {
if (mainHelper != null && !Utils.isEmpty(result)) {
closeAnyOpenDrawer();
addToStack();
userQuery = result;
userQuery = (result.contains("/") || result.startsWith("#")) ? result : ("@"+result);
mainHelper.onRefresh();
}
};
@ -193,8 +196,8 @@ public final class Main extends BaseLanguageActivity {
final Intent intent;
if (which == 0 || storyModels == null || storyModels.length < 1) {
intent = new Intent(this, ProfileViewer.class).putExtra(
((hashtagModel != null) ? Constants.EXTRAS_HASHTAG : Constants.EXTRAS_PROFILE),
((hashtagModel != null) ? hashtagModel : profileModel));
((hashtagModel != null) ? Constants.EXTRAS_HASHTAG : (locationModel != null ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_PROFILE)),
((hashtagModel != null) ? hashtagModel : (locationModel != null ? locationModel : profileModel)));
}
else intent = new Intent(this, StoryViewer.class).putExtra(Constants.EXTRAS_USERNAME, userQuery)
.putExtra(Constants.EXTRAS_STORIES, storyModels)
@ -205,7 +208,9 @@ public final class Main extends BaseLanguageActivity {
final View.OnClickListener onClickListener = v -> {
if (v == mainBinding.mainBiography) {
Utils.copyText(this, mainBinding.mainBiography.getText().toString());
} else if (v == mainBinding.mainProfileImage || v == mainBinding.mainHashtagImage) {
} else if (v == mainBinding.locationBiography) {
Utils.copyText(this, mainBinding.locationBiography.getText().toString());
} else if (v == mainBinding.mainProfileImage || v == mainBinding.mainHashtagImage || v == mainBinding.mainLocationImage) {
if (storyModels == null || storyModels.length <= 0) {
profileDialogListener.onClick(null, 0);
} else {
@ -217,16 +222,19 @@ public final class Main extends BaseLanguageActivity {
};
mainBinding.mainBiography.setOnClickListener(onClickListener);
mainBinding.locationBiography.setOnClickListener(onClickListener);
mainBinding.mainProfileImage.setOnClickListener(onClickListener);
mainBinding.mainHashtagImage.setOnClickListener(onClickListener);
mainBinding.mainLocationImage.setOnClickListener(onClickListener);
mainBinding.mainBiography.setEnabled(false);
mainBinding.mainProfileImage.setEnabled(false);
mainBinding.mainHashtagImage.setEnabled(false);
mainBinding.mainLocationImage.setEnabled(false);
final boolean isQueryNull = userQuery == null;
if (isQueryNull) allItems.clear();
if (BuildConfig.DEBUG && isQueryNull) userQuery = "austinhuang.me";
if (BuildConfig.DEBUG && isQueryNull) userQuery = "@austinhuang.me";
if (!mainBinding.swipeRefreshLayout.isRefreshing() && userQuery != null) mainHelper.onRefresh();
mainHelper.onIntent(getIntent());
@ -291,7 +299,9 @@ public final class Main extends BaseLanguageActivity {
else if (item == settingsAction)
new SettingsDialog().show(fragmentManager, "settings");
else if (item == quickAccessAction)
new QuickAccessDialog().setQuery(userQuery).show(fragmentManager, "quickAccess");
new QuickAccessDialog()
.setQuery(userQuery, locationModel != null ? locationModel.getName() : userQuery)
.show(fragmentManager, "quickAccess");
else
new AboutDialog().show(fragmentManager, "about");
return true;
@ -359,7 +369,9 @@ public final class Main extends BaseLanguageActivity {
final SuggestionModel suggestionModel = result[i];
if (suggestionModel != null) {
final SuggestionType suggestionType = suggestionModel.getSuggestionType();
final Object[] objects = {i, suggestionModel.getUsername(), suggestionModel.getName(),
final Object[] objects = {i,
(suggestionType == SuggestionType.TYPE_LOCATION) ? suggestionModel.getName() : suggestionModel.getUsername(),
(suggestionType == SuggestionType.TYPE_LOCATION) ? suggestionModel.getUsername() : suggestionModel.getName(),
suggestionType, suggestionModel.getProfilePic(), suggestionModel.isVerified()};
if (!searchHash && !searchUser) cursor.addRow(objects);
@ -388,7 +400,7 @@ public final class Main extends BaseLanguageActivity {
closeAnyOpenDrawer();
addToStack();
userQuery = query;
userQuery = (query.contains("@") || query.contains("#")) ? query : ("@"+query);
searchAction.collapseActionView();
searchView.setIconified(true);
searchView.setIconified(true);

View File

@ -51,6 +51,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.json.JSONObject;
import awais.instagrabber.R;
import awais.instagrabber.adapters.PostsMediaAdapter;
import awais.instagrabber.asyncs.PostFetcher;
@ -404,7 +406,8 @@ public final class PostViewer extends BaseLanguageActivity {
postModel.setBookmark(viewerPostModel.getBookmark());
}
setupPostInfoBar(viewerPostModel.getUsername(), viewerPostModel.getItemType(), viewerPostModel.getLocation());
setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocation() == null ? null : viewerPostModel.getLocation());
postCaption = postModel.getPostCaption();
viewerCaptionParent.setVisibility(View.VISIBLE);
@ -609,7 +612,8 @@ public final class PostViewer extends BaseLanguageActivity {
viewerBinding.bottomPanel.viewerCaption.setText(postCaption);
}
setupPostInfoBar(viewerPostModel.getUsername(), viewerPostModel.getItemType(), viewerPostModel.getLocation());
setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
viewerPostModel.getLocation());
if (postModel instanceof PostModel) {
final PostModel postModel = (PostModel) this.postModel;
@ -659,14 +663,14 @@ public final class PostViewer extends BaseLanguageActivity {
}
}
private void setupPostInfoBar(final String from, final MediaItemType mediaItemType, final String location) {
private void setupPostInfoBar(final String from, final MediaItemType mediaItemType, final JSONObject location) {
if (prevUsername == null || !prevUsername.equals(from)) {
viewerBinding.topPanel.ivProfilePic.setImageBitmap(null);
viewerBinding.topPanel.ivProfilePic.setImageDrawable(null);
viewerBinding.topPanel.ivProfilePic.setImageResource(0);
if (from.charAt(0) != '#')
new ProfileFetcher(from, result -> {
if (from.charAt(0) == '@')
new ProfileFetcher(from.substring(1), result -> {
profileModel = result;
if (result != null) {
@ -706,10 +710,9 @@ public final class PostViewer extends BaseLanguageActivity {
R.string.post_viewer_video_post : R.string.post_viewer_image_post);
if (Utils.isEmpty(from)) viewerBinding.topPanel.title.setText(titlePrefix);
else {
final CharSequence titleText = resources.getString(R.string.post_viewer_post_from, titlePrefix, from) + " ";
final int titleLen = titleText.length();
final SpannableString spannableString = new SpannableString(titleText);
spannableString.setSpan(new CommentMentionClickSpan(), titleLen - from.length() - 1, titleLen - 1, 0);
final int titleLen = from.length();
final SpannableString spannableString = new SpannableString(from);
spannableString.setSpan(new CommentMentionClickSpan(), 0, titleLen, 0);
viewerBinding.topPanel.title.setText(spannableString);
}
@ -721,7 +724,13 @@ public final class PostViewer extends BaseLanguageActivity {
}
else {
viewerBinding.topPanel.location.setVisibility(View.VISIBLE);
viewerBinding.topPanel.location.setText(location);
viewerBinding.topPanel.location.setText(location.optString("name"));
viewerBinding.topPanel.location.setOnClickListener(v ->
new AlertDialog.Builder(PostViewer.this).setTitle(location.optString("name"))
.setMessage(R.string.comment_view_mention_location_search)
.setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
(dialog, which) -> searchUsername(location.optString("id")+"/"+location.optString("slug"))).show()
);
viewerBinding.topPanel.title.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
));

View File

@ -32,6 +32,7 @@ import awais.instagrabber.databinding.ActivityProfileBinding;
import awais.instagrabber.dialogs.ProfileSettingsDialog;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.enums.ProfilePictureFetchMode;
import awais.instagrabber.utils.Constants;
@ -47,6 +48,7 @@ public final class ProfileViewer extends BaseLanguageActivity {
private ActivityProfileBinding profileBinding;
private ProfileModel profileModel;
private HashtagModel hashtagModel;
private LocationModel locationModel;
private MenuItem menuItemDownload;
private String profilePicUrl;
private FragmentManager fragmentManager;
@ -64,17 +66,18 @@ public final class ProfileViewer extends BaseLanguageActivity {
setSupportActionBar(profileBinding.toolbar.toolbar);
final Intent intent = getIntent();
if (intent == null || (!intent.hasExtra(Constants.EXTRAS_PROFILE) && !intent.hasExtra(Constants.EXTRAS_HASHTAG))
if (intent == null || (!intent.hasExtra(Constants.EXTRAS_PROFILE) && !intent.hasExtra(Constants.EXTRAS_HASHTAG) && !intent.hasExtra(Constants.EXTRAS_LOCATION))
|| ((profileModel = (ProfileModel) intent.getSerializableExtra(Constants.EXTRAS_PROFILE)) == null
&& (hashtagModel = (HashtagModel) intent.getSerializableExtra(Constants.EXTRAS_HASHTAG)) == null)) {
&& (hashtagModel = (HashtagModel) intent.getSerializableExtra(Constants.EXTRAS_HASHTAG)) == null
&& (locationModel = (LocationModel) intent.getSerializableExtra(Constants.EXTRAS_LOCATION)) == null)) {
Utils.errorFinish(this);
return;
}
fragmentManager = getSupportFragmentManager();
final String id = hashtagModel != null ? hashtagModel.getId() : profileModel.getId();
final String username = hashtagModel != null ? hashtagModel.getName() : profileModel.getUsername();
final String id = hashtagModel != null ? hashtagModel.getId() : (locationModel != null ? locationModel.getId() : profileModel.getId());
final String username = hashtagModel != null ? hashtagModel.getName() : (locationModel != null ? locationModel.getName() : profileModel.getUsername());
profileBinding.toolbar.toolbar.setTitle(username);
@ -93,12 +96,12 @@ public final class ProfileViewer extends BaseLanguageActivity {
if (!fallbackToProfile && Utils.isEmpty(profilePicUrl)) {
fallbackToProfile = true;
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, hashtagModel != null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, (hashtagModel != null || locationModel != null)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return;
}
if (errorHandled && fallbackToProfile || Utils.isEmpty(profilePicUrl))
profilePicUrl = hashtagModel != null ? hashtagModel.getSdProfilePic() : profileModel.getHdProfilePic();
profilePicUrl = hashtagModel != null ? hashtagModel.getSdProfilePic() : (locationModel != null ? locationModel.getSdProfilePic() : profileModel.getHdProfilePic());
if (destroyed == true) return;
@ -110,7 +113,7 @@ public final class ProfileViewer extends BaseLanguageActivity {
fallbackToProfile = true;
if (!errorHandled) {
errorHandled = true;
new ProfilePictureFetcher(username, id, fetchListener, fetchModes[Math.min(2, Math.max(0, fetchIndex + 1))], profilePicUrl, hashtagModel != null)
new ProfilePictureFetcher(username, id, fetchListener, fetchModes[Math.min(2, Math.max(0, fetchIndex + 1))], profilePicUrl, (hashtagModel != null || locationModel != null))
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
glideRequestManager.load(profilePicUrl).into(profileBinding.imageViewer);
@ -165,7 +168,7 @@ public final class ProfileViewer extends BaseLanguageActivity {
}).into(profileBinding.imageViewer);
};
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, hashtagModel != null)
new ProfilePictureFetcher(username, id, fetchListener, fetchMode, profilePicUrl, (hashtagModel != null || locationModel != null))
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

View File

@ -15,6 +15,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -35,6 +36,8 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import java.util.ArrayList;
import java.util.Collections;
import org.json.JSONObject;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
import awais.instagrabber.activities.CommentsViewer;
@ -195,7 +198,7 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
final ProfileModel profileModel = feedModel.getProfileModel();
if (profileModel != null) {
glideRequestManager.load(profileModel.getSdProfilePic()).into(viewHolder.profilePic);
viewHolder.username.setText(profileModel.getUsername());
viewHolder.username.setText("@"+profileModel.getUsername());
}
viewHolder.viewPost.setOnClickListener(clickListener);
@ -217,6 +220,22 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
viewHolder.btnComments.setEnabled(true);
}
final JSONObject location = feedModel.getLocation();
if (location == null) {
viewHolder.location.setVisibility(View.GONE);
viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT
));
}
else {
viewHolder.location.setVisibility(View.VISIBLE);
viewHolder.location.setText(location.optString("name"));
viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
));
}
final String thumbnailUrl = feedModel.getThumbnailUrl();
final String displayUrl = feedModel.getDisplayUrl();
CharSequence postCaption = feedModel.getPostCaption();
@ -313,7 +332,7 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
};
viewHolder.btnMute.setOnClickListener(muteClickListener);
viewHolder.mediaList.setAdapter(new ChildMediaItemsAdapter(sliderItems, viewHolder.btnMute, muteClickListener, playerChangeListener));
viewHolder.mediaList.setAdapter(new ChildMediaItemsAdapter(sliderItems, viewHolder.btnMute, playerChangeListener));
}
} else {
viewToChangeHeight = viewHolder.imageView;
@ -382,14 +401,12 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
private static final class ChildMediaItemsAdapter extends PagerAdapter {
private final PlayerChangeListener playerChangeListener;
private final View.OnClickListener muteClickListener;
private final ViewerPostModel[] sliderItems;
private final View btnMute;
private SimpleExoPlayer player;
private ChildMediaItemsAdapter(final ViewerPostModel[] sliderItems, final View btnMute, final View.OnClickListener muteClickListener,
private ChildMediaItemsAdapter(final ViewerPostModel[] sliderItems, final View btnMute,
final PlayerChangeListener playerChangeListener) {
this.muteClickListener = muteClickListener;
this.sliderItems = sliderItems;
this.btnMute = btnMute;
if (BuildConfig.DEBUG) this.playerChangeListener = playerChangeListener;
@ -408,6 +425,8 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
if (btnMute != null) btnMute.setVisibility(View.VISIBLE);
final PlayerView playerView = new PlayerView(context);
Log.d("austin_debug","1");
player = new SimpleExoPlayer.Builder(context).build();
playerView.setPlayer(player);
@ -424,7 +443,6 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
player.setVolume(vol);
playerView.setTag(player);
playerView.setOnClickListener(muteClickListener);
if (playerChangeListener != null) {
//todo

View File

@ -46,9 +46,10 @@ public final class SuggestionsAdapter extends CursorAdapter {
final boolean verified = cursor.getString(5).charAt(0) == 't';
if ("TYPE_HASHTAG".equals(cursor.getString(3))) username = '#' + username;
else if ("TYPE_USER".equals(cursor.getString(3))) username = '@' + username;
view.setOnClickListener(onClickListener);
view.setTag(username);
view.setTag("TYPE_LOCATION".equals(cursor.getString(3)) ? fullname : username);
view.findViewById(R.id.isVerified).setVisibility(verified ? View.VISIBLE : View.GONE);
@ -56,6 +57,6 @@ public final class SuggestionsAdapter extends CursorAdapter {
((TextView) view.findViewById(R.id.tvFullName)).setText(fullname);
glideRequestManager.applyDefaultRequestOptions(new RequestOptions().skipMemoryCache(true))
.load(picUrl).into((ImageView) view.findViewById(R.id.ivProfilePic));
.load(picUrl == null ? R.drawable.ic_location : picUrl).into((ImageView) view.findViewById(R.id.ivProfilePic));
}
}

View File

@ -16,7 +16,7 @@ import awais.instagrabber.customviews.RamboTextView;
public final class FeedItemViewHolder extends RecyclerView.ViewHolder {
public final ImageView profilePic, btnMute, btnDownload;
public final TextView username, commentsCount, videoViews, mediaCounter, tvPostDate;
public final TextView username, commentsCount, videoViews, mediaCounter, tvPostDate, location;
public final RamboTextView viewerCaption;
public final View btnComments, videoViewsParent, viewPost;
public final ViewPager mediaList;
@ -34,6 +34,7 @@ public final class FeedItemViewHolder extends RecyclerView.ViewHolder {
tvPostDate = itemView.findViewById(R.id.tvPostDate);
viewPost = itemView.findViewById(R.id.viewStoryPost);
username = itemView.findViewById(R.id.title);
location = itemView.findViewById(R.id.location);
// video view
btnMute = itemView.findViewById(R.id.btnMute);

View File

@ -133,7 +133,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
feedItem.optLong("taken_at_timestamp", -1),
feedItem.getBoolean("viewer_has_liked"),
feedItem.getBoolean("viewer_has_saved"),
feedItem.getJSONObject("edge_media_preview_like").getLong("count"));
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
feedItem.optJSONObject("location"));
final boolean isSlider = "GraphSidecar".equals(mediaType) && feedItem.has("edge_sidecar_to_children");
@ -156,7 +157,7 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
null, null, null,
node.optLong("video_view_count", -1), -1, false, false,
feedItem.getJSONObject("edge_media_preview_like").getLong("count"),
feedItem.getJSONObject("location") == null ? null : feedItem.getJSONObject("location").optString("name"));
feedItem.optJSONObject("location"));
sliderItems[j].setSliderDisplayUrl(node.getString("display_url"));
}

View File

@ -0,0 +1,79 @@
package awais.instagrabber.asyncs;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import org.json.JSONArray;
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.Utils;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel> {
private final FetchListener<LocationModel> fetchListener;
private final String idSlug;
public LocationFetcher(String idSlug, FetchListener<LocationModel> fetchListener) {
Log.d("austin_debug", idSlug);
// idSlug = id + "/" + slug
this.idSlug = idSlug;
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/" + idSlug + "/?__a=1").openConnection();
conn.setUseCaches(true);
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
final JSONObject user = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_LOCATION);
final JSONObject timelineMedia = user.getJSONObject("edge_location_to_media");
if (timelineMedia.has("edges")) {
final JSONArray edges = timelineMedia.getJSONArray("edges");
}
result = new LocationModel(
user.getString(Constants.EXTRAS_ID) + "/" + user.getString("slug"),
user.getString("name"),
user.getString("blurb"),
user.getString("website"),
user.getString("profile_pic_url"),
timelineMedia.getLong("count"),
BigDecimal.valueOf(user.optDouble("lat", 0d)).toString(),
BigDecimal.valueOf(user.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("AWAISKING_APP", "", e);
}
return result;
}
@Override
protected void onPostExecute(final LocationModel result) {
if (fetchListener != null) fetchListener.onResult(result);
}
}

View File

@ -90,7 +90,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),
media.optJSONObject("location") == null ? null : media.getJSONObject("location").optString("name"));
media.optJSONObject("location"));
postModel.setCommentsCount(commentsCount);
postModel.setCommentsEndCursor(endCursor);
@ -116,7 +116,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
isChildVideo && node.has("video_view_count") ? node.getLong("video_view_count") : -1,
timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"),
media.getJSONObject("edge_media_preview_like").getLong("count"),
media.optJSONObject("location") == null ? null : media.getJSONObject("location").optString("name"));
media.optJSONObject("location"));
postModels[i].setSliderDisplayUrl(node.getString("display_url"));
Utils.checkExistence(downloadDir, customDir, username, true, i, postModels[i]);

View File

@ -49,11 +49,15 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
@Override
protected PostModel[] doInBackground(final Void... voids) {
final boolean isHashTag = id.charAt(0) == '#';
final boolean isLocation = id.contains("/");
final String url;
if (isHashTag)
url = "https://www.instagram.com/graphql/query/?query_hash=ded47faa9a1aaded10161a2ff32abb6b&variables=" +
"{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isLocation)
url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" +
"{\"id\":\""+ id.split("/")[0] +"\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else
url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=" + id + "&first=50&after=" + endCursor;
@ -73,8 +77,10 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
}
final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data")
.getJSONObject(isHashTag ? "hashtag" : Constants.EXTRAS_USER)
.getJSONObject(isHashTag ? "edge_hashtag_to_media" : "edge_owner_to_timeline_media");
.getJSONObject(isHashTag ? Constants.EXTRAS_HASHTAG :
(isLocation ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_USER))
.getJSONObject(isHashTag ? "edge_hashtag_to_media" :
(isLocation ? "edge_location_to_media" : "edge_owner_to_timeline_media"));
final String endCursor;
final boolean hasNextPage;

View File

@ -21,11 +21,13 @@ import static awais.instagrabber.utils.Utils.logCollector;
public final class StoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[]> {
private final String id, hashtag;
private final boolean location;
private final FetchListener<StoryModel[]> fetchListener;
public StoryStatusFetcher(final String id, final String hashtag, final FetchListener<StoryModel[]> fetchListener) {
public StoryStatusFetcher(final String id, final String hashtag, final boolean location, final FetchListener<StoryModel[]> fetchListener) {
this.id = id;
this.hashtag = hashtag;
this.location = location;
this.fetchListener = fetchListener;
}
@ -33,8 +35,9 @@ public final class StoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[]
protected StoryModel[] doInBackground(final Void... voids) {
StoryModel[] result = null;
final String url = "https://www.instagram.com/graphql/query/?query_hash=52a36e788a02a3c612742ed5146f1676&variables=" +
"{\"precomposed_overlay\":false,\"reel_ids\":[\"" + id + "\"]"
+(!Utils.isEmpty(hashtag) ? (",\"tag_names\":\""+hashtag+"\"") : "")+"}";
"{\"precomposed_overlay\":false,"
+(!Utils.isEmpty(hashtag) ? ("\"tag_names\":\""+hashtag+"\"}") : (
location ? "\"location_ids\":[\""+id.split("/")[0]+"\"]}" : "\"reel_ids\":[\"" + id + "\"]}"));
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

View File

@ -48,9 +48,11 @@ public final class SuggestionsFetcher extends AsyncTask<String, String, Suggesti
final JSONArray usersArray = jsonObject.getJSONArray("users");
final JSONArray hashtagsArray = jsonObject.getJSONArray("hashtags");
final JSONArray placesArray = jsonObject.getJSONArray("places");
final int usersLen = usersArray.length();
final int hashtagsLen = hashtagsArray.length();
final int placesLen = placesArray.length();
final ArrayList<SuggestionModel> suggestionModels = new ArrayList<>(usersLen + hashtagsLen);
for (int i = 0; i < hashtagsLen; i++) {
@ -66,6 +68,20 @@ public final class SuggestionsFetcher extends AsyncTask<String, String, Suggesti
hashtagsArrayJSONObject.optInt("position", suggestionModels.size() - 1)));
}
for (int i = 0; i < placesLen; i++) {
final JSONObject placesArrayJSONObject = placesArray.getJSONObject(i);
final JSONObject place = placesArrayJSONObject.getJSONObject("place");
// name
suggestionModels.add(new SuggestionModel(false,
place.getJSONObject("location").getString("pk")+"/"+place.getString("slug"),
place.getString("title"),
place.optString("profile_pic_url", null),
SuggestionType.TYPE_LOCATION,
placesArrayJSONObject.optInt("position", suggestionModels.size() - 1)));
}
for (int i = 0; i < usersLen; i++) {
final JSONObject usersArrayJSONObject = usersArray.getJSONObject(i);

View File

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@ -239,7 +240,16 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener {
player.prepare(mediaSource);
player.setVolume(vol);
playerView.setOnClickListener(muteClickListener);
playerView.setOnClickListener(v -> {
if (player.getPlayWhenReady() == true) {
player.setPlayWhenReady(false);
player.getPlaybackState();
}
else {
player.setPlayWhenReady(true);
player.getPlaybackState();
}
});
}
}

View File

@ -33,13 +33,14 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
View.OnClickListener, View.OnLongClickListener {
private boolean cookieChanged, isQuery;
private Activity activity;
private String userQuery;
private String userQuery, displayName;
private View btnFavorite, btnImportExport;
private SimpleAdapter<DataBox.FavoriteModel> favoritesAdapter;
private RecyclerView rvFavorites, rvQuickAccess;
public QuickAccessDialog setQuery(final String userQuery) {
public QuickAccessDialog setQuery(final String userQuery, final String displayName) {
this.userQuery = userQuery;
this.displayName = displayName;
return this;
}
@ -102,7 +103,7 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
final Object tag = v.getTag();
if (v == btnFavorite) {
if (isQuery) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis()));
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(userQuery, System.currentTimeMillis(), displayName));
favoritesAdapter.setItems(Utils.dataBox.getAllFavorites());
}
} else if (v == btnImportExport) {

View File

@ -2,19 +2,23 @@ package awais.instagrabber.models;
import awais.instagrabber.models.enums.MediaItemType;
import org.json.JSONObject;
public final class FeedModel extends PostModel {
private final ProfileModel profileModel;
private final long commentsCount, viewCount;
private boolean captionExpanded = false, mentionClicked = false;
private final JSONObject location;
private ViewerPostModel[] sliderItems;
public FeedModel(final ProfileModel profileModel, final MediaItemType itemType, final long viewCount, final String postId,
final String displayUrl, final String thumbnailUrl, final String shortCode, final String postCaption,
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked, long likes) {
final long commentsCount, final long timestamp, boolean liked, boolean bookmarked, long likes, JSONObject location) {
super(itemType, postId, displayUrl, thumbnailUrl, shortCode, postCaption, timestamp, liked, bookmarked, likes);
this.profileModel = profileModel;
this.commentsCount = commentsCount;
this.viewCount = viewCount;
this.location = location;
}
public ProfileModel getProfileModel() {
@ -33,6 +37,10 @@ public final class FeedModel extends PostModel {
return commentsCount;
}
public JSONObject getLocation() {
return location;
}
public boolean isCaptionExpanded() {
return captionExpanded;
}

View File

@ -0,0 +1,44 @@
package awais.instagrabber.models;
import java.io.Serializable;
public final class LocationModel implements Serializable {
private final long postCount;
private final String id, name, bio, url, sdProfilePic, lat, lng;
public LocationModel(final String 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; // <- id + "/" + slug
this.name = name;
this.bio = bio;
this.url = url;
this.sdProfilePic = sdProfilePic;
this.postCount = postCount;
this.lat = lat;
this.lng = lng;
}
public String 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; }
}

View File

@ -1,9 +1,11 @@
package awais.instagrabber.models;
import org.json.JSONObject;
import awais.instagrabber.models.enums.MediaItemType;
public final class ViewerPostModel extends BasePostModel {
protected final String username, location;
protected final String username;
protected final JSONObject location;
protected final long videoViews;
protected String sliderDisplayUrl, commentsEndCursor;
protected long commentsCount, likes;
@ -11,7 +13,7 @@ public final class ViewerPostModel extends BasePostModel {
public ViewerPostModel(final MediaItemType itemType, final String postId, final String displayUrl, final String shortCode,
final String postCaption, final String username, final long videoViews, final long timestamp,
boolean liked, boolean bookmarked, long likes, final String location) {
boolean liked, boolean bookmarked, long likes, final JSONObject location) {
this.itemType = itemType;
this.postId = postId;
this.displayUrl = displayUrl;
@ -38,7 +40,7 @@ public final class ViewerPostModel extends BasePostModel {
return username;
}
public String getLocation() {
public JSONObject getLocation() {
return location;
}

View File

@ -3,4 +3,5 @@ package awais.instagrabber.models.enums;
public enum SuggestionType {
TYPE_USER,
TYPE_HASHTAG,
TYPE_LOCATION
}

View File

@ -10,6 +10,7 @@ public final class Constants {
public static final String APP_THEME = "app_theme";
public static final String APP_LANGUAGE = "app_language";
public static final String PREV_INSTALL_VERSION = "prevVersion";
public static final String DB_TO_MIGRATE = "dbToMigrate";
public static final String PROFILE_FETCH_MODE = "profile_fetch_mode";
// boolean prefs
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
@ -26,6 +27,7 @@ public final class Constants {
//////////////////////// EXTRAS ////////////////////////
public static final String EXTRAS_USER = "user";
public static final String EXTRAS_HASHTAG = "hashtag";
public static final String EXTRAS_LOCATION = "location";
public static final String EXTRAS_USERNAME = "username";
public static final String EXTRAS_ID = "id";
public static final String EXTRAS_POST = "post";

View File

@ -16,6 +16,7 @@ import awais.instagrabber.BuildConfig;
import awaisomereport.LogCollector;
import static awais.instagrabber.utils.Utils.logCollector;
import static awais.instagrabber.utils.Utils.settingsHelper;
public final class DataBox extends SQLiteOpenHelper {
private static DataBox sInstance;
@ -24,6 +25,7 @@ public final class DataBox extends SQLiteOpenHelper {
private final static String TABLE_FAVORITES = "favorites";
private final static String KEY_DATE_ADDED = "date_added";
private final static String KEY_QUERY_TEXT = "query_text";
private final static String KEY_QUERY_DISPLAY = "query_display";
private final static String KEY_USERNAME = Constants.EXTRAS_USERNAME;
private final static String KEY_COOKIE = "cookie";
private final static String KEY_UID = "uid";
@ -40,7 +42,7 @@ public final class DataBox extends SQLiteOpenHelper {
@Override
public void onCreate(@NonNull final SQLiteDatabase db) {
db.execSQL("CREATE TABLE cookies (id INTEGER PRIMARY KEY, uid TEXT, username TEXT, cookie TEXT)");
db.execSQL("CREATE TABLE favorites (id INTEGER PRIMARY KEY, query_text TEXT, date_added INTEGER)");
db.execSQL("CREATE TABLE favorites (id INTEGER PRIMARY KEY, query_text TEXT, date_added INTEGER, query_display TEXT)");
}
@Override
@ -49,6 +51,7 @@ public final class DataBox extends SQLiteOpenHelper {
///////////////////////////////////////// YOUR FAVORITES! HERE /////////////////////////////////////////
public final void addFavorite(@NonNull final FavoriteModel favoriteModel) {
final String query = favoriteModel.getQuery();
final String display = favoriteModel.getDisplayName();
if (!Utils.isEmpty(query)) {
try (final SQLiteDatabase db = getWritableDatabase()) {
db.beginTransaction();
@ -56,6 +59,7 @@ public final class DataBox extends SQLiteOpenHelper {
final ContentValues values = new ContentValues();
values.put(KEY_DATE_ADDED, favoriteModel.getDate());
values.put(KEY_QUERY_TEXT, query);
values.put(KEY_QUERY_DISPLAY, display);
final int rows = db.update(TABLE_FAVORITES, values, KEY_QUERY_TEXT + "=?", new String[]{query});
@ -76,12 +80,15 @@ public final class DataBox extends SQLiteOpenHelper {
public final synchronized void delFavorite(@NonNull final FavoriteModel favoriteModel) {
final String query = favoriteModel.getQuery();
final String display = favoriteModel.getDisplayName();
if (!Utils.isEmpty(query)) {
try (final SQLiteDatabase db = getWritableDatabase()) {
db.beginTransaction();
try {
final int rowsDeleted = db.delete(TABLE_FAVORITES, KEY_QUERY_TEXT + "=? AND " + KEY_DATE_ADDED + "=?",
new String[]{query, Long.toString(favoriteModel.getDate())});
final int rowsDeleted = db.delete(TABLE_FAVORITES, KEY_QUERY_TEXT + "=? AND "
+ KEY_DATE_ADDED + "=? AND "
+ KEY_QUERY_DISPLAY + "=?",
new String[]{query, Long.toString(favoriteModel.getDate()), display});
if (rowsDeleted > 0) db.setTransactionSuccessful();
} catch (final Exception e) {
@ -98,16 +105,50 @@ public final class DataBox extends SQLiteOpenHelper {
@Nullable
public final ArrayList<FavoriteModel> getAllFavorites() {
ArrayList<FavoriteModel> favorites = null;
FavoriteModel tempFav;
try (final SQLiteDatabase db = getReadableDatabase();
final Cursor cursor = db.rawQuery("SELECT query_text, date_added FROM favorites ORDER BY date_added DESC", null)) {
if (Utils.settingsHelper.getBoolean(Constants.DB_TO_MIGRATE)) {
try (final SQLiteDatabase db = getWritableDatabase()) {
db.execSQL("ALTER TABLE favorites ADD query_display TEXT");
try {
db.beginTransaction();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "delFavorite");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
} finally {
db.endTransaction();
settingsHelper.putBoolean(Constants.DB_TO_MIGRATE, false);
}
}
}
try (final SQLiteDatabase db = getWritableDatabase();
final Cursor cursor = db.rawQuery("SELECT query_text, date_added, query_display FROM favorites ORDER BY date_added DESC", null)) {
if (cursor != null && cursor.moveToFirst()) {
favorites = new ArrayList<>();
do {
favorites.add(new FavoriteModel(
tempFav = new FavoriteModel(
cursor.getString(0), // query text
cursor.getLong(1) // date added
));
cursor.getLong(1), // date added
cursor.getString(2) == null ? cursor.getString(0) : cursor.getString(2) // display
);
if (cursor.getString(2) == null) {
try {
db.beginTransaction();
final int rowsDeleted = db.delete(TABLE_FAVORITES, KEY_QUERY_TEXT + "=? AND " + KEY_DATE_ADDED + "=? AND " + KEY_QUERY_DISPLAY + " IS NULL",
new String[]{cursor.getString(0), Long.toString(cursor.getLong(1))});
if (rowsDeleted > 0) db.setTransactionSuccessful();
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "delFavorite");
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
} finally {
db.endTransaction();
}
addFavorite(tempFav);
}
favorites.add(tempFav);
} while (cursor.moveToNext());
}
}
@ -120,7 +161,7 @@ public final class DataBox extends SQLiteOpenHelper {
try (final SQLiteDatabase db = getReadableDatabase();
final Cursor cursor = db.rawQuery("SELECT query_text, date_added FROM favorites WHERE "
+KEY_QUERY_TEXT+"='"+query+"' ORDER BY date_added DESC", null)) {
+KEY_QUERY_DISPLAY+"='"+query+"' ORDER BY date_added DESC", null)) {
if (cursor != null && cursor.moveToFirst()) {
return cursor.getString(0) + "/" + String.valueOf(cursor.getLong(1));
}
@ -260,18 +301,23 @@ public final class DataBox extends SQLiteOpenHelper {
}
public static class FavoriteModel {
private final String query;
private final String query, displayName;
private final long date;
public FavoriteModel(final String query, final long date) {
public FavoriteModel(final String query, final long date, final String displayName) {
this.query = query;
this.date = date;
this.displayName = displayName;
}
public String getQuery() {
return query;
}
public String getDisplayName() {
return displayName;
}
public long getDate() {
return date;
}

View File

@ -167,7 +167,7 @@ public final class ExportImportUtils {
for (int i = 0; i < favsLen; ++i) {
final JSONObject favsObject = favs.getJSONObject(i);
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(favsObject.getString("q"),
favsObject.getLong("d")));
favsObject.getLong("d"), favsObject.has("s") ? favsObject.getString("s") : favsObject.getString("q")));
}
}
@ -265,6 +265,7 @@ public final class ExportImportUtils {
final JSONObject jsonObject = new JSONObject();
jsonObject.put("q", favorite.getQuery());
jsonObject.put("d", favorite.getDate());
jsonObject.put("s", favorite.getDisplayName());
jsonArray.put(jsonObject);
}
result = jsonArray.toString();

View File

@ -55,6 +55,8 @@ public final class FlavorTown {
public static void changelogCheck(@NonNull final Context context) {
if (settingsHelper.getInteger(Constants.PREV_INSTALL_VERSION) < BuildConfig.VERSION_CODE) {
if (settingsHelper.getInteger(Constants.PREV_INSTALL_VERSION) < 35)
settingsHelper.putBoolean(Constants.DB_TO_MIGRATE, true);
Toast.makeText(context, R.string.updated, Toast.LENGTH_SHORT).show();
settingsHelper.putInteger(Constants.PREV_INSTALL_VERSION, BuildConfig.VERSION_CODE);
}

View File

@ -107,6 +107,7 @@ public final class LogCollector {
ASYNC_POST_FETCHER("async-single-post-fetcher.txt"),
ASYNC_FEED_FETCHER("async-feed-fetcher.txt"),
ASYNC_HASHTAG_FETCHER("async-hashtag-fetcher.txt"),
ASYNC_LOCATION_FETCHER("async-location-fetcher.txt"),
ASYNC_PROFILE_FETCHER("async-profile-fetcher.txt"),
ASYNC_PROFILE_PICTURE_FETCHER("async-pfp-fetcher.txt"),
ASYNC_STORY_STATUS_FETCHER("async-story-status-fetcher.txt"),

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -31,6 +31,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- for users -->
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -227,38 +228,87 @@
</LinearLayout>
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<!-- for hashtags -->
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/tagToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:visibility="gone">
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:id="@+id/tagInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/profile_info_container_bottom_space"
android:visibility="gone">
<awais.instagrabber.customviews.CircularImageView
android:id="@+id/mainHashtagImage"
android:layout_width="@dimen/profile_picture_size"
android:layout_height="@dimen/profile_picture_size"
android:adjustViewBounds="true"
android:background="?selectableItemBackgroundBorderless" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mainTagPostCount"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:layout_weight="1"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="15sp"
tools:text="35\nPosts" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnFollowTag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/follow"
android:textColor="@color/btn_pink_text_color"
android:textSize="20sp"
app:backgroundTint="@color/btn_pink_background" />
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<!-- for locations -->
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:id="@+id/tagInfoContainer"
android:id="@+id/locInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@null"
android:orientation="vertical"
android:paddingBottom="5dp">
android:paddingBottom="5dp"
android:visibility="gone">
<LinearLayout
android:id="@+id/hashtagInfo"
android:id="@+id/locInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/profile_info_container_bottom_space">
<awais.instagrabber.customviews.CircularImageView
android:id="@+id/mainHashtagImage"
android:id="@+id/mainLocationImage"
android:layout_width="@dimen/profile_picture_size"
android:layout_height="@dimen/profile_picture_size"
android:adjustViewBounds="true"
android:background="?selectableItemBackgroundBorderless" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mainTagPostCount"
android:id="@+id/mainLocPostCount"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
@ -272,16 +322,62 @@
tools:text="35\nPosts" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnFollowTag"
android:id="@+id/btnMap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/follow"
android:textColor="@color/btn_pink_text_color"
android:text="@string/map"
android:textColor="@color/btn_green_text_color"
android:textSize="20sp"
app:backgroundTint="@color/btn_pink_background" />
app:backgroundTint="@color/btn_green_background" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/locationFullName"
android:layout_below="@id/locInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="10dp"
android:paddingLeft="10dp"
android:paddingEnd="10dp"
android:paddingRight="10dp"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textSize="16sp"
tools:text="OUR HOUSE" />
<awais.instagrabber.customviews.RamboTextView
android:id="@+id/locationBiography"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/locationFullName"
android:background="?android:selectableItemBackground"
android:paddingStart="10dp"
android:paddingLeft="10dp"
android:paddingEnd="10dp"
android:paddingRight="10dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="16sp"
android:visibility="gone"
tools:text="IN THE MIDDLE OF OUR STREET" />
<awais.instagrabber.customviews.RamboTextView
android:id="@+id/locationUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/locationBiography"
android:ellipsize="marquee"
android:paddingStart="10dp"
android:paddingLeft="10dp"
android:paddingEnd="10dp"
android:paddingRight="10dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="16sp"
tools:text="https://austinhuang.me/"
android:visibility="gone" />
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

View File

@ -86,6 +86,7 @@
<string name="unblock">Unblock</string>
<string name="restrict">Restrict</string>
<string name="unrestrict">Unrestrict</string>
<string name="map">Map</string>
<string name="dialog_export_btn_export">Export</string>
<string name="dialog_export_btn_import">Import</string>
<string name="dialog_export_logins">Export Logins</string>
@ -158,6 +159,7 @@
<string name="comment_send_empty_comment">No empty comments, dawg!</string>
<string name="comment_view_mention_user_search">Do you want to search the username?</string>
<string name="comment_view_mention_hash_search">Do you want to search the hashtag?</string>
<string name="comment_view_mention_location_search">Do you want to search the location?</string>
<string name="followers_type_followers">Followers</string>
<string name="followers_type_following">Following</string>
<string name="followers_compare">Comparing followers &amp; following</string>

View File

@ -1,7 +1,7 @@
* You can now write comments, and reply/like/delete comments through the menu (by clicking the comment)
* Liked comments are shown with a pink background
* You can now share posts in the post viewer
* You can now see the geotag name of a post
* Geotag viewing/searching support
* Search field is now empty if you're viewing your own profile while logged in
* Post like counts are now displayed (The button texts are slightly reduced to accomodate @world_record_egg) (logged in only)
* Mute buttons are changed to display the current status (i.e. muted icon when muted, sound icon when not muted)