Reporting posts is now available.

This commit is contained in:
Alex Ning 2020-05-05 13:48:42 +08:00
parent 9d451d65dd
commit d444a3a084
9 changed files with 240 additions and 35 deletions

View File

@ -14,6 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout; 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.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -23,11 +26,13 @@ import butterknife.ButterKnife;
import ml.docilealligator.infinityforreddit.Adapter.ReportReasonRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.Adapter.ReportReasonRecyclerViewAdapter;
import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask;
import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.FetchRules;
import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.ReportReason; import ml.docilealligator.infinityforreddit.ReportReason;
import ml.docilealligator.infinityforreddit.ReportThing; import ml.docilealligator.infinityforreddit.ReportThing;
import ml.docilealligator.infinityforreddit.Rule;
import retrofit2.Retrofit; import retrofit2.Retrofit;
public class ReportActivity extends BaseActivity { public class ReportActivity extends BaseActivity {
@ -36,6 +41,8 @@ public class ReportActivity extends BaseActivity {
public static final String EXTRA_THING_FULLNAME = "ETF"; public static final String EXTRA_THING_FULLNAME = "ETF";
private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; private static final String NULL_ACCESS_TOKEN_STATE = "NATS";
private static final String ACCESS_TOKEN_STATE = "ATS"; 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) @BindView(R.id.coordinator_layout_report_activity)
CoordinatorLayout coordinatorLayout; CoordinatorLayout coordinatorLayout;
@ -49,6 +56,9 @@ public class ReportActivity extends BaseActivity {
@Named("oauth") @Named("oauth")
Retrofit mOauthRetrofit; Retrofit mOauthRetrofit;
@Inject @Inject
@Named("no_oauth")
Retrofit mRetrofit;
@Inject
@Named("default") @Named("default")
SharedPreferences mSharedPreferences; SharedPreferences mSharedPreferences;
@Inject @Inject
@ -59,6 +69,8 @@ public class ReportActivity extends BaseActivity {
private String mAccessToken; private String mAccessToken;
private String mFullname; private String mFullname;
private String mSubredditName; private String mSubredditName;
private ArrayList<ReportReason> generalReasons;
private ArrayList<ReportReason> rulesReasons;
private ReportReasonRecyclerViewAdapter mAdapter; private ReportReasonRecyclerViewAdapter mAdapter;
@Override @Override
@ -83,9 +95,6 @@ public class ReportActivity extends BaseActivity {
mFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); mFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME);
mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME);
mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mAdapter);
if (savedInstanceState != null) { if (savedInstanceState != null) {
mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE);
@ -94,9 +103,36 @@ public class ReportActivity extends BaseActivity {
if (!mNullAccessToken && mAccessToken == null) { if (!mNullAccessToken && mAccessToken == null) {
getCurrentAccount(); getCurrentAccount();
} }
generalReasons = savedInstanceState.getParcelableArrayList(GENERAL_REASONS_STATE);
rulesReasons = savedInstanceState.getParcelableArrayList(RULES_REASON_STATE);
} else { } else {
getCurrentAccount(); 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<Rule> 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() { private void getCurrentAccount() {
@ -152,6 +188,10 @@ public class ReportActivity extends BaseActivity {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken);
outState.putString(ACCESS_TOKEN_STATE, mAccessToken); outState.putString(ACCESS_TOKEN_STATE, mAccessToken);
if (mAdapter != null) {
outState.putParcelableArrayList(GENERAL_REASONS_STATE, mAdapter.getGeneralReasons());
outState.putParcelableArrayList(RULES_REASON_STATE, mAdapter.getRules());
}
} }
@Override @Override

View File

@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
@ -22,9 +21,6 @@ import com.google.android.material.appbar.AppBarLayout;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,15 +32,10 @@ import butterknife.ButterKnife;
import ml.docilealligator.infinityforreddit.Adapter.RulesRecyclerViewAdapter; import ml.docilealligator.infinityforreddit.Adapter.RulesRecyclerViewAdapter;
import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent;
import ml.docilealligator.infinityforreddit.FetchRules;
import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditAPI;
import ml.docilealligator.infinityforreddit.Rule; 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; import retrofit2.Retrofit;
public class RulesActivity extends BaseActivity { public class RulesActivity extends BaseActivity {
@ -116,7 +107,26 @@ public class RulesActivity extends BaseActivity {
mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper); mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper);
recyclerView.setAdapter(mAdapter); recyclerView.setAdapter(mAdapter);
fetchRules(); //fetchRules();
FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() {
@Override
public void success(ArrayList<Rule> 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 @Override
@ -137,7 +147,7 @@ public class RulesActivity extends BaseActivity {
errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor());
} }
private void fetchRules() { /*private void fetchRules() {
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.GONE); errorTextView.setVisibility(View.GONE);
@ -175,13 +185,34 @@ public class RulesActivity extends BaseActivity {
displayError(); displayError();
} }
}); });
} }*/
private void displayError() { private void displayError() {
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
errorTextView.setVisibility(View.VISIBLE); errorTextView.setVisibility(View.VISIBLE);
errorTextView.setText(R.string.error_loading_rules); 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<Rule> 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 @Override
@ -205,7 +236,7 @@ public class RulesActivity extends BaseActivity {
finish(); finish();
} }
private static class ParseRulesAsyncTask extends AsyncTask<Void, ArrayList<Rule>, ArrayList<Rule>> { /*private static class ParseRulesAsyncTask extends AsyncTask<Void, ArrayList<Rule>, ArrayList<Rule>> {
private String response; private String response;
private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener;
@ -248,5 +279,5 @@ public class RulesActivity extends BaseActivity {
void parseFailed(); void parseFailed();
} }
} }*/
} }

View File

@ -27,7 +27,6 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
public ReportReasonRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList<ReportReason> generalReasons) { public ReportReasonRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList<ReportReason> generalReasons) {
this.generalReasons = generalReasons; this.generalReasons = generalReasons;
rules = new ArrayList<>();
primaryTextColor = customThemeWrapper.getPrimaryTextColor(); primaryTextColor = customThemeWrapper.getPrimaryTextColor();
colorAccent = customThemeWrapper.getColorAccent(); colorAccent = customThemeWrapper.getColorAccent();
} }
@ -54,7 +53,7 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
@Override @Override
public int getItemCount() { public int getItemCount() {
return rules.size() + generalReasons.size(); return rules == null ? generalReasons.size() : rules.size() + generalReasons.size();
} }
public void setRules(ArrayList<ReportReason> reportReasons) { public void setRules(ArrayList<ReportReason> reportReasons) {
@ -78,6 +77,14 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
return null; return null;
} }
public ArrayList<ReportReason> getGeneralReasons() {
return generalReasons;
}
public ArrayList<ReportReason> getRules() {
return rules;
}
class ReasonViewHolder extends RecyclerView.ViewHolder { class ReasonViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.reason_text_view_item_report_reason) @BindView(R.id.reason_text_view_item_report_reason)
@ -101,12 +108,14 @@ public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
} }
} }
if (rules != null) {
for (int i = 0; i < rules.size(); i++) { for (int i = 0; i < rules.size(); i++) {
if (rules.get(i).isSelected()) { if (rules.get(i).isSelected()) {
rules.get(i).setSelected(false); rules.get(i).setSelected(false);
notifyItemChanged(i + generalReasons.size()); notifyItemChanged(i + generalReasons.size());
} }
} }
}
if (getAdapterPosition() >= generalReasons.size()) { if (getAdapterPosition() >= generalReasons.size()) {
rules.get(getAdapterPosition() - generalReasons.size()).setSelected(checkBox.isChecked()); rules.get(getAdapterPosition() - generalReasons.size()).setSelected(checkBox.isChecked());

View File

@ -0,0 +1,101 @@
package ml.docilealligator.infinityforreddit;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
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 FetchRules {
public interface FetchRulesListener {
void success(ArrayList<Rule> rules);
void failed();
}
public static void fetchRules(Retrofit retrofit, String subredditName, FetchRulesListener fetchRulesListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> rulesCall = api.getRules(subredditName);
rulesCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() {
@Override
public void parseSuccessful(ArrayList<Rule> rules) {
fetchRulesListener.success(rules);
}
@Override
public void parseFailed() {
fetchRulesListener.failed();
}
}).execute();
} else {
fetchRulesListener.failed();
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
fetchRulesListener.failed();
}
});
}
private static class ParseRulesAsyncTask extends AsyncTask<Void, ArrayList<Rule>, ArrayList<Rule>> {
private String response;
private ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener;
ParseRulesAsyncTask(String response, ParseRulesAsyncTask.ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) {
this.response = response;
this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener;
}
@Override
protected ArrayList<Rule> doInBackground(Void... voids) {
try {
JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY);
ArrayList<Rule> 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<Rule> rules) {
if (rules != null) {
parseRulesAsyncTaskListener.parseSuccessful(rules);
} else {
parseRulesAsyncTaskListener.parseFailed();
}
}
interface ParseRulesAsyncTaskListener {
void parseSuccessful(ArrayList<Rule> rules);
void parseFailed();
}
}
}

View File

@ -7,8 +7,12 @@ import android.os.Parcelable;
import java.util.ArrayList; import java.util.ArrayList;
public class ReportReason implements Parcelable { 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_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 reportReason;
private String reasonType; private String reasonType;
@ -68,10 +72,19 @@ public class ReportReason implements Parcelable {
public static ArrayList<ReportReason> getGeneralReasons(Context context) { public static ArrayList<ReportReason> getGeneralReasons(Context context) {
ArrayList<ReportReason> reportReasons = new ArrayList<>(); ArrayList<ReportReason> 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_spam), REASON_TYPE_SITE_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_copyright_issue), REASON_TYPE_SITE_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_child_pornography), REASON_TYPE_SITE_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_abusive_content), REASON_TYPE_SITE_REASON));
return reportReasons;
}
public static ArrayList<ReportReason> convertRulesToReasons(ArrayList<Rule> rules) {
ArrayList<ReportReason> reportReasons = new ArrayList<>();
for (Rule r : rules) {
reportReasons.add(new ReportReason(r.getShortName(), REASON_TYPE_RULE_REASON));
}
return reportReasons; return reportReasons;
} }
} }

View File

@ -26,6 +26,14 @@ public class ReportThing {
params.put(RedditUtils.THING_ID_KEY, thingFullname); params.put(RedditUtils.THING_ID_KEY, thingFullname);
params.put(RedditUtils.SR_NAME_KEY, subredditName); params.put(RedditUtils.SR_NAME_KEY, subredditName);
params.put(reasonType, reason); 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<String>() { oauthRetrofit.create(RedditAPI.class).report(header, params).enqueue(new Callback<String>() {
@Override @Override

View File

@ -84,6 +84,8 @@ public class RedditUtils {
public static final String MULTIPATH_KEY = "multipath"; public static final String MULTIPATH_KEY = "multipath";
public static final String MODEL_KEY = "model"; public static final String MODEL_KEY = "model";
public static final String REASON_KEY = "reason";
public static Map<String, String> getHttpBasicAuthHeader() { public static Map<String, String> getHttpBasicAuthHeader() {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
String credentials = String.format("%s:%s", RedditUtils.CLIENT_ID, ""); String credentials = String.format("%s:%s", RedditUtils.CLIENT_ID, "");

View File

@ -3,7 +3,7 @@
android:id="@+id/linear_layout_exo_playback_control_view" android:id="@+id/linear_layout_exo_playback_control_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="8dp" android:paddingStart="16dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:layout_gravity="bottom"> android:layout_gravity="bottom">

View File

@ -198,6 +198,7 @@
<string name="no_rule">No rule</string> <string name="no_rule">No rule</string>
<string name="error_loading_rules">Error loading rules.\nTap to retry.</string> <string name="error_loading_rules">Error loading rules.\nTap to retry.</string>
<string name="error_loading_rules_without_retry">Error Loading Rules</string>
<string name="search_in">Search in</string> <string name="search_in">Search in</string>
<string name="all_subreddits">All subreddits</string> <string name="all_subreddits">All subreddits</string>
@ -708,9 +709,9 @@
<string name="report_failed">Report failed</string> <string name="report_failed">Report failed</string>
<string name="report_reason_not_selected">You haven\'t selected a reason</string> <string name="report_reason_not_selected">You haven\'t selected a reason</string>
<string name="report_reason_general_spam">Spam</string> <string name="report_reason_general_spam">It Is Spam</string>
<string name="report_reason_general_copyright_issue">Copyright Issue</string> <string name="report_reason_general_copyright_issue">It Contains Copyright Issue</string>
<string name="report_reason_general_child_pornography">Child Pornography</string> <string name="report_reason_general_child_pornography">It Contains Child Pornography</string>
<string name="report_reason_general_abusive_content">Abusive Content</string> <string name="report_reason_general_abusive_content">It Contains Abusive Content</string>
</resources> </resources>