From 15dde36c470ce5b63246793c060c9b2a78f33193 Mon Sep 17 00:00:00 2001 From: Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:20:41 -0400 Subject: Continue adding comment filter. --- .../infinityforreddit/AppComponent.java | 3 + .../CommentFilterPreferenceActivity.java | 2 +- .../activities/CustomizeCommentFilterActivity.java | 245 ++++++++++++++++++++- .../commentfilter/SaveCommentFilter.java | 36 +++ .../layout/activity_customize_comment_filter.xml | 133 ++++++++++- app/src/main/res/values/strings.xml | 2 + 6 files changed, 412 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/commentfilter/SaveCommentFilter.java diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index b4cb2444..2bb4f6ec 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -13,6 +13,7 @@ import ml.docilealligator.infinityforreddit.activities.CommentFilterPreferenceAc import ml.docilealligator.infinityforreddit.activities.CreateMultiRedditActivity; import ml.docilealligator.infinityforreddit.activities.CustomThemeListingActivity; import ml.docilealligator.infinityforreddit.activities.CustomThemePreviewActivity; +import ml.docilealligator.infinityforreddit.activities.CustomizeCommentFilterActivity; import ml.docilealligator.infinityforreddit.activities.CustomizePostFilterActivity; import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; import ml.docilealligator.infinityforreddit.activities.EditCommentActivity; @@ -310,6 +311,8 @@ public interface AppComponent { void inject(CommentFilterPreferenceActivity commentFilterPreferenceActivity); + void inject(CustomizeCommentFilterActivity customizeCommentFilterActivity); + @Component.Factory interface Factory { AppComponent create(@BindsInstance Application application); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentFilterPreferenceActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentFilterPreferenceActivity.java index aaddff6e..170c5335 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentFilterPreferenceActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentFilterPreferenceActivity.java @@ -82,7 +82,7 @@ public class CommentFilterPreferenceActivity extends BaseActivity { public void editCommentFilter(CommentFilter commentFilter) { Intent intent = new Intent(this, CustomizeCommentFilterActivity.class); - intent.putExtra(CustomizeCommentFilterActivity.EXTRA_POST_FILTER, commentFilter); + intent.putExtra(CustomizeCommentFilterActivity.EXTRA_COMMENT_FILTER, commentFilter); intent.putExtra(CustomizeCommentFilterActivity.EXTRA_FROM_SETTINGS, true); startActivity(intent); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeCommentFilterActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeCommentFilterActivity.java index 68a31b6f..6b07e1df 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeCommentFilterActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeCommentFilterActivity.java @@ -1,19 +1,256 @@ package ml.docilealligator.infinityforreddit.activities; +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; -import androidx.appcompat.app.AppCompatActivity; +import androidx.annotation.NonNull; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import java.lang.reflect.Field; +import java.util.concurrent.Executor; +import java.util.regex.PatternSyntaxException; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.commentfilter.CommentFilter; +import ml.docilealligator.infinityforreddit.commentfilter.SaveCommentFilter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.databinding.ActivityCustomizeCommentFilterBinding; +import ml.docilealligator.infinityforreddit.utils.Utils; -public class CustomizeCommentFilterActivity extends AppCompatActivity { +public class CustomizeCommentFilterActivity extends BaseActivity { - public static final String EXTRA_POST_FILTER = "EPF"; + public static final String EXTRA_COMMENT_FILTER = "ECF"; public static final String EXTRA_FROM_SETTINGS = "EFS"; + public static final String RETURN_EXTRA_COMMENT_FILTER = "RECF"; + private static final String COMMENT_FILTER_STATE = "CFS"; + private static final String ORIGINAL_NAME_STATE = "ONS"; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences currentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private CommentFilter commentFilter; + private boolean fromSettings; + private String originalName; + private ActivityCustomizeCommentFilterBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + super.onCreate(savedInstanceState); - setContentView(R.layout.activity_customize_comment_filter); + binding = ActivityCustomizeCommentFilterBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(binding.appbarLayoutCustomizeCommentFilterActivity); + } + + setSupportActionBar(binding.toolbarCustomizeCommentFilterActivity); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(binding.toolbarCustomizeCommentFilterActivity); + + fromSettings = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS, false); + + if (savedInstanceState != null) { + commentFilter = savedInstanceState.getParcelable(COMMENT_FILTER_STATE); + originalName = savedInstanceState.getString(ORIGINAL_NAME_STATE); + } else { + commentFilter = getIntent().getParcelableExtra(EXTRA_COMMENT_FILTER); + if (commentFilter == null) { + commentFilter = new CommentFilter(); + originalName = ""; + } else { + if (!fromSettings) { + originalName = ""; + } else { + originalName = commentFilter.name; + } + } + bindView(); + } + } + + private void bindView() { + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.name); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setText(commentFilter.excludeStrings); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.minVote)); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setText(Integer.toString(commentFilter.maxVote)); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + binding.getRoot().setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(binding.appbarLayoutCustomizeCommentFilterActivity, binding.collapsingToolbarLayoutCustomizeCommentFilterActivity, binding.toolbarCustomizeCommentFilterActivity); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + int primaryIconColor = mCustomThemeWrapper.getPrimaryIconColor(); + Drawable cursorDrawable = Utils.getTintedDrawable(this, R.drawable.edit_text_cursor, primaryTextColor); + binding.nameTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.nameTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.excludeStringsTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.minVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setBoxStrokeColor(primaryTextColor); + binding.maxVoteTextInputLayoutCustomizeCommentFilterActivity.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextColor(primaryTextColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.nameTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.setTextCursorDrawable(cursorDrawable); + } else { + setCursorDrawableColor(binding.nameTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + setCursorDrawableColor(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity, primaryTextColor); + } + + if (typeface != null) { + Utils.setFontToAllTextViews(binding.getRoot(), typeface); + } + } + + public void setCursorDrawableColor(EditText editText, int color) { + try { + Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); + fCursorDrawableRes.setAccessible(true); + int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); + Field fEditor = TextView.class.getDeclaredField("mEditor"); + fEditor.setAccessible(true); + Object editor = fEditor.get(editText); + Class clazz = editor.getClass(); + Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); + fCursorDrawable.setAccessible(true); + Drawable[] drawables = new Drawable[2]; + drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN); + drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); + fCursorDrawable.set(editor, drawables); + } catch (Throwable ignored) { } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.customize_post_filter_activity, menu); + if (fromSettings) { + menu.findItem(R.id.action_save_customize_post_filter_activity).setVisible(false); + } + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } else if (item.getItemId() == R.id.action_save_customize_post_filter_activity) { + try { + constructCommentFilter(); + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } catch (PatternSyntaxException e) { + Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); + } + + return true; + } else if (item.getItemId() == R.id.action_save_to_database_customize_post_filter_activity) { + try { + constructCommentFilter(); + + if (!commentFilter.name.equals("")) { + saveCommentFilter(originalName); + } else { + Toast.makeText(CustomizeCommentFilterActivity.this, R.string.post_filter_requires_a_name, Toast.LENGTH_LONG).show(); + } + } catch (PatternSyntaxException e) { + Toast.makeText(this, R.string.invalid_regex, Toast.LENGTH_SHORT).show(); + } + } + return false; + } + + private void saveCommentFilter(String originalName) { + SaveCommentFilter.saveCommentFilter(mExecutor, new Handler(), mRedditDataRoomDatabase, commentFilter, originalName, + new SaveCommentFilter.SaveCommentFilterListener() { + @Override + public void success() { + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_FILTER, commentFilter); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + + @Override + public void duplicate() { + new MaterialAlertDialogBuilder(CustomizeCommentFilterActivity.this, R.style.MaterialAlertDialogTheme) + .setTitle(getString(R.string.duplicate_post_filter_dialog_title, commentFilter.name)) + .setMessage(R.string.duplicate_post_filter_dialog_message) + .setPositiveButton(R.string.override, (dialogInterface, i) -> saveCommentFilter(commentFilter.name)) + .setNegativeButton(R.string.cancel, null) + .show(); + } + }); + } + + private void constructCommentFilter() throws PatternSyntaxException { + commentFilter.name = binding.nameTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); + commentFilter.maxVote = binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.maxVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); + commentFilter.minVote = binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText() == null || binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString().equals("") ? -1 : Integer.parseInt(binding.minVoteTextInputEditTextCustomizeCommentFilterActivity.getText().toString()); + commentFilter.excludeStrings = binding.excludeStringsTextInputEditTextCustomizeCommentFilterActivity.getText().toString(); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelable(COMMENT_FILTER_STATE, commentFilter); + outState.putString(ORIGINAL_NAME_STATE, originalName); } } \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/commentfilter/SaveCommentFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/commentfilter/SaveCommentFilter.java new file mode 100644 index 00000000..99d8ce6b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/commentfilter/SaveCommentFilter.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.commentfilter; + +import android.os.Handler; + +import java.util.List; +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SaveCommentFilter { + public interface SaveCommentFilterListener { + void success(); + void duplicate(); + } + + public static void saveCommentFilter(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase, + CommentFilter commentFilter, String originalName, SaveCommentFilter.SaveCommentFilterListener saveCommentFilterListener) { + executor.execute(() -> { + if (!originalName.equals(commentFilter.name) && + redditDataRoomDatabase.commentFilterDao().getCommentFilter(commentFilter.name) != null) { + handler.post(saveCommentFilterListener::duplicate); + } else { + List commentFilterUsages = redditDataRoomDatabase.commentFilterUsageDao().getAllCommentFilterUsage(originalName); + if (!originalName.equals(commentFilter.name)) { + redditDataRoomDatabase.commentFilterDao().deleteCommentFilter(originalName); + } + redditDataRoomDatabase.commentFilterDao().insert(commentFilter); + for (CommentFilterUsage commentFilterUsage : commentFilterUsages) { + commentFilterUsage.name = commentFilter.name; + redditDataRoomDatabase.commentFilterUsageDao().insert(commentFilterUsage); + } + handler.post(saveCommentFilterListener::success); + } + }); + } +} diff --git a/app/src/main/res/layout/activity_customize_comment_filter.xml b/app/src/main/res/layout/activity_customize_comment_filter.xml index fc6cbfd9..32022e92 100644 --- a/app/src/main/res/layout/activity_customize_comment_filter.xml +++ b/app/src/main/res/layout/activity_customize_comment_filter.xml @@ -1,9 +1,134 @@ - - + tools:application=".CustomizeCommentFilterActivity"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 33f35339..fbd5f4f0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1157,6 +1157,8 @@ User Leave it blank to apply this post filter to all the subreddits / users / multireddits + Comment Filter Name + You are doing this too frequently. Try again later. This is Reddit API\'s rate limit. Read all messages successfully Unable to read all messages -- cgit v1.2.3