From 71402cd164bc61ce6b461d6f5fcae0fede00af12 Mon Sep 17 00:00:00 2001 From: Austin Huang Date: Thu, 30 Jul 2020 18:19:44 -0400 Subject: [PATCH] answering polls in stories --- README.md | 1 + .../instagrabber/activities/StoryViewer.java | 82 ++++++++++++++++++- .../instagrabber/adapters/FeedAdapter.java | 2 - .../instagrabber/asyncs/DiscoverFetcher.java | 2 +- .../instagrabber/asyncs/LocationFetcher.java | 1 - .../instagrabber/asyncs/PostFetcher.java | 4 +- .../instagrabber/asyncs/PostsFetcher.java | 2 +- .../asyncs/StoryStatusFetcher.java | 21 +++-- .../awais/instagrabber/models/PollModel.java | 52 ++++++++++++ .../awais/instagrabber/models/StoryModel.java | 9 ++ .../java/awais/instagrabber/utils/Utils.java | 27 ++++-- .../main/res/layout/activity_story_viewer.xml | 32 ++++++-- app/src/main/res/values/strings.xml | 3 + 13 files changed, 207 insertions(+), 31 deletions(-) create mode 100755 app/src/main/java/awais/instagrabber/models/PollModel.java diff --git a/README.md b/README.md index 5d793f41..40896085 100755 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Not compatible with pre-16.6 versions (including alpha). Remember to read the [wiki](https://github.com/austinhuang0131/instagrabber/wiki) for more info! [![Open Source Love svg3](https://badges.frapsoft.com/os/v3/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE) [![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/austinhuang0131/instagrabber)](https://snyk.io/test/github/austinhuang0131/instagrabber) [![LGTM Alerts](https://img.shields.io/lgtm/alerts/github/austinhuang0131/instagrabber)](https://lgtm.com/projects/g/austinhuang0131/instagrabber) diff --git a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java index c657f79c..d0adf0df 100755 --- a/app/src/main/java/awais/instagrabber/activities/StoryViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/StoryViewer.java @@ -15,10 +15,12 @@ import android.util.Pair; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.ArrayAdapter; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.view.GestureDetectorCompat; @@ -36,8 +38,11 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import java.io.DataOutputStream; import java.io.File; import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; import awais.instagrabber.BuildConfig; import awais.instagrabber.R; @@ -47,6 +52,7 @@ import awais.instagrabber.customviews.helpers.SwipeGestureListener; import awais.instagrabber.databinding.ActivityStoryViewerBinding; import awais.instagrabber.interfaces.SwipeEvent; import awais.instagrabber.models.FeedStoryModel; +import awais.instagrabber.models.PollModel; import awais.instagrabber.models.PostModel; import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.enums.MediaItemType; @@ -79,6 +85,7 @@ public final class StoryViewer extends BaseLanguageActivity { private SimpleExoPlayer player; private SwipeEvent swipeEvent; private MenuItem menuDownload; + private PollModel poll; private StoryModel currentStory; private String url, username; private int slidePos = 0, lastSlidePos = 0; @@ -121,8 +128,6 @@ public final class StoryViewer extends BaseLanguageActivity { @Override public void onSwipe(final boolean isRightSwipe) { - Log.d("austin_debug", "swipe: "+(isRightSwipe ? "backward " : "forward ") + slidePos + "/" + storiesLen + " " - + (slidePos == storiesLen - 1 && isRightSwipe == false) + " " + intent.hasExtra(Constants.FEED)); if (storyModels != null && storiesLen > 0) { if (((slidePos + 1 >= storiesLen && isRightSwipe == false) || (slidePos == 0 && isRightSwipe == true)) && intent.hasExtra(Constants.FEED)) { @@ -195,6 +200,30 @@ public final class StoryViewer extends BaseLanguageActivity { .putExtra(Constants.EXTRAS_POST, new PostModel(tag.toString()))); }); + storyViewerBinding.interactStory.setOnClickListener(v -> { + final Object tag = v.getTag(); + if (tag instanceof PollModel) { + poll = (PollModel) tag; + if (poll.getMyChoice() > -1) + new AlertDialog.Builder(this).setTitle(R.string.voted_story_poll) + .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{ + (poll.getMyChoice() == 0 ? "√ " : "") + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")", + (poll.getMyChoice() == 1 ? "√ " : "") + poll.getRightChoice() + " (" + poll.getRightCount() + ")" + }), null) + .setPositiveButton(R.string.ok, null) + .show(); + else new AlertDialog.Builder(this).setTitle(poll.getQuestion()) + .setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{ + poll.getLeftChoice() + " (" + poll.getLeftCount() + ")", + poll.getRightChoice() + " (" + poll.getRightCount() + ")" + }), (d, w) -> { + new VoteAction().execute(w); + }) + .setPositiveButton(R.string.cancel, null) + .show(); + } + }); + storiesAdapter.setData(storyModels); if (storyModels.length > 1) storyViewerBinding.storiesList.setVisibility(View.VISIBLE); @@ -368,9 +397,14 @@ public final class StoryViewer extends BaseLanguageActivity { storyViewerBinding.viewStoryPost.setVisibility(shortCode != null ? View.VISIBLE : View.GONE); storyViewerBinding.viewStoryPost.setTag(shortCode); + final PollModel poll = currentStory.getPoll(); + storyViewerBinding.interactStory.setVisibility(poll != null ? View.VISIBLE : View.GONE); + storyViewerBinding.interactStory.setText(R.string.vote_story_poll); + storyViewerBinding.interactStory.setTag(poll); + releasePlayer(); final Intent intent = getIntent(); - if (intent.hasExtra(Constants.EXTRAS_HASHTAG)) { + if (intent.getBooleanExtra(Constants.EXTRAS_HASHTAG, false)) { storyViewerBinding.toolbar.toolbar.setTitle(currentStory.getUsername() + " (" + intent.getStringExtra(Constants.EXTRAS_USERNAME) + ")"); storyViewerBinding.toolbar.toolbar.setOnClickListener(v -> { searchUsername(currentStory.getUsername()); @@ -408,4 +442,46 @@ public final class StoryViewer extends BaseLanguageActivity { } return returnvalue; } + + class VoteAction extends AsyncTask { + int ok = -1; + String action; + + protected Void doInBackground(Integer... rawchoice) { + int choice = rawchoice[0]; + final String url = "https://www.instagram.com/media/"+currentStory.getStoryMediaId()+"/"+poll.getId()+"/story_poll_vote/"; + try { + final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); + urlConnection.setRequestMethod("POST"); + urlConnection.setUseCaches(false); + urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT); + urlConnection.setRequestProperty("x-csrftoken", + settingsHelper.getString(Constants.COOKIE).split("csrftoken=")[1].split(";")[0]); + urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + urlConnection.setRequestProperty("Content-Length", "6"); + urlConnection.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); + wr.writeBytes("vote="+choice); + wr.flush(); + wr.close(); + urlConnection.connect(); + if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { + ok = choice; + } + 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 > -1) { + poll.setMyChoice(ok); + Toast.makeText(getApplicationContext(), R.string.votef_story_poll, Toast.LENGTH_SHORT).show(); + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java index 526984ab..c223040e 100755 --- a/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/FeedAdapter.java @@ -425,8 +425,6 @@ public final class FeedAdapter extends RecyclerView.Adapter if (btnMute != null) btnMute.setVisibility(View.VISIBLE); final PlayerView playerView = new PlayerView(context); - Log.d("austin_debug","1"); - player = new SimpleExoPlayer.Builder(context).build(); playerView.setPlayer(player); diff --git a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java index 4569a4f4..18eb08f2 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java @@ -177,7 +177,7 @@ public final class DiscoverFetcher extends AsyncTask private final String idSlug; public LocationFetcher(String idSlug, FetchListener fetchListener) { - Log.d("austin_debug", idSlug); // idSlug = id + "/" + slug this.idSlug = idSlug; this.fetchListener = fetchListener; diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java index c201f7a9..0f6a06a6 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java @@ -95,7 +95,7 @@ public final class PostFetcher extends AsyncTask postModel.setCommentsCount(commentsCount); postModel.setCommentsEndCursor(endCursor); - Utils.checkExistence(downloadDir, customDir, username, false, -1, postModel); + Utils.checkExistence(downloadDir, customDir, username, false, postModel); result = new ViewerPostModel[]{postModel}; @@ -119,7 +119,7 @@ public final class PostFetcher extends AsyncTask media.optJSONObject("location")); postModels[i].setSliderDisplayUrl(node.getString("display_url")); - Utils.checkExistence(downloadDir, customDir, username, true, i, postModels[i]); + Utils.checkExistence(downloadDir, customDir, username, true, postModels[i]); } postModels[0].setCommentsCount(commentsCount); diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java index 7d8696a5..8a41325a 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java @@ -115,7 +115,7 @@ public final class PostsFetcher extends AsyncTask { mediaNode.getLong("taken_at_timestamp"), mediaNode.optBoolean("viewer_has_liked"), mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count")); - Utils.checkExistence(downloadDir, customDir, username, isSlider, -1, models[i]); + Utils.checkExistence(downloadDir, customDir, username, isSlider, models[i]); } if (models[models.length - 1] != null) diff --git a/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java index f885d936..4c84fca1 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/StoryStatusFetcher.java @@ -12,6 +12,7 @@ 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; @@ -34,8 +35,8 @@ public final class StoryStatusFetcher extends AsyncTask Pattern.matches(fileWithPrefix, name); File[] files = downloadDir.listFiles(filenameFilter); @@ -1007,7 +1008,6 @@ public final class Utils { if (logCollector != null) logCollector.appendException(e, LogCollector.LogFile.UTILS, "checkExistence", new Pair<>("isSlider", isSlider), - new Pair<>("sliderIndex", sliderIndex), new Pair<>("model", model)); if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); } @@ -1167,9 +1167,18 @@ public final class Utils { for (int k = 0; k < tappableLength; ++k) { JSONObject jsonObject = tappableObjects.getJSONObject(k); if (jsonObject.getString("__typename").equals("GraphTappableFeedMedia") && jsonObject.has("media")) { - jsonObject = jsonObject.getJSONObject("media"); - storyModels[j].setTappableShortCode(jsonObject.getString(Constants.EXTRAS_SHORTCODE)); - break; + storyModels[j].setTappableShortCode(jsonObject.getJSONObject("media").getString(Constants.EXTRAS_SHORTCODE)); + } + else if (jsonObject.optString("__typename").equals("GraphTappableStoryPoll")) { + storyModels[j].setPoll(new PollModel( + jsonObject.getString("id"), + jsonObject.getString("question"), + jsonObject.getJSONArray("tallies").getJSONObject(0).getString("text"), + jsonObject.getJSONArray("tallies").getJSONObject(0).getInt("count"), + jsonObject.getJSONArray("tallies").getJSONObject(1).getString("text"), + jsonObject.getJSONArray("tallies").getJSONObject(1).getInt("count"), + jsonObject.optInt("viewer_vote", -1) + )); } } } diff --git a/app/src/main/res/layout/activity_story_viewer.xml b/app/src/main/res/layout/activity_story_viewer.xml index 23d0593a..f332cb0b 100755 --- a/app/src/main/res/layout/activity_story_viewer.xml +++ b/app/src/main/res/layout/activity_story_viewer.xml @@ -38,15 +38,33 @@ android:layout_gravity="center" android:visibility="gone" /> - + android:layout_weight="0.3" + android:background="#0000" + android:weightSum="2" + android:layout_gravity="bottom"> + + + Show stories No more stories! View Story Post + Vote + Vote successful! + You have already voted! This Account is Private This Account has No Posts Current version: v%s