mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 06:37:30 +00:00
story stickers and various bug fixes
This commit is contained in:
parent
90daf3069c
commit
eac0d9a5f7
@ -12,8 +12,8 @@ android {
|
|||||||
// REMEMBER TO CHANGE versionCode AS WELL
|
// REMEMBER TO CHANGE versionCode AS WELL
|
||||||
// 16.7 is 32, 16.9 is 35 (34 is public beta)
|
// 16.7 is 32, 16.9 is 35 (34 is public beta)
|
||||||
|
|
||||||
versionCode 36
|
versionCode 37
|
||||||
versionName '17.0'
|
versionName '17.1'
|
||||||
|
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import androidx.multidex.MultiDexApplication;
|
|||||||
|
|
||||||
import java.net.CookieHandler;
|
import java.net.CookieHandler;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.DataBox;
|
import awais.instagrabber.utils.DataBox;
|
||||||
@ -61,6 +62,8 @@ public final class InstaApp extends MultiDexApplication {
|
|||||||
settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT) :
|
settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT) :
|
||||||
settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
|
settingsHelper.getString(Constants.DATE_TIME_FORMAT), LocaleUtils.getCurrentLocale());
|
||||||
|
|
||||||
|
settingsHelper.putString(Constants.DEVICE_UUID, UUID.randomUUID().toString());
|
||||||
|
|
||||||
changeTheme();
|
changeTheme();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -60,7 +60,7 @@ import awais.instagrabber.asyncs.HighlightsFetcher;
|
|||||||
import awais.instagrabber.asyncs.LocationFetcher;
|
import awais.instagrabber.asyncs.LocationFetcher;
|
||||||
import awais.instagrabber.asyncs.PostsFetcher;
|
import awais.instagrabber.asyncs.PostsFetcher;
|
||||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
import awais.instagrabber.asyncs.ProfileFetcher;
|
||||||
import awais.instagrabber.asyncs.StoryStatusFetcher;
|
import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
|
||||||
import awais.instagrabber.customviews.MouseDrawer;
|
import awais.instagrabber.customviews.MouseDrawer;
|
||||||
import awais.instagrabber.customviews.RamboTextView;
|
import awais.instagrabber.customviews.RamboTextView;
|
||||||
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
|
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
|
||||||
@ -543,7 +543,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
else main.startActivity(new Intent(main, PostViewer.class)
|
else main.startActivity(new Intent(main, PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_INDEX, itemModel.getPosition())
|
.putExtra(Constants.EXTRAS_INDEX, itemModel.getPosition())
|
||||||
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.DISCOVER_ITEMS)
|
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.DISCOVER_ITEMS)
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(itemModel.getShortCode())));
|
.putExtra(Constants.EXTRAS_POST, new PostModel(itemModel.getShortCode(), false)));
|
||||||
}
|
}
|
||||||
}, v -> {
|
}, v -> {
|
||||||
final Object tag = v.getTag();
|
final Object tag = v.getTag();
|
||||||
@ -599,7 +599,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
if (modelType == IntentModelType.POST) {
|
if (modelType == IntentModelType.POST) {
|
||||||
main.startActivityForResult(new Intent(main, PostViewer.class)
|
main.startActivityForResult(new Intent(main, PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_USER, main.userQuery)
|
.putExtra(Constants.EXTRAS_USER, main.userQuery)
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(modelText)), 9629);
|
.putExtra(Constants.EXTRAS_POST, new PostModel(modelText, false)), 9629);
|
||||||
} else {
|
} else {
|
||||||
main.addToStack();
|
main.addToStack();
|
||||||
main.userQuery = modelType == IntentModelType.HASHTAG ? '#' + modelText : ("@"+modelText);
|
main.userQuery = modelType == IntentModelType.HASHTAG ? '#' + modelText : ("@"+modelText);
|
||||||
@ -700,8 +700,6 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String profileId = hashtagModel.getId();
|
|
||||||
|
|
||||||
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
||||||
|
|
||||||
@ -711,7 +709,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
main.mainBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
main.mainBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
new StoryStatusFetcher(profileId, hashtagModel.getName(), false, result -> {
|
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, result -> {
|
||||||
main.storyModels = result;
|
main.storyModels = result;
|
||||||
if (result != null && result.length > 0) main.mainBinding.mainHashtagImage.setStoriesBorder();
|
if (result != null && result.length > 0) main.mainBinding.mainHashtagImage.setStoriesBorder();
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
@ -774,7 +772,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
new StoryStatusFetcher(profileId, "", false, result -> {
|
new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false, result -> {
|
||||||
main.storyModels = result;
|
main.storyModels = result;
|
||||||
if (result != null && result.length > 0) main.mainBinding.mainProfileImage.setStoriesBorder();
|
if (result != null && result.length > 0) main.mainBinding.mainProfileImage.setStoriesBorder();
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
@ -971,7 +969,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
|
main.mainBinding.toolbar.toolbar.setTitle(main.userQuery);
|
||||||
main.mainBinding.locInfoContainer.setVisibility(View.VISIBLE);
|
main.mainBinding.locInfoContainer.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
currentlyExecuting = new LocationFetcher(main.userQuery, locationModel -> {
|
currentlyExecuting = new LocationFetcher(main.userQuery.split("/")[0], locationModel -> {
|
||||||
main.locationModel = locationModel;
|
main.locationModel = locationModel;
|
||||||
|
|
||||||
main.mainBinding.toolbar.toolbar.setTitle(locationModel.getName());
|
main.mainBinding.toolbar.toolbar.setTitle(locationModel.getName());
|
||||||
@ -988,7 +986,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
final boolean isLoggedIn = !Utils.isEmpty(cookie);
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
new StoryStatusFetcher(profileId, "", true, result -> {
|
new iStoryStatusFetcher(profileId.split("/")[0], null, true, false, result -> {
|
||||||
main.storyModels = result;
|
main.storyModels = result;
|
||||||
if (result != null && result.length > 0) main.mainBinding.mainLocationImage.setStoriesBorder();
|
if (result != null && result.length > 0) main.mainBinding.mainLocationImage.setStoriesBorder();
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
@ -1199,7 +1197,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||||||
private final View.OnClickListener profileActionListener = new View.OnClickListener() {
|
private final View.OnClickListener profileActionListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final View v) {
|
public void onClick(final View v) {
|
||||||
final boolean iamme = isLoggedIn
|
final boolean iamme = (isLoggedIn && main.profileModel != null)
|
||||||
? Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)).equals(main.profileModel.getId())
|
? Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE)).equals(main.profileModel.getId())
|
||||||
: false;
|
: false;
|
||||||
if (!isLoggedIn && Utils.dataBox.getFavorite(main.userQuery) != null && v == main.mainBinding.btnFollow) {
|
if (!isLoggedIn && Utils.dataBox.getFavorite(main.userQuery) != null && v == main.mainBinding.btnFollow) {
|
||||||
|
@ -50,6 +50,7 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
|
|||||||
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||||
private Resources resources;
|
private Resources resources;
|
||||||
private InputMethodManager imm;
|
private InputMethodManager imm;
|
||||||
|
private View focus;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
@ -122,7 +123,8 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
|
|||||||
} else if (which == 3) {
|
} else if (which == 3) {
|
||||||
Utils.copyText(this, commentModel.getText().toString());
|
Utils.copyText(this, commentModel.getText().toString());
|
||||||
} else if (which == 4) {
|
} else if (which == 4) {
|
||||||
commentsBinding.rvComments.findViewWithTag(commentModel).setBackgroundColor(0x80888888);
|
focus = commentsBinding.rvComments.findViewWithTag(commentModel);
|
||||||
|
focus.setBackgroundColor(0x80888888);
|
||||||
commentsBinding.commentCancelParent.setVisibility(View.VISIBLE);
|
commentsBinding.commentCancelParent.setVisibility(View.VISIBLE);
|
||||||
String mention = "@"+profileModel.getUsername()+" ";
|
String mention = "@"+profileModel.getUsername()+" ";
|
||||||
commentsBinding.commentText.setText(mention);
|
commentsBinding.commentText.setText(mention);
|
||||||
@ -200,10 +202,11 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
|
|||||||
Toast.makeText(getApplicationContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
|
||||||
else if (v == commentsBinding.commentSend) new CommentAction().execute("add");
|
else if (v == commentsBinding.commentSend) new CommentAction().execute("add");
|
||||||
else if (v == commentsBinding.commentCancelParent) {
|
else if (v == commentsBinding.commentCancelParent) {
|
||||||
commentsBinding.rvComments.findViewWithTag(commentModel).setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
|
focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
|
||||||
commentsBinding.commentCancelParent.setVisibility(View.GONE);
|
commentsBinding.commentCancelParent.setVisibility(View.GONE);
|
||||||
commentsBinding.commentText.setText("");
|
commentsBinding.commentText.setText("");
|
||||||
commentModel = null;
|
commentModel = null;
|
||||||
|
focus = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -287,9 +290,11 @@ public final class CommentsViewer extends BaseLanguageActivity implements SwipeR
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void result) {
|
protected void onPostExecute(Void result) {
|
||||||
if (ok == true) {
|
if (ok == true) {
|
||||||
if (commentModel != null) {
|
if (focus != null) {
|
||||||
commentsBinding.rvComments.findViewWithTag(commentModel).setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
|
focus.setBackgroundColor(commentModel.getLiked() ? 0x40FF69B4 : 0x00000000);
|
||||||
commentsBinding.commentCancelParent.setVisibility(View.GONE);
|
commentsBinding.commentCancelParent.setVisibility(View.GONE);
|
||||||
|
commentModel = null;
|
||||||
|
focus = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//imm.hideSoftInputFromWindow(commentsBinding.getView().getRootView().getWindowToken(), 0);
|
//imm.hideSoftInputFromWindow(commentsBinding.getView().getRootView().getWindowToken(), 0);
|
||||||
|
@ -110,7 +110,7 @@ public final class DirectMessagesUserInbox extends AppCompatActivity {
|
|||||||
switch (itemType) {
|
switch (itemType) {
|
||||||
case MEDIA_SHARE:
|
case MEDIA_SHARE:
|
||||||
startActivity(new Intent(this, PostViewer.class)
|
startActivity(new Intent(this, PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(directItemModel.getMediaModel().getCode())));
|
.putExtra(Constants.EXTRAS_POST, new PostModel(directItemModel.getMediaModel().getCode(), false)));
|
||||||
break;
|
break;
|
||||||
case LINK:
|
case LINK:
|
||||||
Intent linkIntent = new Intent(Intent.ACTION_VIEW);
|
Intent linkIntent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
@ -92,7 +92,7 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S
|
|||||||
searchUsername(notificationModel.getUsername());
|
searchUsername(notificationModel.getUsername());
|
||||||
else if (which == 1)
|
else if (which == 1)
|
||||||
startActivity(new Intent(getApplicationContext(), PostViewer.class)
|
startActivity(new Intent(getApplicationContext(), PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode())));
|
.putExtra(Constants.EXTRAS_POST, new PostModel(notificationModel.getShortcode(), false)));
|
||||||
};
|
};
|
||||||
|
|
||||||
private final View.OnClickListener clickListener = v -> {
|
private final View.OnClickListener clickListener = v -> {
|
||||||
|
@ -57,9 +57,11 @@ import awais.instagrabber.R;
|
|||||||
import awais.instagrabber.adapters.PostsMediaAdapter;
|
import awais.instagrabber.adapters.PostsMediaAdapter;
|
||||||
import awais.instagrabber.asyncs.PostFetcher;
|
import awais.instagrabber.asyncs.PostFetcher;
|
||||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
import awais.instagrabber.asyncs.ProfileFetcher;
|
||||||
|
import awais.instagrabber.asyncs.i.iPostFetcher;
|
||||||
import awais.instagrabber.customviews.CommentMentionClickSpan;
|
import awais.instagrabber.customviews.CommentMentionClickSpan;
|
||||||
import awais.instagrabber.customviews.helpers.SwipeGestureListener;
|
import awais.instagrabber.customviews.helpers.SwipeGestureListener;
|
||||||
import awais.instagrabber.databinding.ActivityViewerBinding;
|
import awais.instagrabber.databinding.ActivityViewerBinding;
|
||||||
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.interfaces.SwipeEvent;
|
import awais.instagrabber.interfaces.SwipeEvent;
|
||||||
import awais.instagrabber.models.BasePostModel;
|
import awais.instagrabber.models.BasePostModel;
|
||||||
import awais.instagrabber.models.PostModel;
|
import awais.instagrabber.models.PostModel;
|
||||||
@ -185,6 +187,83 @@ public final class PostViewer extends BaseLanguageActivity {
|
|||||||
private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
|
private final PostsMediaAdapter mediaAdapter = new PostsMediaAdapter(null, onClickListener);
|
||||||
private RequestManager glideRequestManager;
|
private RequestManager glideRequestManager;
|
||||||
private LinearLayout.LayoutParams containerLayoutParams;
|
private LinearLayout.LayoutParams containerLayoutParams;
|
||||||
|
private final FetchListener<ViewerPostModel[]> pfl = result -> {
|
||||||
|
if (result == null || result.length < 1) {
|
||||||
|
Toast.makeText(this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewerPostModel = result[0];
|
||||||
|
|
||||||
|
mediaAdapter.setData(result);
|
||||||
|
if (result.length > 1) {
|
||||||
|
viewerBinding.mediaList.setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.55f
|
||||||
|
));
|
||||||
|
containerLayoutParams.weight = 1.35f;
|
||||||
|
containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
|
||||||
|
viewerBinding.container.setLayoutParams(containerLayoutParams);
|
||||||
|
viewerBinding.mediaList.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final View viewStoryPost = findViewById(R.id.viewStoryPost);
|
||||||
|
if (viewStoryPost != null) {
|
||||||
|
viewStoryPost.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (profileModel.isPrivate())
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.share_private_post, Toast.LENGTH_LONG).show();
|
||||||
|
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||||
|
sharingIntent.setType("text/plain");
|
||||||
|
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "https://instagram.com/p/"+postModel.getShortCode());
|
||||||
|
startActivity(Intent.createChooser(sharingIntent,
|
||||||
|
(profileModel.isPrivate()) ? getString(R.string.share_private_post) : getString(R.string.share_public_post)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
viewerCaptionParent.setOnTouchListener(gestureTouchListener);
|
||||||
|
viewerBinding.playerView.setOnTouchListener(gestureTouchListener);
|
||||||
|
viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
|
||||||
|
final float diffX = e2.getX() - e1.getX();
|
||||||
|
if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
|
||||||
|
&& Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
|
||||||
|
swipeEvent.onSwipe(diffX > 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
final long commentsCount = viewerPostModel.getCommentsCount();
|
||||||
|
viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
|
||||||
|
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
|
||||||
|
startActivityForResult(new Intent(this, CommentsViewer.class)
|
||||||
|
.putExtra(Constants.EXTRAS_SHORTCODE, postShortCode)
|
||||||
|
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
|
||||||
|
.putExtra(Constants.EXTRAS_USER, postUserId), 6969));
|
||||||
|
viewerBinding.bottomPanel.btnComments.setClickable(true);
|
||||||
|
viewerBinding.bottomPanel.btnComments.setEnabled(true);
|
||||||
|
|
||||||
|
if (postModel instanceof PostModel) {
|
||||||
|
final PostModel postModel = (PostModel) this.postModel;
|
||||||
|
postModel.setPostId(viewerPostModel.getPostId());
|
||||||
|
postModel.setTimestamp(viewerPostModel.getTimestamp());
|
||||||
|
postModel.setPostCaption(viewerPostModel.getPostCaption());
|
||||||
|
postModel.setLike(viewerPostModel.getLike());
|
||||||
|
postModel.setBookmark(viewerPostModel.getBookmark());
|
||||||
|
}
|
||||||
|
|
||||||
|
setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
|
||||||
|
viewerPostModel.getLocation() == null ? null : viewerPostModel.getLocation());
|
||||||
|
|
||||||
|
postCaption = postModel.getPostCaption();
|
||||||
|
viewerCaptionParent.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
viewerBinding.bottomPanel.btnDownload.setOnClickListener(downloadClickListener);
|
||||||
|
|
||||||
|
refreshPost();
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
@ -341,85 +420,10 @@ public final class PostViewer extends BaseLanguageActivity {
|
|||||||
viewerBinding.imageViewer.setImageResource(0);
|
viewerBinding.imageViewer.setImageResource(0);
|
||||||
viewerBinding.imageViewer.setImageDrawable(null);
|
viewerBinding.imageViewer.setImageDrawable(null);
|
||||||
|
|
||||||
new PostFetcher(postModel.getShortCode(), result -> {
|
if (postModel.getShortCode() != null)
|
||||||
if (result == null || result.length < 1) {
|
new PostFetcher(postModel.getShortCode(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
Toast.makeText(this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
else if (postModel.getPostId() != null)
|
||||||
return;
|
new iPostFetcher(postModel.getPostId(), pfl).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
|
||||||
|
|
||||||
viewerPostModel = result[0];
|
|
||||||
commentsEndCursor = viewerPostModel.getCommentsEndCursor();
|
|
||||||
|
|
||||||
mediaAdapter.setData(result);
|
|
||||||
if (result.length > 1) {
|
|
||||||
viewerBinding.mediaList.setLayoutParams(new LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.55f
|
|
||||||
));
|
|
||||||
containerLayoutParams.weight = 1.35f;
|
|
||||||
containerLayoutParams.weight += (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) ? 0.3f : 0;
|
|
||||||
viewerBinding.container.setLayoutParams(containerLayoutParams);
|
|
||||||
viewerBinding.mediaList.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
final View viewStoryPost = findViewById(R.id.viewStoryPost);
|
|
||||||
if (viewStoryPost != null) {
|
|
||||||
viewStoryPost.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (profileModel.isPrivate())
|
|
||||||
Toast.makeText(getApplicationContext(), R.string.share_private_post, Toast.LENGTH_LONG).show();
|
|
||||||
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
|
||||||
sharingIntent.setType("text/plain");
|
|
||||||
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "https://instagram.com/p/"+postModel.getShortCode());
|
|
||||||
startActivity(Intent.createChooser(sharingIntent,
|
|
||||||
(profileModel.isPrivate()) ? getString(R.string.share_private_post) : getString(R.string.share_public_post)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
viewerCaptionParent.setOnTouchListener(gestureTouchListener);
|
|
||||||
viewerBinding.playerView.setOnTouchListener(gestureTouchListener);
|
|
||||||
viewerBinding.imageViewer.setOnSingleFlingListener((e1, e2, velocityX, velocityY) -> {
|
|
||||||
final float diffX = e2.getX() - e1.getX();
|
|
||||||
if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY()) && Math.abs(diffX) > SwipeGestureListener.SWIPE_THRESHOLD
|
|
||||||
&& Math.abs(velocityX) > SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD) {
|
|
||||||
swipeEvent.onSwipe(diffX > 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
final long commentsCount = viewerPostModel.getCommentsCount();
|
|
||||||
viewerBinding.bottomPanel.commentsCount.setText(String.valueOf(commentsCount));
|
|
||||||
viewerBinding.bottomPanel.btnComments.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
viewerBinding.bottomPanel.btnComments.setOnClickListener(v ->
|
|
||||||
startActivityForResult(new Intent(this, CommentsViewer.class)
|
|
||||||
.putExtra(Constants.EXTRAS_END_CURSOR, commentsEndCursor)
|
|
||||||
.putExtra(Constants.EXTRAS_SHORTCODE, postShortCode)
|
|
||||||
.putExtra(Constants.EXTRAS_POST, viewerPostModel.getPostId())
|
|
||||||
.putExtra(Constants.EXTRAS_USER, postUserId), 6969));
|
|
||||||
viewerBinding.bottomPanel.btnComments.setClickable(true);
|
|
||||||
viewerBinding.bottomPanel.btnComments.setEnabled(true);
|
|
||||||
|
|
||||||
if (postModel instanceof PostModel) {
|
|
||||||
final PostModel postModel = (PostModel) this.postModel;
|
|
||||||
postModel.setPostId(viewerPostModel.getPostId());
|
|
||||||
postModel.setTimestamp(viewerPostModel.getTimestamp());
|
|
||||||
postModel.setPostCaption(viewerPostModel.getPostCaption());
|
|
||||||
postModel.setLike(viewerPostModel.getLike());
|
|
||||||
postModel.setBookmark(viewerPostModel.getBookmark());
|
|
||||||
}
|
|
||||||
|
|
||||||
setupPostInfoBar("@"+viewerPostModel.getUsername(), viewerPostModel.getItemType(),
|
|
||||||
viewerPostModel.getLocation() == null ? null : viewerPostModel.getLocation());
|
|
||||||
|
|
||||||
postCaption = postModel.getPostCaption();
|
|
||||||
viewerCaptionParent.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
viewerBinding.bottomPanel.btnDownload.setOnClickListener(downloadClickListener);
|
|
||||||
|
|
||||||
refreshPost();
|
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchUsername(final String text) {
|
private void searchUsername(final String text) {
|
||||||
@ -673,7 +677,7 @@ public final class PostViewer extends BaseLanguageActivity {
|
|||||||
viewerBinding.topPanel.ivProfilePic.setImageDrawable(null);
|
viewerBinding.topPanel.ivProfilePic.setImageDrawable(null);
|
||||||
viewerBinding.topPanel.ivProfilePic.setImageResource(0);
|
viewerBinding.topPanel.ivProfilePic.setImageResource(0);
|
||||||
|
|
||||||
if (from.charAt(0) == '@')
|
if (!Utils.isEmpty(from) && from.charAt(0) == '@')
|
||||||
new ProfileFetcher(from.substring(1), result -> {
|
new ProfileFetcher(from.substring(1), result -> {
|
||||||
profileModel = result;
|
profileModel = result;
|
||||||
|
|
||||||
|
@ -10,12 +10,15 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.text.InputType;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -43,6 +46,10 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
import awais.instagrabber.BuildConfig;
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
@ -52,7 +59,8 @@ import awais.instagrabber.customviews.helpers.SwipeGestureListener;
|
|||||||
import awais.instagrabber.databinding.ActivityStoryViewerBinding;
|
import awais.instagrabber.databinding.ActivityStoryViewerBinding;
|
||||||
import awais.instagrabber.interfaces.SwipeEvent;
|
import awais.instagrabber.interfaces.SwipeEvent;
|
||||||
import awais.instagrabber.models.FeedStoryModel;
|
import awais.instagrabber.models.FeedStoryModel;
|
||||||
import awais.instagrabber.models.PollModel;
|
import awais.instagrabber.models.stickers.PollModel;
|
||||||
|
import awais.instagrabber.models.stickers.QuestionModel;
|
||||||
import awais.instagrabber.models.PostModel;
|
import awais.instagrabber.models.PostModel;
|
||||||
import awais.instagrabber.models.StoryModel;
|
import awais.instagrabber.models.StoryModel;
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
@ -86,6 +94,8 @@ public final class StoryViewer extends BaseLanguageActivity {
|
|||||||
private SwipeEvent swipeEvent;
|
private SwipeEvent swipeEvent;
|
||||||
private MenuItem menuDownload;
|
private MenuItem menuDownload;
|
||||||
private PollModel poll;
|
private PollModel poll;
|
||||||
|
private QuestionModel question;
|
||||||
|
private String[] mentions;
|
||||||
private StoryModel currentStory;
|
private StoryModel currentStory;
|
||||||
private String url, username;
|
private String url, username;
|
||||||
private int slidePos = 0, lastSlidePos = 0;
|
private int slidePos = 0, lastSlidePos = 0;
|
||||||
@ -206,10 +216,10 @@ public final class StoryViewer extends BaseLanguageActivity {
|
|||||||
storyViewerBinding.viewStoryPost.setOnClickListener(v -> {
|
storyViewerBinding.viewStoryPost.setOnClickListener(v -> {
|
||||||
final Object tag = v.getTag();
|
final Object tag = v.getTag();
|
||||||
if (tag instanceof CharSequence) startActivity(new Intent(this, PostViewer.class)
|
if (tag instanceof CharSequence) startActivity(new Intent(this, PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString())));
|
.putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString(), tag.toString().matches("^[\\d]+$"))));
|
||||||
});
|
});
|
||||||
|
|
||||||
storyViewerBinding.interactStory.setOnClickListener(v -> {
|
final View.OnClickListener storyActionListener = v -> {
|
||||||
final Object tag = v.getTag();
|
final Object tag = v.getTag();
|
||||||
if (tag instanceof PollModel) {
|
if (tag instanceof PollModel) {
|
||||||
poll = (PollModel) tag;
|
poll = (PollModel) tag;
|
||||||
@ -231,7 +241,32 @@ public final class StoryViewer extends BaseLanguageActivity {
|
|||||||
.setPositiveButton(R.string.cancel, null)
|
.setPositiveButton(R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
});
|
else if (tag instanceof QuestionModel) {
|
||||||
|
question = (QuestionModel) tag;
|
||||||
|
final EditText input = new EditText(this);
|
||||||
|
input.setHint(R.string.answer_hint);
|
||||||
|
new AlertDialog.Builder(this).setTitle(question.getQuestion())
|
||||||
|
.setView(input)
|
||||||
|
.setPositiveButton(R.string.ok, (d,w) -> {
|
||||||
|
new RespondAction().execute(input.getText().toString());
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
else if (tag instanceof String[]) {
|
||||||
|
mentions = (String[]) tag;
|
||||||
|
new AlertDialog.Builder(this).setTitle(R.string.story_mentions)
|
||||||
|
.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mentions), (d,w) -> {
|
||||||
|
searchUsername(mentions[w]);
|
||||||
|
})
|
||||||
|
.setPositiveButton(R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
storyViewerBinding.poll.setOnClickListener(storyActionListener);
|
||||||
|
storyViewerBinding.answer.setOnClickListener(storyActionListener);
|
||||||
|
storyViewerBinding.mention.setOnClickListener(storyActionListener);
|
||||||
|
|
||||||
storiesAdapter.setData(storyModels);
|
storiesAdapter.setData(storyModels);
|
||||||
if (storyModels.length > 1) storyViewerBinding.storiesList.setVisibility(View.VISIBLE);
|
if (storyModels.length > 1) storyViewerBinding.storiesList.setVisibility(View.VISIBLE);
|
||||||
@ -410,10 +445,17 @@ public final class StoryViewer extends BaseLanguageActivity {
|
|||||||
storyViewerBinding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE);
|
storyViewerBinding.spotify.setVisibility(spotify != null ? View.VISIBLE : View.GONE);
|
||||||
storyViewerBinding.spotify.setTag(spotify);
|
storyViewerBinding.spotify.setTag(spotify);
|
||||||
|
|
||||||
final PollModel poll = currentStory.getPoll();
|
poll = currentStory.getPoll();
|
||||||
storyViewerBinding.interactStory.setVisibility(poll != null ? View.VISIBLE : View.GONE);
|
storyViewerBinding.poll.setVisibility(poll != null ? View.VISIBLE : View.GONE);
|
||||||
storyViewerBinding.interactStory.setText(R.string.vote_story_poll);
|
storyViewerBinding.poll.setTag(poll);
|
||||||
storyViewerBinding.interactStory.setTag(poll);
|
|
||||||
|
question = currentStory.getQuestion();
|
||||||
|
storyViewerBinding.answer.setVisibility(question != null ? View.VISIBLE : View.GONE);
|
||||||
|
storyViewerBinding.answer.setTag(question);
|
||||||
|
|
||||||
|
mentions = currentStory.getMentions();
|
||||||
|
storyViewerBinding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE);
|
||||||
|
storyViewerBinding.mention.setTag(mentions);
|
||||||
|
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
@ -497,4 +539,53 @@ public final class StoryViewer extends BaseLanguageActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RespondAction extends AsyncTask<String, Void, Void> {
|
||||||
|
boolean ok = false;
|
||||||
|
String action;
|
||||||
|
|
||||||
|
protected Void doInBackground(String... rawchoice) {
|
||||||
|
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
|
final String url = "https://i.instagram.com/api/v1/media/"
|
||||||
|
+currentStory.getStoryMediaId()+"/"+question.getId()+"/story_question_response/";
|
||||||
|
try {
|
||||||
|
JSONObject ogbody = new JSONObject("{\"client_context\":\"" + UUID.randomUUID().toString()
|
||||||
|
+"\",\"mutation_token\":\"" + UUID.randomUUID().toString()
|
||||||
|
+"\",\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
|
||||||
|
+"\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie)
|
||||||
|
+"\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID)
|
||||||
|
+"\"}");
|
||||||
|
String choice = rawchoice[0].replaceAll("\"", ("\\\""));
|
||||||
|
ogbody.put("response", choice);
|
||||||
|
String urlParameters = Utils.sign(ogbody.toString());
|
||||||
|
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
urlConnection.setRequestMethod("POST");
|
||||||
|
urlConnection.setUseCaches(false);
|
||||||
|
urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
|
||||||
|
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
urlConnection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
|
||||||
|
urlConnection.setDoOutput(true);
|
||||||
|
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
|
||||||
|
wr.writeBytes(urlParameters);
|
||||||
|
wr.flush();
|
||||||
|
wr.close();
|
||||||
|
urlConnection.connect();
|
||||||
|
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||||
|
urlConnection.disconnect();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Log.e("austin_debug", "vote: " + ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
if (ok) {
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.answered_story, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -93,7 +93,7 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
|
|||||||
case R.id.viewStoryPost:
|
case R.id.viewStoryPost:
|
||||||
activity.startActivity(new Intent(activity, PostViewer.class)
|
activity.startActivity(new Intent(activity, PostViewer.class)
|
||||||
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
|
.putExtra(Constants.EXTRAS_INDEX, feedModel.getPosition())
|
||||||
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode()))
|
.putExtra(Constants.EXTRAS_POST, new PostModel(feedModel.getShortCode(), false))
|
||||||
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
|
.putExtra(Constants.EXTRAS_TYPE, ItemGetType.FEED_ITEMS));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -210,15 +210,9 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
|
|||||||
final long commentsCount = feedModel.getCommentsCount();
|
final long commentsCount = feedModel.getCommentsCount();
|
||||||
viewHolder.commentsCount.setText(String.valueOf(commentsCount));
|
viewHolder.commentsCount.setText(String.valueOf(commentsCount));
|
||||||
|
|
||||||
if (commentsCount <= 0) {
|
|
||||||
viewHolder.btnComments.setTag(null);
|
|
||||||
viewHolder.btnComments.setOnClickListener(null);
|
|
||||||
viewHolder.btnComments.setEnabled(false);
|
|
||||||
} else {
|
|
||||||
viewHolder.btnComments.setTag(feedModel);
|
viewHolder.btnComments.setTag(feedModel);
|
||||||
viewHolder.btnComments.setOnClickListener(clickListener);
|
viewHolder.btnComments.setOnClickListener(clickListener);
|
||||||
viewHolder.btnComments.setEnabled(true);
|
viewHolder.btnComments.setEnabled(true);
|
||||||
}
|
|
||||||
|
|
||||||
final JSONObject location = feedModel.getLocation();
|
final JSONObject location = feedModel.getLocation();
|
||||||
|
|
||||||
@ -234,6 +228,12 @@ public final class FeedAdapter extends RecyclerView.Adapter<FeedItemViewHolder>
|
|||||||
viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
|
viewHolder.username.setLayoutParams(new RelativeLayout.LayoutParams(
|
||||||
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
|
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
));
|
));
|
||||||
|
viewHolder.location.setOnClickListener(v ->
|
||||||
|
new AlertDialog.Builder(v.getContext()).setTitle(location.optString("name"))
|
||||||
|
.setMessage(R.string.comment_view_mention_location_search)
|
||||||
|
.setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok,
|
||||||
|
(dialog, which) -> mentionClickListener.onClick(null, location.optString("id")+"/"+location.optString("slug"), false)).show()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String thumbnailUrl = feedModel.getThumbnailUrl();
|
final String thumbnailUrl = feedModel.getThumbnailUrl();
|
||||||
|
@ -68,14 +68,21 @@ public final class FeedStoriesFetcher extends AsyncTask<Void, Void, FeedStoryMod
|
|||||||
feedStoryModels[i] = new FeedStoryModel(id, profileModel);
|
feedStoryModels[i] = new FeedStoryModel(id, profileModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
url = "https://www.instagram.com/graphql/query/?query_hash=0a85e6ea60a4c99edc58ab2f3d17cfdf&variables=" +
|
for (int s = 0; s <= Math.ceil(feedStoryIDs.length / 20); ++s) {
|
||||||
"{\"reel_ids\":" + Utils.highlightIdsMerger(feedStoryIDs) + ",\"precomposed_overlay\":false}";
|
String[] shard = new String[Math.min(20, (feedStoryIDs.length - s*20))];
|
||||||
|
FeedStoryModel[] feedStoryShard = new FeedStoryModel[Math.min(20, (feedStoryIDs.length - s*20))];
|
||||||
|
System.arraycopy(feedStoryIDs, s*20, shard, 0, shard.length);
|
||||||
|
System.arraycopy(feedStoryModels, s*20, feedStoryShard, 0, shard.length);
|
||||||
|
url = "https://i.instagram.com/api/v1/feed/reels_media/?reel_ids=" + Utils.iHighlightIdsMerger(shard);
|
||||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
conn.setInstanceFollowRedirects(false);
|
conn.setInstanceFollowRedirects(false);
|
||||||
conn.setUseCaches(false);
|
conn.setUseCaches(false);
|
||||||
|
conn.setReadTimeout(2000);
|
||||||
conn.connect();
|
conn.connect();
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
Utils.putHighlightModels(conn, feedStoryModels);
|
Utils.iPutFeedStoryModels(conn, feedStoryShard, shard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = feedStoryModels;
|
result = feedStoryModels;
|
||||||
|
@ -26,7 +26,7 @@ public final class LocationFetcher extends AsyncTask<Void, Void, LocationModel>
|
|||||||
private final String idSlug;
|
private final String idSlug;
|
||||||
|
|
||||||
public LocationFetcher(String idSlug, FetchListener<LocationModel> fetchListener) {
|
public LocationFetcher(String idSlug, FetchListener<LocationModel> fetchListener) {
|
||||||
// idSlug = id + "/" + slug
|
// idSlug = id + "/" + slug UPDATE: slug can be ignored tbh
|
||||||
this.idSlug = idSlug;
|
this.idSlug = idSlug;
|
||||||
this.fetchListener = fetchListener;
|
this.fetchListener = fetchListener;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,6 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
|
|||||||
media.optJSONObject("location"));
|
media.optJSONObject("location"));
|
||||||
|
|
||||||
postModel.setCommentsCount(commentsCount);
|
postModel.setCommentsCount(commentsCount);
|
||||||
postModel.setCommentsEndCursor(endCursor);
|
|
||||||
|
|
||||||
Utils.checkExistence(downloadDir, customDir, false, postModel);
|
Utils.checkExistence(downloadDir, customDir, false, postModel);
|
||||||
|
|
||||||
@ -127,7 +126,6 @@ public final class PostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]>
|
|||||||
}
|
}
|
||||||
|
|
||||||
postModels[0].setCommentsCount(commentsCount);
|
postModels[0].setCommentsCount(commentsCount);
|
||||||
postModels[0].setCommentsEndCursor(endCursor);
|
|
||||||
|
|
||||||
result = postModels;
|
result = postModels;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, ProfileModel> {
|
|||||||
final JSONObject timelineMedia = user.getJSONObject("edge_owner_to_timeline_media");
|
final JSONObject timelineMedia = user.getJSONObject("edge_owner_to_timeline_media");
|
||||||
if (timelineMedia.has("edges")) {
|
if (timelineMedia.has("edges")) {
|
||||||
final JSONArray edges = timelineMedia.getJSONArray("edges");
|
final JSONArray edges = timelineMedia.getJSONArray("edges");
|
||||||
if (edges.length() > 0) reallyPrivate = false;
|
if (edges.length() > 0 || timelineMedia.getLong("count") == 0L) reallyPrivate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = user.optString("external_url");
|
String url = user.optString("external_url");
|
||||||
|
@ -5,6 +5,10 @@ import android.util.Log;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -33,11 +37,11 @@ public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String doInBackground(final Void... voids) {
|
protected String doInBackground(final Void... voids) {
|
||||||
String out = picUrl;
|
String out = null;
|
||||||
if (!isHashtag) try {
|
if (isHashtag) out = picUrl;
|
||||||
final String url = "https://i.instagram.com/api/v1/users/"+userId+"/info/";
|
else try {
|
||||||
|
final HttpURLConnection conn =
|
||||||
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
(HttpURLConnection) new URL("https://i.instagram.com/api/v1/users/"+userId+"/info/").openConnection();
|
||||||
conn.setUseCaches(false);
|
conn.setUseCaches(false);
|
||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
@ -50,13 +54,45 @@ public final class ProfilePictureFetcher extends AsyncTask<Void, Void, String> {
|
|||||||
if (data.has("hd_profile_pic_url_info"))
|
if (data.has("hd_profile_pic_url_info"))
|
||||||
out = data.getJSONObject("hd_profile_pic_url_info").optString("url");
|
out = data.getJSONObject("hd_profile_pic_url_info").optString("url");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Utils.isEmpty(out)) {
|
||||||
|
final HttpURLConnection backup =
|
||||||
|
(HttpURLConnection) new URL("https://instadp.com/fullsize/" + userName).openConnection();
|
||||||
|
backup.setUseCaches(false);
|
||||||
|
backup.setRequestMethod("GET");
|
||||||
|
|
||||||
|
final String instadp = backup.getResponseCode() == HttpURLConnection.HTTP_OK ? Utils.readFromConnection(backup) : null;
|
||||||
|
backup.disconnect();
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(instadp)) {
|
||||||
|
final Document doc = Jsoup.parse(instadp);
|
||||||
|
boolean fallback = false;
|
||||||
|
|
||||||
|
final int imgIndex = instadp.indexOf("preloadImg('"), lastIndex;
|
||||||
|
|
||||||
|
Element element = doc.selectFirst(".instadp");
|
||||||
|
if (element != null && (element = element.selectFirst(".picture")) != null)
|
||||||
|
out = element.attr("src");
|
||||||
|
else if ((element = doc.selectFirst(".download-btn")) != null)
|
||||||
|
out = element.attr("href");
|
||||||
|
else if (imgIndex != -1 && (lastIndex = instadp.indexOf("')", imgIndex)) != -1)
|
||||||
|
out = instadp.substring(imgIndex + 12, lastIndex);
|
||||||
|
else {
|
||||||
|
final Elements imgs = doc.getElementsByTag("img");
|
||||||
|
for (final Element img : imgs) {
|
||||||
|
final String imgStr = img.toString();
|
||||||
|
if (imgStr.contains("cdninstagram.com")) out = img.attr("src");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out == null) out = picUrl;
|
||||||
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
if (logCollector != null)
|
if (logCollector != null)
|
||||||
logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground");
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground");
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out == null) out = picUrl;
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
package awais.instagrabber.asyncs;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
|
||||||
import awais.instagrabber.models.PollModel;
|
|
||||||
import awais.instagrabber.models.StoryModel;
|
|
||||||
import awais.instagrabber.utils.Constants;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
import awaisomereport.LogCollector;
|
|
||||||
|
|
||||||
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 boolean location, final FetchListener<StoryModel[]> fetchListener) {
|
|
||||||
this.id = id;
|
|
||||||
this.hashtag = hashtag;
|
|
||||||
this.location = location;
|
|
||||||
this.fetchListener = fetchListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected StoryModel[] doInBackground(final Void... voids) {
|
|
||||||
StoryModel[] result = null;
|
|
||||||
final String url = "https://www.instagram.com/graphql/query/?query_hash=90709b530ea0969f002c86a89b4f2b8d&variables=" +
|
|
||||||
"{\"precomposed_overlay\":false,\"show_story_viewer_list\":false,\"stories_video_dash_manifest\":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();
|
|
||||||
conn.setInstanceFollowRedirects(false);
|
|
||||||
conn.setUseCaches(false);
|
|
||||||
conn.connect();
|
|
||||||
|
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
|
||||||
JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data");
|
|
||||||
|
|
||||||
JSONArray media;
|
|
||||||
if ((media = data.optJSONArray("reels_media")) != null && media.length() > 0 &&
|
|
||||||
(data = media.optJSONObject(0)) != null &&
|
|
||||||
(media = data.optJSONArray("items")) != null) {
|
|
||||||
|
|
||||||
final int mediaLen = media.length();
|
|
||||||
|
|
||||||
final StoryModel[] models = new StoryModel[mediaLen];
|
|
||||||
for (int i = 0; i < mediaLen; ++i) {
|
|
||||||
data = media.getJSONObject(i);
|
|
||||||
final boolean isVideo = data.getBoolean("is_video");
|
|
||||||
|
|
||||||
final JSONArray tappableObjects = data.optJSONArray("tappable_objects");
|
|
||||||
final int tappableLength = tappableObjects != null ? tappableObjects.length() : 0;
|
|
||||||
|
|
||||||
models[i] = new StoryModel(data.getString(Constants.EXTRAS_ID),
|
|
||||||
data.getString("display_url"),
|
|
||||||
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
|
||||||
data.optLong("taken_at_timestamp", 0),
|
|
||||||
data.getJSONObject("owner").getString("username"));
|
|
||||||
|
|
||||||
final JSONArray videoResources = data.optJSONArray("video_resources");
|
|
||||||
if (isVideo && videoResources != null)
|
|
||||||
models[i].setVideoUrl(Utils.getHighQualityPost(videoResources, true));
|
|
||||||
|
|
||||||
if (!data.isNull("story_app_attribution"))
|
|
||||||
models[i].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
|
||||||
|
|
||||||
for (int j = 0; j < tappableLength; ++j) {
|
|
||||||
JSONObject tappableObject = tappableObjects.getJSONObject(j);
|
|
||||||
if (tappableObject.optString("__typename").equals("GraphTappableFeedMedia")) {
|
|
||||||
models[i].setTappableShortCode(tappableObject.getJSONObject("media").getString(Constants.EXTRAS_SHORTCODE));
|
|
||||||
}
|
|
||||||
else if (tappableObject.optString("__typename").equals("GraphTappableStoryPoll")) {
|
|
||||||
models[i].setPoll(new PollModel(
|
|
||||||
tappableObject.getString("id"),
|
|
||||||
tappableObject.getString("question"),
|
|
||||||
tappableObject.getJSONArray("tallies").getJSONObject(0).getString("text"),
|
|
||||||
tappableObject.getJSONArray("tallies").getJSONObject(0).getInt("count"),
|
|
||||||
tappableObject.getJSONArray("tallies").getJSONObject(1).getString("text"),
|
|
||||||
tappableObject.getJSONArray("tallies").getJSONObject(1).getInt("count"),
|
|
||||||
tappableObject.optInt("viewer_vote", -1)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = models;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.disconnect();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
if (logCollector != null)
|
|
||||||
logCollector.appendException(e, LogCollector.LogFile.ASYNC_STORY_STATUS_FETCHER, "doInBackground");
|
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
if (fetchListener != null) fetchListener.doBefore();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final StoryModel[] result) {
|
|
||||||
if (fetchListener != null) fetchListener.onResult(result);
|
|
||||||
}
|
|
||||||
}
|
|
146
app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java
Executable file
146
app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java
Executable file
@ -0,0 +1,146 @@
|
|||||||
|
package awais.instagrabber.asyncs.i;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import awais.instagrabber.BuildConfig;
|
||||||
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
|
import awais.instagrabber.models.ViewerPostModel;
|
||||||
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awaisomereport.LogCollector;
|
||||||
|
|
||||||
|
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
|
||||||
|
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
|
||||||
|
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
||||||
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
|
public final class iPostFetcher extends AsyncTask<Void, Void, ViewerPostModel[]> {
|
||||||
|
private final String id;
|
||||||
|
private final FetchListener<ViewerPostModel[]> fetchListener;
|
||||||
|
|
||||||
|
public iPostFetcher(final String id, final FetchListener<ViewerPostModel[]> fetchListener) {
|
||||||
|
this.id = id;
|
||||||
|
this.fetchListener = fetchListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ViewerPostModel[] doInBackground(final Void... voids) {
|
||||||
|
ViewerPostModel[] result = null;
|
||||||
|
try {
|
||||||
|
final HttpURLConnection conn = (HttpURLConnection) new URL("https://i.instagram.com/api/v1/media/" + id + "/info").openConnection();
|
||||||
|
conn.setUseCaches(false);
|
||||||
|
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
|
|
||||||
|
final JSONObject media = new JSONObject(Utils.readFromConnection(conn)).getJSONArray("items").getJSONObject(0);
|
||||||
|
|
||||||
|
final String username = media.has("user") ? media.getJSONObject("user").getString(Constants.EXTRAS_USERNAME) : null;
|
||||||
|
|
||||||
|
// to check if file exists
|
||||||
|
final File downloadDir = new File(Environment.getExternalStorageDirectory(), "Download" +
|
||||||
|
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
|
||||||
|
File customDir = null;
|
||||||
|
if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
|
||||||
|
final String customPath = Utils.settingsHelper.getString(FOLDER_PATH +
|
||||||
|
(Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : ""));
|
||||||
|
if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long timestamp = media.getLong("taken_at");
|
||||||
|
|
||||||
|
final boolean isVideo = media.has("has_audio") && media.optBoolean("has_audio");
|
||||||
|
final boolean isSlider = !media.isNull("carousel_media_count");
|
||||||
|
|
||||||
|
final MediaItemType mediaItemType;
|
||||||
|
if (isSlider) mediaItemType = MediaItemType.MEDIA_TYPE_SLIDER;
|
||||||
|
else if (isVideo) mediaItemType = MediaItemType.MEDIA_TYPE_VIDEO;
|
||||||
|
else mediaItemType = MediaItemType.MEDIA_TYPE_IMAGE;
|
||||||
|
|
||||||
|
final String postCaption;
|
||||||
|
final JSONObject mediaToCaption = media.optJSONObject("caption");
|
||||||
|
if (mediaToCaption == null) postCaption = null;
|
||||||
|
else postCaption = mediaToCaption.optString("text");
|
||||||
|
|
||||||
|
final long commentsCount = media.optLong("comment_count");
|
||||||
|
|
||||||
|
if (mediaItemType != MediaItemType.MEDIA_TYPE_SLIDER) {
|
||||||
|
final ViewerPostModel postModel = new ViewerPostModel(mediaItemType,
|
||||||
|
media.getString(Constants.EXTRAS_ID),
|
||||||
|
isVideo
|
||||||
|
? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true)
|
||||||
|
: Utils.getHighQualityImage(media),
|
||||||
|
media.getString("code"),
|
||||||
|
Utils.isEmpty(postCaption) ? null : postCaption,
|
||||||
|
username,
|
||||||
|
isVideo && media.has("view_count") ? media.getLong("view_count") : -1,
|
||||||
|
timestamp, media.optBoolean("has_liked"), media.optBoolean("has_viewer_saved"),
|
||||||
|
media.getLong("like_count"),
|
||||||
|
media.optJSONObject("location"));
|
||||||
|
|
||||||
|
postModel.setCommentsCount(commentsCount);
|
||||||
|
|
||||||
|
Utils.checkExistence(downloadDir, customDir, false, postModel);
|
||||||
|
|
||||||
|
result = new ViewerPostModel[]{postModel};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
final JSONArray children = media.getJSONArray("carousel_media");
|
||||||
|
final ViewerPostModel[] postModels = new ViewerPostModel[children.length()];
|
||||||
|
|
||||||
|
for (int i = 0; i < postModels.length; ++i) {
|
||||||
|
final JSONObject node = children.getJSONObject(i);
|
||||||
|
final boolean isChildVideo = node.has("video_duration");
|
||||||
|
|
||||||
|
postModels[i] = new ViewerPostModel(isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
||||||
|
media.getString(Constants.EXTRAS_ID),
|
||||||
|
isChildVideo
|
||||||
|
? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true)
|
||||||
|
: Utils.getHighQualityImage(node),
|
||||||
|
media.getString("code"),
|
||||||
|
postCaption,
|
||||||
|
username,
|
||||||
|
-1,
|
||||||
|
timestamp, media.optBoolean("has_liked"), media.optBoolean("has_viewer_saved"),
|
||||||
|
media.getLong("like_count"),
|
||||||
|
media.optJSONObject("location"));
|
||||||
|
postModels[i].setSliderDisplayUrl(Utils.getHighQualityImage(node));
|
||||||
|
|
||||||
|
Utils.checkExistence(downloadDir, customDir, true, postModels[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
postModels[0].setCommentsCount(commentsCount);
|
||||||
|
result = postModels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.disconnect();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (logCollector != null)
|
||||||
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_POST_FETCHER, "doInBackground (i)");
|
||||||
|
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
if (fetchListener != null) fetchListener.doBefore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final ViewerPostModel[] postModels) {
|
||||||
|
if (fetchListener != null) fetchListener.onResult(postModels);
|
||||||
|
}
|
||||||
|
}
|
152
app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java
Executable file
152
app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java
Executable file
@ -0,0 +1,152 @@
|
|||||||
|
package awais.instagrabber.asyncs.i;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import awais.instagrabber.BuildConfig;
|
||||||
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
|
import awais.instagrabber.models.stickers.PollModel;
|
||||||
|
import awais.instagrabber.models.stickers.QuestionModel;
|
||||||
|
import awais.instagrabber.models.StoryModel;
|
||||||
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awaisomereport.LogCollector;
|
||||||
|
|
||||||
|
import static awais.instagrabber.utils.Utils.logCollector;
|
||||||
|
|
||||||
|
public final class iStoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[]> {
|
||||||
|
private final String id, username;
|
||||||
|
private final boolean isLoc, isHashtag;
|
||||||
|
private final FetchListener<StoryModel[]> fetchListener;
|
||||||
|
|
||||||
|
public iStoryStatusFetcher(final String id, final String username, final boolean isLoc,
|
||||||
|
final boolean isHashtag, final FetchListener<StoryModel[]> fetchListener) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.isLoc = isLoc;
|
||||||
|
this.isHashtag = isHashtag;
|
||||||
|
this.fetchListener = fetchListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected StoryModel[] doInBackground(final Void... voids) {
|
||||||
|
StoryModel[] result = null;
|
||||||
|
final String url = "https://i.instagram.com/api/v1/" + (isLoc ? "locations/" : (isHashtag ? "tags/" : "feed/reels_media/?reel_ids="))
|
||||||
|
+ id + ((isLoc || isHashtag) ? "/story/" : "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
conn.setInstanceFollowRedirects(false);
|
||||||
|
conn.setUseCaches(false);
|
||||||
|
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
|
JSONObject data = (isLoc || isHashtag)
|
||||||
|
? new JSONObject(Utils.readFromConnection(conn)).getJSONObject("story")
|
||||||
|
: new JSONObject(Utils.readFromConnection(conn)).getJSONObject("reels").getJSONObject(id);
|
||||||
|
|
||||||
|
JSONArray media;
|
||||||
|
if ((media = data.optJSONArray("items")) != null && media.length() > 0 &&
|
||||||
|
(data = media.optJSONObject(0)) != null) {
|
||||||
|
|
||||||
|
final int mediaLen = media.length();
|
||||||
|
|
||||||
|
final StoryModel[] models = new StoryModel[mediaLen];
|
||||||
|
for (int i = 0; i < mediaLen; ++i) {
|
||||||
|
data = media.getJSONObject(i);
|
||||||
|
final boolean isVideo = data.has("has_audio") && data.optBoolean("has_audio");
|
||||||
|
|
||||||
|
models[i] = new StoryModel(data.getString("pk"),
|
||||||
|
data.getJSONObject("image_versions2").getJSONArray("candidates").getJSONObject(0).getString("url"),
|
||||||
|
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
||||||
|
data.optLong("taken_at", 0),
|
||||||
|
(isLoc || isHashtag) ? data.getJSONObject("user").getString("username") : username);
|
||||||
|
|
||||||
|
final JSONArray videoResources = data.optJSONArray("video_versions");
|
||||||
|
if (isVideo && videoResources != null)
|
||||||
|
models[i].setVideoUrl(Utils.getHighQualityPost(videoResources, true, true));
|
||||||
|
|
||||||
|
if (data.has("story_feed_media")) {
|
||||||
|
models[i].setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.isNull("story_app_attribution"))
|
||||||
|
models[i].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
||||||
|
|
||||||
|
if (data.has("story_polls")) {
|
||||||
|
JSONObject tappableObject = data.optJSONArray("story_polls").getJSONObject(0).optJSONObject("poll_sticker");
|
||||||
|
if (tappableObject != null) models[i].setPoll(new PollModel(
|
||||||
|
String.valueOf(tappableObject.getLong("poll_id")),
|
||||||
|
tappableObject.getString("question"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getString("text"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getInt("count"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getString("text"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getInt("count"),
|
||||||
|
tappableObject.optInt("viewer_vote", -1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (data.has("story_questions")) {
|
||||||
|
JSONObject tappableObject = data.getJSONArray("story_questions").getJSONObject(0).optJSONObject("question_sticker");
|
||||||
|
if (tappableObject != null) models[i].setQuestion(new QuestionModel(
|
||||||
|
String.valueOf(tappableObject.getLong("question_id")),
|
||||||
|
tappableObject.getString("question")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
JSONArray hashtags = data.optJSONArray("story_hashtags");
|
||||||
|
JSONArray locations = data.optJSONArray("story_locations");
|
||||||
|
JSONArray atmarks = data.optJSONArray("reel_mentions");
|
||||||
|
String[] mentions = new String[(hashtags == null ? 0 : hashtags.length())
|
||||||
|
+ (atmarks == null ? 0 : atmarks.length())
|
||||||
|
+ (locations == null ? 0 : locations.length())];
|
||||||
|
if (hashtags != null) {
|
||||||
|
for (int h = 0; h < hashtags.length(); ++h) {
|
||||||
|
mentions[h] = "#"+hashtags.getJSONObject(h).getJSONObject("hashtag").getString("name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (atmarks != null) {
|
||||||
|
for (int h = 0; h < atmarks.length(); ++h) {
|
||||||
|
mentions[h + (hashtags == null ? 0 : hashtags.length())] =
|
||||||
|
"@"+atmarks.getJSONObject(h).getJSONObject("user").getString("username");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (locations != null) {
|
||||||
|
for (int h = 0; h < locations.length(); ++h) {
|
||||||
|
mentions[h + (hashtags == null ? 0 : hashtags.length()) + (atmarks == null ? 0 : atmarks.length())] =
|
||||||
|
String.valueOf(locations.getJSONObject(h).getJSONObject("location").getLong("pk"))
|
||||||
|
+"/ ("+locations.getJSONObject(h).getJSONObject("location").getString("short_name")+")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mentions.length != 0) models[i].setMentions(mentions);
|
||||||
|
}
|
||||||
|
result = models;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.disconnect();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
if (logCollector != null)
|
||||||
|
logCollector.appendException(e, LogCollector.LogFile.ASYNC_STORY_STATUS_FETCHER, "doInBackground (i)");
|
||||||
|
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
if (fetchListener != null) fetchListener.doBefore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final StoryModel[] result) {
|
||||||
|
if (fetchListener != null) fetchListener.onResult(result);
|
||||||
|
}
|
||||||
|
}
|
@ -7,8 +7,9 @@ public class PostModel extends BasePostModel {
|
|||||||
protected String endCursor;
|
protected String endCursor;
|
||||||
protected boolean hasNextPage;
|
protected boolean hasNextPage;
|
||||||
|
|
||||||
public PostModel(final String shortCode) {
|
public PostModel(final String shortCode, final boolean isid) {
|
||||||
this.shortCode = shortCode;
|
if (!isid) this.shortCode = shortCode;
|
||||||
|
else this.postId = shortCode;
|
||||||
this.thumbnailUrl = null;
|
this.thumbnailUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,17 @@ package awais.instagrabber.models;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
|
import awais.instagrabber.models.stickers.PollModel;
|
||||||
|
import awais.instagrabber.models.stickers.QuestionModel;
|
||||||
|
|
||||||
public final class StoryModel implements Serializable {
|
public final class StoryModel implements Serializable {
|
||||||
private final String storyMediaId, storyUrl, username;
|
private final String storyMediaId, storyUrl, username;
|
||||||
private final MediaItemType itemType;
|
private final MediaItemType itemType;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
private String videoUrl, tappableShortCode, spotify;
|
private String videoUrl, tappableShortCode, tappableId, spotify;
|
||||||
private PollModel poll;
|
private PollModel poll;
|
||||||
|
private QuestionModel question;
|
||||||
|
private String[] mentions;
|
||||||
private int position;
|
private int position;
|
||||||
private boolean isCurrentSlide = false;
|
private boolean isCurrentSlide = false;
|
||||||
|
|
||||||
@ -49,6 +53,14 @@ public final class StoryModel implements Serializable {
|
|||||||
return poll;
|
return poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QuestionModel getQuestion() {
|
||||||
|
return question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMentions() {
|
||||||
|
return mentions;
|
||||||
|
}
|
||||||
|
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@ -73,6 +85,14 @@ public final class StoryModel implements Serializable {
|
|||||||
this.poll = poll;
|
this.poll = poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setQuestion(final QuestionModel question) {
|
||||||
|
this.question = question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMentions(final String[] mentions) {
|
||||||
|
this.mentions = mentions;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPosition(final int position) {
|
public void setPosition(final int position) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ public final class ViewerPostModel extends BasePostModel {
|
|||||||
protected final String username;
|
protected final String username;
|
||||||
protected final JSONObject location;
|
protected final JSONObject location;
|
||||||
protected final long videoViews;
|
protected final long videoViews;
|
||||||
protected String sliderDisplayUrl, commentsEndCursor;
|
protected String sliderDisplayUrl;
|
||||||
protected long commentsCount, likes;
|
protected long commentsCount, likes;
|
||||||
private boolean isCurrentSlide = false;
|
private boolean isCurrentSlide = false;
|
||||||
|
|
||||||
@ -44,10 +44,6 @@ public final class ViewerPostModel extends BasePostModel {
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCommentsEndCursor() {
|
|
||||||
return commentsEndCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final long getVideoViews() {
|
public final long getVideoViews() {
|
||||||
return videoViews;
|
return videoViews;
|
||||||
}
|
}
|
||||||
@ -71,10 +67,6 @@ public final class ViewerPostModel extends BasePostModel {
|
|||||||
this.commentsCount = commentsCount;
|
this.commentsCount = commentsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommentsEndCursor(final String commentsEndCursor) {
|
|
||||||
this.commentsEndCursor = commentsEndCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentSlide(final boolean currentSlide) {
|
public void setCurrentSlide(final boolean currentSlide) {
|
||||||
this.isCurrentSlide = currentSlide;
|
this.isCurrentSlide = currentSlide;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package awais.instagrabber.models;
|
package awais.instagrabber.models.stickers;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
20
app/src/main/java/awais/instagrabber/models/stickers/QuestionModel.java
Executable file
20
app/src/main/java/awais/instagrabber/models/stickers/QuestionModel.java
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
package awais.instagrabber.models.stickers;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public final class QuestionModel implements Serializable {
|
||||||
|
private final String id, question;
|
||||||
|
|
||||||
|
public QuestionModel(final String id, final String question) {
|
||||||
|
this.id = id; // only the poll id
|
||||||
|
this.question = question;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuestion() {
|
||||||
|
return question;
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ public final class Constants {
|
|||||||
// never Export
|
// never Export
|
||||||
public static final String COOKIE = "cookie";
|
public static final String COOKIE = "cookie";
|
||||||
public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg";
|
public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg";
|
||||||
|
public static final String DEVICE_UUID = "device_uuid";
|
||||||
//////////////////////// EXTRAS ////////////////////////
|
//////////////////////// EXTRAS ////////////////////////
|
||||||
public static final String EXTRAS_USER = "user";
|
public static final String EXTRAS_USER = "user";
|
||||||
public static final String EXTRAS_HASHTAG = "hashtag";
|
public static final String EXTRAS_HASHTAG = "hashtag";
|
||||||
@ -45,6 +46,8 @@ public final class Constants {
|
|||||||
public static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 8.1.0; motorola one Build/OPKS28.63-18-3; wv) " +
|
public static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 8.1.0; motorola one Build/OPKS28.63-18-3; wv) " +
|
||||||
"AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36 " +
|
"AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36 " +
|
||||||
"Instagram 72.0.0.21.98 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 132081645)";
|
"Instagram 72.0.0.21.98 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 132081645)";
|
||||||
|
public static final String I_USER_AGENT =
|
||||||
|
"Instagram 72.0.0.21.98 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 132081645)";
|
||||||
// see https://github.com/dilame/instagram-private-api/blob/master/src/core/constants.ts
|
// see https://github.com/dilame/instagram-private-api/blob/master/src/core/constants.ts
|
||||||
public static final String SUPPORTED_CAPABILITIES = "[ { \"name\": \"SUPPORTED_SDK_VERSIONS\", \"value\":" +
|
public static final String SUPPORTED_CAPABILITIES = "[ { \"name\": \"SUPPORTED_SDK_VERSIONS\", \"value\":" +
|
||||||
" \"13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0," +
|
" \"13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0," +
|
||||||
|
@ -18,6 +18,7 @@ import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT;
|
|||||||
import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED;
|
import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED;
|
||||||
import static awais.instagrabber.utils.Constants.DATE_TIME_FORMAT;
|
import static awais.instagrabber.utils.Constants.DATE_TIME_FORMAT;
|
||||||
import static awais.instagrabber.utils.Constants.DATE_TIME_SELECTION;
|
import static awais.instagrabber.utils.Constants.DATE_TIME_SELECTION;
|
||||||
|
import static awais.instagrabber.utils.Constants.DEVICE_UUID;
|
||||||
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
|
import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER;
|
||||||
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
|
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
|
||||||
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
||||||
@ -101,7 +102,7 @@ public final class SettingsHelper {
|
|||||||
if (sharedPreferences != null) sharedPreferences.edit().putBoolean(key, val).apply();
|
if (sharedPreferences != null) sharedPreferences.edit().putBoolean(key, val).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@StringDef({COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT})
|
@StringDef({COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID})
|
||||||
public @interface StringSettings {}
|
public @interface StringSettings {}
|
||||||
|
|
||||||
@StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
|
@StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
|
||||||
|
@ -53,7 +53,6 @@ import java.net.HttpCookie;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -75,7 +74,7 @@ import awais.instagrabber.models.BasePostModel;
|
|||||||
import awais.instagrabber.models.FeedStoryModel;
|
import awais.instagrabber.models.FeedStoryModel;
|
||||||
import awais.instagrabber.models.HighlightModel;
|
import awais.instagrabber.models.HighlightModel;
|
||||||
import awais.instagrabber.models.IntentModel;
|
import awais.instagrabber.models.IntentModel;
|
||||||
import awais.instagrabber.models.PollModel;
|
import awais.instagrabber.models.stickers.PollModel;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
import awais.instagrabber.models.ProfileModel;
|
||||||
import awais.instagrabber.models.StoryModel;
|
import awais.instagrabber.models.StoryModel;
|
||||||
import awais.instagrabber.models.direct_messages.DirectItemModel;
|
import awais.instagrabber.models.direct_messages.DirectItemModel;
|
||||||
@ -89,6 +88,7 @@ import awais.instagrabber.models.enums.MediaItemType;
|
|||||||
import awais.instagrabber.models.enums.NotificationType;
|
import awais.instagrabber.models.enums.NotificationType;
|
||||||
import awais.instagrabber.models.enums.RavenExpiringMediaType;
|
import awais.instagrabber.models.enums.RavenExpiringMediaType;
|
||||||
import awais.instagrabber.models.enums.RavenMediaViewType;
|
import awais.instagrabber.models.enums.RavenMediaViewType;
|
||||||
|
import awais.instagrabber.models.stickers.QuestionModel;
|
||||||
import awaisomereport.LogCollector;
|
import awaisomereport.LogCollector;
|
||||||
|
|
||||||
import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemActionLogModel;
|
import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemActionLogModel;
|
||||||
@ -260,8 +260,9 @@ public final class Utils {
|
|||||||
return stringBuilder;
|
return stringBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isI: true if the content was requested from i.instagram.com instead of graphql
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getHighQualityPost(final JSONArray resources, final boolean isVideo) {
|
public static String getHighQualityPost(final JSONArray resources, final boolean isVideo, final boolean isI) {
|
||||||
try {
|
try {
|
||||||
final int resourcesLen = resources.length();
|
final int resourcesLen = resources.length();
|
||||||
|
|
||||||
@ -270,18 +271,18 @@ public final class Utils {
|
|||||||
int lastResBase = 0, lastIndexBase = -1;
|
int lastResBase = 0, lastIndexBase = -1;
|
||||||
for (int i = 0; i < resourcesLen; ++i) {
|
for (int i = 0; i < resourcesLen; ++i) {
|
||||||
final JSONObject item = resources.getJSONObject(i);
|
final JSONObject item = resources.getJSONObject(i);
|
||||||
if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE))) {
|
if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE) || isI)) {
|
||||||
sources[i] = item.getString("src");
|
sources[i] = item.getString(isI ? "url" : "src");
|
||||||
final int currRes = item.getInt("config_width") * item.getInt("config_height");
|
final int currRes = item.getInt(isI ? "width" : "config_width") * item.getInt(isI ? "height" : "config_height");
|
||||||
|
|
||||||
final String profile = isVideo ? item.getString(Constants.EXTRAS_PROFILE) : null;
|
final String profile = isVideo ? item.optString(Constants.EXTRAS_PROFILE) : null;
|
||||||
|
|
||||||
if (!isVideo || "MAIN".equals(profile)) {
|
if (!isVideo || "MAIN".equals(profile)) {
|
||||||
if (currRes > lastResMain) {
|
if (currRes > lastResMain) {
|
||||||
lastResMain = currRes;
|
lastResMain = currRes;
|
||||||
lastIndexMain = i;
|
lastIndexMain = i;
|
||||||
}
|
}
|
||||||
} else if ("BASELINE".equals(profile)) {
|
} else {
|
||||||
if (currRes > lastResBase) {
|
if (currRes > lastResBase) {
|
||||||
lastResBase = currRes;
|
lastResBase = currRes;
|
||||||
lastIndexBase = i;
|
lastIndexBase = i;
|
||||||
@ -305,7 +306,9 @@ public final class Utils {
|
|||||||
public static String getHighQualityImage(final JSONObject resources) {
|
public static String getHighQualityImage(final JSONObject resources) {
|
||||||
String src = null;
|
String src = null;
|
||||||
try {
|
try {
|
||||||
if (resources.has("display_resources")) src = getHighQualityPost(resources.getJSONArray("display_resources"), false);
|
if (resources.has("display_resources")) src = getHighQualityPost(resources.getJSONArray("display_resources"), false, false);
|
||||||
|
else if (resources.has("image_versions2"))
|
||||||
|
src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true);
|
||||||
if (src == null) return resources.getString("display_url");
|
if (src == null) return resources.getString("display_url");
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
if (logCollector != null)
|
if (logCollector != null)
|
||||||
@ -1157,6 +1160,23 @@ public final class Utils {
|
|||||||
return "[]";
|
return "[]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static String iHighlightIdsMerger(final String... strings) {
|
||||||
|
if (strings != null) {
|
||||||
|
int iMax = strings.length - 1;
|
||||||
|
if (iMax != -1) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
builder.append(strings[i]);
|
||||||
|
if (i == iMax) return builder.toString();
|
||||||
|
builder.append("&reel_ids=");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public static void putHighlightModels(final HttpURLConnection conn, final Object[] model) throws Exception {
|
public static void putHighlightModels(final HttpURLConnection conn, final Object[] model) throws Exception {
|
||||||
final boolean isHighlightModel = model instanceof HighlightModel[];
|
final boolean isHighlightModel = model instanceof HighlightModel[];
|
||||||
final boolean isFeedStoryModel = model instanceof FeedStoryModel[];
|
final boolean isFeedStoryModel = model instanceof FeedStoryModel[];
|
||||||
@ -1192,7 +1212,7 @@ public final class Utils {
|
|||||||
data.getLong("taken_at_timestamp"), data.getJSONObject("owner").getString("username"));
|
data.getLong("taken_at_timestamp"), data.getJSONObject("owner").getString("username"));
|
||||||
|
|
||||||
if (isVideo && data.has("video_resources"))
|
if (isVideo && data.has("video_resources"))
|
||||||
storyModels[j].setVideoUrl(Utils.getHighQualityPost(data.getJSONArray("video_resources"), true));
|
storyModels[j].setVideoUrl(Utils.getHighQualityPost(data.getJSONArray("video_resources"), true, false));
|
||||||
|
|
||||||
if (!data.isNull("story_app_attribution"))
|
if (!data.isNull("story_app_attribution"))
|
||||||
storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
||||||
@ -1226,6 +1246,75 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void iPutFeedStoryModels(final HttpURLConnection conn, final FeedStoryModel[] model, final String[] ids) throws Exception {
|
||||||
|
final JSONObject highlightsMediaReel = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("reels");
|
||||||
|
final int mediaLength = highlightsMediaReel.length();
|
||||||
|
|
||||||
|
for (int i = 0; i < mediaLength; ++i) {
|
||||||
|
final JSONArray items = highlightsMediaReel.getJSONObject(ids[i]).getJSONArray("items");
|
||||||
|
final int itemsLen = items.length();
|
||||||
|
|
||||||
|
final StoryModel[] storyModels = new StoryModel[itemsLen];
|
||||||
|
for (int j = 0; j < itemsLen; ++j) {
|
||||||
|
final JSONObject data = items.getJSONObject(j);
|
||||||
|
final boolean isVideo = data.has("has_audio") && data.optBoolean("has_audio");
|
||||||
|
|
||||||
|
storyModels[j] = new StoryModel(data.getString("pk"),
|
||||||
|
data.getJSONObject("image_versions2").getJSONArray("candidates").getJSONObject(0).getString("url"),
|
||||||
|
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
||||||
|
data.optLong("taken_at", 0),
|
||||||
|
model[i].getProfileModel().getUsername());
|
||||||
|
|
||||||
|
final JSONArray videoResources = data.optJSONArray("video_versions");
|
||||||
|
if (isVideo && videoResources != null)
|
||||||
|
storyModels[j].setVideoUrl(Utils.getHighQualityPost(videoResources, true, true));
|
||||||
|
|
||||||
|
if (data.has("story_feed_media")) {
|
||||||
|
storyModels[j].setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.isNull("story_app_attribution"))
|
||||||
|
storyModels[j].setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
||||||
|
|
||||||
|
if (data.has("story_polls")) {
|
||||||
|
JSONObject tappableObject = data.optJSONArray("story_polls").getJSONObject(0).optJSONObject("poll_sticker");
|
||||||
|
if (tappableObject != null) storyModels[j].setPoll(new PollModel(
|
||||||
|
String.valueOf(tappableObject.getLong("poll_id")),
|
||||||
|
tappableObject.getString("question"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getString("text"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getInt("count"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getString("text"),
|
||||||
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getInt("count"),
|
||||||
|
tappableObject.optInt("viewer_vote", -1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (data.has("story_questions")) {
|
||||||
|
JSONObject tappableObject = data.getJSONArray("story_questions").getJSONObject(0).optJSONObject("question_sticker");
|
||||||
|
if (tappableObject != null) storyModels[j].setQuestion(new QuestionModel(
|
||||||
|
String.valueOf(tappableObject.getLong("question_id")),
|
||||||
|
tappableObject.getString("question")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
JSONArray hashtags = data.optJSONArray("story_hashtags");
|
||||||
|
JSONArray atmarks = data.optJSONArray("reel_mentions");
|
||||||
|
String[] mentions = new String[(hashtags == null ? 0 : hashtags.length()) + (atmarks == null ? 0 : atmarks.length())];
|
||||||
|
if (hashtags != null) {
|
||||||
|
for (int h = 0; h < hashtags.length(); ++h) {
|
||||||
|
mentions[h] = "#"+hashtags.getJSONObject(h).getJSONObject("hashtag").getString("name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (atmarks != null) {
|
||||||
|
for (int h = 0; h < atmarks.length(); ++h) {
|
||||||
|
mentions[h + (hashtags == null ? 0 : hashtags.length())] =
|
||||||
|
"@"+atmarks.getJSONObject(h).getJSONObject("user").getString("username");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storyModels[j].setMentions(mentions);
|
||||||
|
}
|
||||||
|
model[i].setStoryModels(storyModels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String sign(final String message) {
|
public static String sign(final String message) {
|
||||||
try {
|
try {
|
||||||
Mac hasher = Mac.getInstance("HmacSHA256");
|
Mac hasher = Mac.getInstance("HmacSHA256");
|
||||||
@ -1237,8 +1326,7 @@ public final class Utils {
|
|||||||
if (hex.length() == 1) hexString.append('0');
|
if (hex.length() == 1) hexString.append('0');
|
||||||
hexString.append(hex);
|
hexString.append(hex);
|
||||||
}
|
}
|
||||||
Log.d("austin_debug", "hash: " + hexString.toString());
|
return "ig_sig_key_version="+Constants.SIGNATURE_VERSION+"&signed_body=" + hexString.toString() + "." + message;
|
||||||
return hexString.toString() + "." + message;
|
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
Log.e("austin_debug", "sign: ", e);
|
Log.e("austin_debug", "sign: ", e);
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0.3"
|
android:layout_weight="0.3"
|
||||||
android:background="#0000"
|
android:background="#0000"
|
||||||
android:weightSum="3"
|
|
||||||
android:layout_gravity="bottom">
|
android:layout_gravity="bottom">
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/viewStoryPost"
|
android:id="@+id/viewStoryPost"
|
||||||
@ -56,14 +55,32 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:backgroundTint="@color/btn_green_background" />
|
app:backgroundTint="@color/btn_green_background" />
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/interactStory"
|
android:id="@+id/poll"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/view_story_post"
|
android:text="@string/vote_story_poll"
|
||||||
android:textColor="@color/btn_blue_text_color"
|
android:textColor="@color/btn_blue_text_color"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:backgroundTint="@color/btn_blue_background" />
|
app:backgroundTint="@color/btn_blue_background" />
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/answer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/answer_story"
|
||||||
|
android:textColor="@color/btn_blue_text_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:backgroundTint="@color/btn_blue_background" />
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/mention"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/story_mentions"
|
||||||
|
android:textColor="@color/btn_orange_text_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:backgroundTint="@color/btn_orange_background" />
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/spotify"
|
android:id="@+id/spotify"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -67,6 +67,10 @@
|
|||||||
<string name="vote_story_poll">Vote</string>
|
<string name="vote_story_poll">Vote</string>
|
||||||
<string name="votef_story_poll">Vote successful!</string>
|
<string name="votef_story_poll">Vote successful!</string>
|
||||||
<string name="voted_story_poll">You have already voted!</string>
|
<string name="voted_story_poll">You have already voted!</string>
|
||||||
|
<string name="answer_story">Answer</string>
|
||||||
|
<string name="answer_hint">Answer...</string>
|
||||||
|
<string name="answered_story">Answer successful!</string>
|
||||||
|
<string name="story_mentions">Mentions</string>
|
||||||
<string name="priv_acc">This Account is Private</string>
|
<string name="priv_acc">This Account is Private</string>
|
||||||
<string name="no_acc">You can log in via Settings on the bottom-right corner. Or, you can view public accounts without login!</string>
|
<string name="no_acc">You can log in via Settings on the bottom-right corner. Or, you can view public accounts without login!</string>
|
||||||
<string name="no_acc_logged_in">You can swipe left/right for explore/feed, or search something below!</string>
|
<string name="no_acc_logged_in">You can swipe left/right for explore/feed, or search something below!</string>
|
||||||
|
5
fastlane/metadata/android/changelogs/37.txt
Normal file
5
fastlane/metadata/android/changelogs/37.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
* You can now respond to question boxes in stories
|
||||||
|
* You can now check out story mentions (except non-Spotify music stickers, but you can hear them by playing the story)
|
||||||
|
* Above 2 does not apply to highlights
|
||||||
|
* You can now click on locations from feed
|
||||||
|
* Fixed a bug where you cannot access your own follower/following list when you are private and have no posts
|
Loading…
Reference in New Issue
Block a user