diff options
Diffstat (limited to 'app/src/main/java/ml/docilealligator/infinityforreddit')
8 files changed, 451 insertions, 1 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java new file mode 100644 index 00000000..526be6ef --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java @@ -0,0 +1,172 @@ +package ml.docilealligator.infinityforreddit.Activity; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +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.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.ReportReason; +import ml.docilealligator.infinityforreddit.ReportThing; +import retrofit2.Retrofit; + +public class ReportActivity extends BaseActivity { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + 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"; + + @BindView(R.id.coordinator_layout_report_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_report_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_report_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_report_activity) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mFullname; + private String mSubredditName; + private ReportReasonRecyclerViewAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_report); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + 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); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + } else { + getCurrentAccount(); + } + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.report_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_send_report_activity: + ReportReason reportReason = mAdapter.getSelectedReason(); + if (reportReason != null) { + ReportThing.reportThing(mOauthRetrofit, mAccessToken, mFullname, mSubredditName, + reportReason.getReasonType(), reportReason.getReportReason(), new ReportThing.ReportThingListener() { + @Override + public void success() { + Toast.makeText(ReportActivity.this, R.string.report_successful, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void failed() { + Toast.makeText(ReportActivity.this, R.string.report_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + Toast.makeText(ReportActivity.this, R.string.report_reason_not_selected, Toast.LENGTH_SHORT).show(); + } + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + protected SharedPreferences getSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java index 9d8ea8a9..f3e4d0aa 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java @@ -473,6 +473,8 @@ public class ViewPostDetailActivity extends BaseActivity implements FlairBottomS hideItem.setVisible(true); hideItem.setTitle(R.string.action_hide_post); } + + mMenu.findItem(R.id.action_report_view_post_detail_activity).setVisible(true); } else { saveItem.setVisible(false); hideItem.setVisible(false); @@ -622,6 +624,8 @@ public class ViewPostDetailActivity extends BaseActivity implements FlairBottomS hideItem.setVisible(true); hideItem.setTitle(R.string.action_hide_post); } + + mMenu.findItem(R.id.action_report_view_post_detail_activity).setVisible(true); } else { saveItem.setVisible(false); hideItem.setVisible(false); @@ -931,6 +935,8 @@ public class ViewPostDetailActivity extends BaseActivity implements FlairBottomS hideItem.setVisible(true); hideItem.setTitle(R.string.action_hide_post); } + + mMenu.findItem(R.id.action_report_view_post_detail_activity).setVisible(true); } else { saveItem.setVisible(false); hideItem.setVisible(false); @@ -1264,6 +1270,8 @@ public class ViewPostDetailActivity extends BaseActivity implements FlairBottomS hideItem.setVisible(true); hideItem.setTitle(R.string.action_hide_post); } + + mMenu.findItem(R.id.action_report_view_post_detail_activity).setVisible(true); } else { saveItem.setVisible(false); hideItem.setVisible(false); @@ -1481,6 +1489,11 @@ public class ViewPostDetailActivity extends BaseActivity implements FlairBottomS flairBottomSheetFragment.setArguments(bundle); flairBottomSheetFragment.show(getSupportFragmentManager(), flairBottomSheetFragment.getTag()); return true; + case R.id.action_report_view_post_detail_activity: + Intent intent = new Intent(this, ReportActivity.class); + intent.putExtra(ReportActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); + intent.putExtra(ReportActivity.EXTRA_THING_FULLNAME, mPost.getFullName()); + startActivity(intent); case android.R.id.home: onBackPressed(); return true; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java index c474a710..3623fb54 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java @@ -13,7 +13,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; @@ -1849,6 +1848,8 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView PlayerView videoPlayer; @BindView(R.id.mute_exo_playback_control_view) ImageView muteButton; + @BindView(R.id.fullscreen_exo_playback_control_view) + ImageView fullscreenButton; @BindView(R.id.bottom_constraint_layout_item_post_video_type_autoplay) ConstraintLayout bottomConstraintLayout; @BindView(R.id.plus_button_item_post_video_type_autoplay) @@ -1910,6 +1911,19 @@ public class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView } } }); + + fullscreenButton.setOnClickListener(view -> { + Post post = getItem(getAdapterPosition()); + if (post != null) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, post.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, post.getId()); + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, post.getTitle()); + mActivity.startActivity(intent); + } + }); } void bindVideoUri(Uri videoUri) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java new file mode 100644 index 00000000..98db7e3c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java @@ -0,0 +1,121 @@ +package ml.docilealligator.infinityforreddit.Adapter; + +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.ReportReason; + +public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + + private ArrayList<ReportReason> generalReasons; + private ArrayList<ReportReason> rules; + private int primaryTextColor; + private int colorAccent; + + public ReportReasonRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList<ReportReason> generalReasons) { + this.generalReasons = generalReasons; + rules = new ArrayList<>(); + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + colorAccent = customThemeWrapper.getColorAccent(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ReasonViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_report_reason, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ReasonViewHolder) { + ReportReason reportReason; + if (position >= generalReasons.size()) { + reportReason = rules.get(holder.getAdapterPosition() - generalReasons.size()); + } else { + reportReason = generalReasons.get(holder.getAdapterPosition()); + } + ((ReasonViewHolder) holder).reasonTextView.setText(reportReason.getReportReason()); + ((ReasonViewHolder) holder).checkBox.setChecked(reportReason.isSelected()); + } + } + + @Override + public int getItemCount() { + return rules.size() + generalReasons.size(); + } + + public void setRules(ArrayList<ReportReason> reportReasons) { + this.rules = reportReasons; + notifyDataSetChanged(); + } + + public ReportReason getSelectedReason() { + for (ReportReason reportReason : rules) { + if (reportReason.isSelected()) { + return reportReason; + } + } + + for (ReportReason reportReason : generalReasons) { + if (reportReason.isSelected()) { + return reportReason; + } + } + + return null; + } + + class ReasonViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.reason_text_view_item_report_reason) + TextView reasonTextView; + @BindView(R.id.check_box_item_report_reason) + CheckBox checkBox; + + ReasonViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + reasonTextView.setTextColor(primaryTextColor); + checkBox.setButtonTintList(ColorStateList.valueOf(colorAccent)); + + checkBox.setOnClickListener(view -> { + for (int i = 0; i < generalReasons.size(); i++) { + if (generalReasons.get(i).isSelected()) { + generalReasons.get(i).setSelected(false); + notifyItemChanged(i); + + } + } + + for (int i = 0; i < rules.size(); i++) { + if (rules.get(i).isSelected()) { + rules.get(i).setSelected(false); + notifyItemChanged(i + generalReasons.size()); + } + } + + if (getAdapterPosition() >= generalReasons.size()) { + rules.get(getAdapterPosition() - generalReasons.size()).setSelected(checkBox.isChecked()); + } else { + generalReasons.get(getAdapterPosition()).setSelected(checkBox.isChecked()); + } + }); + + itemView.setOnClickListener(view -> checkBox.performClick()); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index d8dcc56e..351ab8f8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -21,6 +21,7 @@ import ml.docilealligator.infinityforreddit.Activity.PostImageActivity; import ml.docilealligator.infinityforreddit.Activity.PostLinkActivity; import ml.docilealligator.infinityforreddit.Activity.PostTextActivity; import ml.docilealligator.infinityforreddit.Activity.PostVideoActivity; +import ml.docilealligator.infinityforreddit.Activity.ReportActivity; import ml.docilealligator.infinityforreddit.Activity.RulesActivity; import ml.docilealligator.infinityforreddit.Activity.SearchActivity; import ml.docilealligator.infinityforreddit.Activity.SearchResultActivity; @@ -161,4 +162,6 @@ public interface AppComponent { void inject(EditMultiRedditActivity editMultiRedditActivity); void inject(SelectedSubredditsActivity selectedSubredditsActivity); + + void inject(ReportActivity reportActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java index 371e31e9..113e1604 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java @@ -304,4 +304,8 @@ public interface RedditAPI { @GET("/api/multi/multipath/") Call<String> getMultiRedditInfo(@HeaderMap Map<String, String> headers, @Query("multipath") String multipath); + + @FormUrlEncoded + @POST("/api/report") + Call<String> report(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java new file mode 100644 index 00000000..a132a17f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportReason.java @@ -0,0 +1,77 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +public class ReportReason implements Parcelable { + public static final String REASON_TYPE_RULE_REASON = "rule_reason"; + public static final String REASON_TYPE_REASON = "reason"; + + private String reportReason; + private String reasonType; + private boolean isSelected; + + public ReportReason(String reportReason, String reasonType) { + this.reportReason = reportReason; + this.reasonType = reasonType; + this.isSelected = false; + } + + protected ReportReason(Parcel in) { + reportReason = in.readString(); + reasonType = in.readString(); + isSelected = in.readByte() != 0; + } + + public static final Creator<ReportReason> CREATOR = new Creator<ReportReason>() { + @Override + public ReportReason createFromParcel(Parcel in) { + return new ReportReason(in); + } + + @Override + public ReportReason[] newArray(int size) { + return new ReportReason[size]; + } + }; + + public String getReportReason() { + return reportReason; + } + + public String getReasonType() { + return reasonType; + } + + public boolean isSelected() { + return isSelected; + } + + public void setSelected(boolean selected) { + isSelected = selected; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(reportReason); + parcel.writeString(reasonType); + parcel.writeByte((byte) (isSelected ? 1 : 0)); + } + + public static ArrayList<ReportReason> getGeneralReasons(Context context) { + 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_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)); + return reportReasons; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java new file mode 100644 index 00000000..3d7febfb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java @@ -0,0 +1,46 @@ +package ml.docilealligator.infinityforreddit; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.Utils.RedditUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class ReportThing { + + public interface ReportThingListener { + void success(); + void failed(); + } + + public static void reportThing(Retrofit oauthRetrofit, String accessToken, String thingFullname, + String subredditName, String reasonType, String reason, + ReportThingListener reportThingListener) { + Map<String, String> header = RedditUtils.getOAuthHeader(accessToken); + Map<String, String> params = new HashMap<>(); + params.put(RedditUtils.THING_ID_KEY, thingFullname); + params.put(RedditUtils.SR_NAME_KEY, subredditName); + params.put(reasonType, reason); + + oauthRetrofit.create(RedditAPI.class).report(header, params).enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + reportThingListener.success(); + } else { + reportThingListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + reportThingListener.failed(); + } + }); + } +}
\ No newline at end of file |