This commit is contained in:
Austin Huang 2020-08-04 12:51:30 -04:00
parent 0f523a7eef
commit 3fb404fa20
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
8 changed files with 157 additions and 4 deletions

View File

@ -62,6 +62,7 @@ import awais.instagrabber.interfaces.SwipeEvent;
import awais.instagrabber.models.FeedStoryModel;
import awais.instagrabber.models.stickers.PollModel;
import awais.instagrabber.models.stickers.QuestionModel;
import awais.instagrabber.models.stickers.QuizModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.MediaItemType;
@ -97,6 +98,7 @@ public final class StoryViewer extends BaseLanguageActivity {
private PollModel poll;
private QuestionModel question;
private String[] mentions;
private QuizModel quiz;
private StoryModel currentStory;
private String url, username;
private int slidePos = 0, lastSlidePos = 0;
@ -267,11 +269,25 @@ public final class StoryViewer extends BaseLanguageActivity {
.setPositiveButton(R.string.cancel, null)
.show();
}
else if (tag instanceof QuizModel) {
quiz = (QuizModel) quiz;
String[] choices = new String[quiz.getChoices().length];
for (int q = 0; q < choices.length; ++q) {
choices[q] = (quiz.getMyChoice() == q ? "" :"") + quiz.getChoices()[q]+ " (" + String.valueOf(quiz.getCounts()[q]) + ")";
}
new AlertDialog.Builder(this).setTitle(quiz.getMyChoice() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion())
.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, choices), (d,w) -> {
if (quiz.getMyChoice() == -1) new QuizAction().execute(w);
})
.setPositiveButton(R.string.cancel, null)
.show();
}
};
storyViewerBinding.poll.setOnClickListener(storyActionListener);
storyViewerBinding.answer.setOnClickListener(storyActionListener);
storyViewerBinding.mention.setOnClickListener(storyActionListener);
storyViewerBinding.quiz.setOnClickListener(storyActionListener);
storiesAdapter.setData(storyModels);
if (storyModels.length > 1) storyViewerBinding.storiesList.setVisibility(View.VISIBLE);
@ -462,6 +478,10 @@ public final class StoryViewer extends BaseLanguageActivity {
storyViewerBinding.mention.setVisibility((mentions != null && mentions.length > 0) ? View.VISIBLE : View.GONE);
storyViewerBinding.mention.setTag(mentions);
quiz = currentStory.getQuiz();
storyViewerBinding.quiz.setVisibility((quiz != null && mentions.length > 0) ? View.VISIBLE : View.GONE);
storyViewerBinding.quiz.setTag(quiz);
releasePlayer();
final Intent intent = getIntent();
if (intent.getBooleanExtra(Constants.EXTRAS_HASHTAG, false)) {
@ -545,6 +565,56 @@ public final class StoryViewer extends BaseLanguageActivity {
}
}
class QuizAction extends AsyncTask<Integer, Void, Void> {
int ok = -1;
String action;
protected Void doInBackground(Integer... rawchoice) {
int choice = rawchoice[0];
final String cookie = settingsHelper.getString(Constants.COOKIE);
final String url = "https://i.instagram.com/api/v1/media/"+currentStory.getStoryMediaId()+"/"+quiz.getId()+"/story_quiz_answer/";
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)
+"\"}");
ogbody.put("answer", String.valueOf(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();
Log.d("austin_debug", "quiz: "+url+" "+cookie+" "+urlParameters);
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", "quiz: " + ex);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (ok > -1) {
quiz.setMyChoice(ok);
Toast.makeText(getApplicationContext(), R.string.answered_story, Toast.LENGTH_SHORT).show();
}
}
}
class RespondAction extends AsyncTask<String, Void, Void> {
boolean ok = false;
String action;
@ -581,7 +651,7 @@ public final class StoryViewer extends BaseLanguageActivity {
else Toast.makeText(getApplicationContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
urlConnection.disconnect();
} catch (Throwable ex) {
Log.e("austin_debug", "vote: " + ex);
Log.e("austin_debug", "respond: " + ex);
}
return null;
}

View File

@ -13,6 +13,7 @@ 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.stickers.QuizModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.utils.Constants;
@ -100,6 +101,26 @@ public final class iStoryStatusFetcher extends AsyncTask<Void, Void, StoryModel[
tappableObject.getString("question")
));
}
if (data.has("story_quizs")) {
JSONObject tappableObject = data.getJSONArray("story_quizs").getJSONObject(0).optJSONObject("quiz_sticker");
if (tappableObject != null) {
String[] choices = new String[tappableObject.getJSONArray("tallies").length()];
Long[] counts = new Long[choices.length];
for (int q = 0; q < choices.length; ++q) {
JSONObject tempchoice = tappableObject.getJSONArray("tallies").getJSONObject(q);
choices[q] = (q == tappableObject.getInt("correct_answer") ? "*** " : "")
+tempchoice.getString("text");
counts[q] = tempchoice.getLong("count");
}
models[i].setQuiz(new QuizModel(
String.valueOf(tappableObject.getLong("quiz_id")),
tappableObject.getString("question"),
choices,
counts,
tappableObject.optInt("viewer_answer", -1)
));
}
}
JSONArray hashtags = data.optJSONArray("story_hashtags");
JSONArray locations = data.optJSONArray("story_locations");
JSONArray atmarks = data.optJSONArray("reel_mentions");

View File

@ -5,6 +5,7 @@ import java.io.Serializable;
import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.stickers.PollModel;
import awais.instagrabber.models.stickers.QuestionModel;
import awais.instagrabber.models.stickers.QuizModel;
public final class StoryModel implements Serializable {
private final String storyMediaId, storyUrl, username;
@ -13,6 +14,7 @@ public final class StoryModel implements Serializable {
private String videoUrl, tappableShortCode, tappableId, spotify;
private PollModel poll;
private QuestionModel question;
private QuizModel quiz;
private String[] mentions;
private int position;
private boolean isCurrentSlide = false;
@ -57,6 +59,10 @@ public final class StoryModel implements Serializable {
return question;
}
public QuizModel getQuiz() {
return quiz;
}
public String[] getMentions() {
return mentions;
}
@ -89,6 +95,10 @@ public final class StoryModel implements Serializable {
this.question = question;
}
public void setQuiz(final QuizModel quiz) {
this.quiz = quiz;
}
public void setMentions(final String[] mentions) {
this.mentions = mentions;
}

View File

@ -0,0 +1,37 @@
package awais.instagrabber.models.stickers;
import java.io.Serializable;
public final class QuizModel implements Serializable {
private final String id, question;
private final String[] choices;
private Long[] counts;
private int mychoice;
public QuizModel(final String id, final String question, final String[] choices, final Long[] counts, final int mychoice) {
this.id = id; // only the poll id
this.question = question;
this.choices = choices;
this.counts = counts;
this.mychoice = mychoice;
}
public String getId() {
return id;
}
public String getQuestion() {
return question;
}
public String[] getChoices() { return choices;}
public Long[] getCounts() { return counts;}
public int getMyChoice() { return mychoice; }
public void setMyChoice(final int choice) {
this.mychoice = choice;
counts[choice] += 1L;
}
}

View File

@ -68,7 +68,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/answer_story"
android:text="@string/respond_story"
android:textColor="@color/btn_blue_text_color"
android:visibility="gone"
app:backgroundTint="@color/btn_blue_background" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/quiz"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/story_quiz"
android:textColor="@color/btn_blue_text_color"
android:visibility="gone"
app:backgroundTint="@color/btn_blue_background" />

View File

@ -185,8 +185,10 @@
<string name="updated">感谢阁下更新InstaGrabber</string>
<string name="crash_title">应用崩溃了</string>
<string name="crash_descr">糟糕.. 应用崩溃了,不过别担心,你可以向开发者发送错误报告来帮助他修复问题。(:</string>
<string name="answer_story">回答</string>
<string name="respond_story">回答</string>
<string name="answer_hint">在此回答...</string>
<string name="answered_story">回答完成!</string>
<string name="story_mentions">提及</string>
<string name="story_quiz">测验</string>
<string name="story_quizzed">您已回答!</string>
</resources>

View File

@ -67,9 +67,11 @@
<string name="vote_story_poll">Vote</string>
<string name="votef_story_poll">Vote successful!</string>
<string name="voted_story_poll">You have already voted!</string>
<string name="answer_story">Answer</string>
<string name="respond_story">Respond</string>
<string name="answer_hint">Answer...</string>
<string name="answered_story">Answer successful!</string>
<string name="story_quiz">Quiz</string>
<string name="story_quizzed">You have already answered!</string>
<string name="story_mentions">Mentions</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>

View File

@ -0,0 +1,2 @@
* You can now respond to quizzes, plus you get to see correct answer beforehand (FYI: I will not support music questions)
* Fixed feed story fetch approach