From d444a3a084d82b65e41e15282c11694e7cde7d7a Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Tue, 5 May 2020 13:48:42 +0800 Subject: Reporting posts is now available. --- .../infinityforreddit/Activity/ReportActivity.java | 46 +++++++++- .../infinityforreddit/Activity/RulesActivity.java | 63 +++++++++---- .../Adapter/ReportReasonRecyclerViewAdapter.java | 21 +++-- .../infinityforreddit/FetchRules.java | 101 +++++++++++++++++++++ .../infinityforreddit/ReportReason.java | 23 ++++- .../infinityforreddit/ReportThing.java | 8 ++ .../infinityforreddit/Utils/RedditUtils.java | 2 + 7 files changed, 234 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java (limited to 'app/src/main/java/ml/docilealligator/infinityforreddit') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java index 526be6ef..3092b8c7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java @@ -14,6 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; + +import java.util.ArrayList; import javax.inject.Inject; import javax.inject.Named; @@ -23,11 +26,13 @@ import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.Adapter.ReportReasonRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchRules; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.ReportReason; import ml.docilealligator.infinityforreddit.ReportThing; +import ml.docilealligator.infinityforreddit.Rule; import retrofit2.Retrofit; public class ReportActivity extends BaseActivity { @@ -36,6 +41,8 @@ public class ReportActivity extends BaseActivity { public static final String EXTRA_THING_FULLNAME = "ETF"; private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String GENERAL_REASONS_STATE = "GRS"; + private static final String RULES_REASON_STATE = "RRS"; @BindView(R.id.coordinator_layout_report_activity) CoordinatorLayout coordinatorLayout; @@ -49,6 +56,9 @@ public class ReportActivity extends BaseActivity { @Named("oauth") Retrofit mOauthRetrofit; @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject @Named("default") SharedPreferences mSharedPreferences; @Inject @@ -59,6 +69,8 @@ public class ReportActivity extends BaseActivity { private String mAccessToken; private String mFullname; private String mSubredditName; + private ArrayList generalReasons; + private ArrayList rulesReasons; private ReportReasonRecyclerViewAdapter mAdapter; @Override @@ -83,9 +95,6 @@ public class ReportActivity extends BaseActivity { mFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this)); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.setAdapter(mAdapter); if (savedInstanceState != null) { mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); @@ -94,9 +103,36 @@ public class ReportActivity extends BaseActivity { if (!mNullAccessToken && mAccessToken == null) { getCurrentAccount(); } + + generalReasons = savedInstanceState.getParcelableArrayList(GENERAL_REASONS_STATE); + rulesReasons = savedInstanceState.getParcelableArrayList(RULES_REASON_STATE); } else { getCurrentAccount(); } + + if (generalReasons != null) { + mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, generalReasons); + } else { + mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this)); + } + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(mAdapter); + + if (rulesReasons == null) { + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + mAdapter.setRules(ReportReason.convertRulesToReasons(rules)); + } + + @Override + public void failed() { + Snackbar.make(coordinatorLayout, R.string.error_loading_rules_without_retry, Snackbar.LENGTH_SHORT).show(); + } + }); + } else { + mAdapter.setRules(rulesReasons); + } } private void getCurrentAccount() { @@ -152,6 +188,10 @@ public class ReportActivity extends BaseActivity { super.onSaveInstanceState(outState); outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + if (mAdapter != null) { + outState.putParcelableArrayList(GENERAL_REASONS_STATE, mAdapter.getGeneralReasons()); + outState.putParcelableArrayList(RULES_REASON_STATE, mAdapter.getRules()); + } } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java index 925efd0e..2c5cb05c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java @@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit.Activity; import android.content.SharedPreferences; import android.content.res.ColorStateList; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.view.MenuItem; @@ -22,9 +21,6 @@ import com.google.android.material.appbar.AppBarLayout; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import java.util.ArrayList; @@ -36,15 +32,10 @@ import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.Adapter.RulesRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.FetchRules; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditAPI; import ml.docilealligator.infinityforreddit.Rule; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; import retrofit2.Retrofit; public class RulesActivity extends BaseActivity { @@ -116,7 +107,26 @@ public class RulesActivity extends BaseActivity { mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper); recyclerView.setAdapter(mAdapter); - fetchRules(); + //fetchRules(); + + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + progressBar.setVisibility(View.GONE); + if (rules == null || rules.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_rule); + errorTextView.setOnClickListener(view -> { + }); + } + mAdapter.changeDataset(rules); + } + + @Override + public void failed() { + displayError(); + } + }); } @Override @@ -137,7 +147,7 @@ public class RulesActivity extends BaseActivity { errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); } - private void fetchRules() { + /*private void fetchRules() { progressBar.setVisibility(View.VISIBLE); errorTextView.setVisibility(View.GONE); @@ -175,13 +185,34 @@ public class RulesActivity extends BaseActivity { displayError(); } }); - } + }*/ private void displayError() { progressBar.setVisibility(View.GONE); errorTextView.setVisibility(View.VISIBLE); errorTextView.setText(R.string.error_loading_rules); - errorTextView.setOnClickListener(view -> fetchRules()); + errorTextView.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + progressBar.setVisibility(View.GONE); + if (rules == null || rules.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_rule); + errorTextView.setOnClickListener(view -> { + }); + } + mAdapter.changeDataset(rules); + } + + @Override + public void failed() { + displayError(); + } + }); + }); } @Override @@ -205,7 +236,7 @@ public class RulesActivity extends BaseActivity { finish(); } - private static class ParseRulesAsyncTask extends AsyncTask, ArrayList> { + /*private static class ParseRulesAsyncTask extends AsyncTask, ArrayList> { private String response; private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; @@ -248,5 +279,5 @@ public class RulesActivity extends BaseActivity { void parseFailed(); } - } + }*/ } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java index 98db7e3c..8bbc3991 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java @@ -27,7 +27,6 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter generalReasons) { this.generalReasons = generalReasons; - rules = new ArrayList<>(); primaryTextColor = customThemeWrapper.getPrimaryTextColor(); colorAccent = customThemeWrapper.getColorAccent(); } @@ -54,7 +53,7 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter reportReasons) { @@ -78,6 +77,14 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter getGeneralReasons() { + return generalReasons; + } + + public ArrayList getRules() { + return rules; + } + class ReasonViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.reason_text_view_item_report_reason) @@ -101,10 +108,12 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter rules); + void failed(); + } + + public static void fetchRules(Retrofit retrofit, String subredditName, FetchRulesListener fetchRulesListener) { + + RedditAPI api = retrofit.create(RedditAPI.class); + Call rulesCall = api.getRules(subredditName); + rulesCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() { + @Override + public void parseSuccessful(ArrayList rules) { + fetchRulesListener.success(rules); + } + + @Override + public void parseFailed() { + fetchRulesListener.failed(); + } + }).execute(); + } else { + fetchRulesListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchRulesListener.failed(); + } + }); + } + + private static class ParseRulesAsyncTask extends AsyncTask, ArrayList> { + private String response; + private ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; + + ParseRulesAsyncTask(String response, ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) { + this.response = response; + this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener; + } + + @Override + protected ArrayList doInBackground(Void... voids) { + try { + JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY); + ArrayList rules = new ArrayList<>(); + for (int i = 0; i < rulesArray.length(); i++) { + String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); + String description = null; + if (rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) { + description = Utils.modifyMarkdown(rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); + } + rules.add(new Rule(shortName, description)); + } + return rules; + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(ArrayList rules) { + if (rules != null) { + parseRulesAsyncTaskListener.parseSuccessful(rules); + } else { + parseRulesAsyncTaskListener.parseFailed(); + } + } + + interface ParseRulesAsyncTaskListener { + void parseSuccessful(ArrayList rules); + + void parseFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java index a132a17f..cedda1d8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java @@ -7,8 +7,12 @@ import android.os.Parcelable; import java.util.ArrayList; public class ReportReason implements Parcelable { + public static final String REASON_TYPE_SITE_REASON = "site_reason"; public static final String REASON_TYPE_RULE_REASON = "rule_reason"; - public static final String REASON_TYPE_REASON = "reason"; + public static final String REASON_TYPE_OTHER_REASON = "other_reason"; + public static final String REASON_SITE_REASON_SELECTED = "site_reason_selected"; + public static final String REASON_RULE_REASON_SELECTED = "rule_reason_selected"; + public static final String REASON_OTHER = "other"; private String reportReason; private String reasonType; @@ -68,10 +72,19 @@ public class ReportReason implements Parcelable { public static ArrayList getGeneralReasons(Context context) { ArrayList reportReasons = new ArrayList<>(); - reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_spam), REASON_TYPE_REASON)); - reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_copyright_issue), REASON_TYPE_REASON)); - reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_child_pornography), REASON_TYPE_REASON)); - reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_abusive_content), REASON_TYPE_REASON)); + reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_spam), REASON_TYPE_SITE_REASON)); + reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_copyright_issue), REASON_TYPE_SITE_REASON)); + reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_child_pornography), REASON_TYPE_SITE_REASON)); + reportReasons.add(new ReportReason(context.getString(R.string.report_reason_general_abusive_content), REASON_TYPE_SITE_REASON)); + return reportReasons; + } + + public static ArrayList convertRulesToReasons(ArrayList rules) { + ArrayList reportReasons = new ArrayList<>(); + for (Rule r : rules) { + reportReasons.add(new ReportReason(r.getShortName(), REASON_TYPE_RULE_REASON)); + } + return reportReasons; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java index 3d7febfb..8a617179 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java @@ -26,6 +26,14 @@ public class ReportThing { params.put(RedditUtils.THING_ID_KEY, thingFullname); params.put(RedditUtils.SR_NAME_KEY, subredditName); params.put(reasonType, reason); + if (reasonType.equals(ReportReason.REASON_TYPE_SITE_REASON)) { + params.put(RedditUtils.REASON_KEY, ReportReason.REASON_SITE_REASON_SELECTED); + } else if (reasonType.equals(ReportReason.REASON_TYPE_RULE_REASON)) { + params.put(RedditUtils.REASON_KEY, ReportReason.REASON_RULE_REASON_SELECTED); + } else { + params.put(RedditUtils.REASON_KEY, ReportReason.REASON_OTHER); + } + params.put(RedditUtils.API_TYPE_KEY, RedditUtils.API_TYPE_JSON); oauthRetrofit.create(RedditAPI.class).report(header, params).enqueue(new Callback() { @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/RedditUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/RedditUtils.java index 2e7c93c8..b42cbff1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/RedditUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/RedditUtils.java @@ -84,6 +84,8 @@ public class RedditUtils { public static final String MULTIPATH_KEY = "multipath"; public static final String MODEL_KEY = "model"; + public static final String REASON_KEY = "reason"; + public static Map getHttpBasicAuthHeader() { Map params = new HashMap<>(); String credentials = String.format("%s:%s", RedditUtils.CLIENT_ID, ""); -- cgit v1.2.3