Save post filter to database.

This commit is contained in:
Alex Ning 2020-12-25 15:45:26 +08:00
parent 4ebd10cd8c
commit 265805038d
22 changed files with 378 additions and 131 deletions

View File

@ -11,6 +11,8 @@ import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvicto
import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import java.io.File; import java.io.File;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Named; import javax.inject.Named;
@ -245,4 +247,10 @@ class AppModule {
.build(); .build();
return ToroExo.with(mApplication).getCreator(config); return ToroExo.with(mApplication).getCreator(config);
} }
@Provides
@Singleton
Executor provideExecutor() {
return Executors.newFixedThreadPool(4);
}
} }

View File

@ -1,5 +1,7 @@
package ml.docilealligator.infinityforreddit; package ml.docilealligator.infinityforreddit;
import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
public interface FragmentCommunicator { public interface FragmentCommunicator {
default void refresh() { default void refresh() {
} }

View File

@ -16,6 +16,10 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomTheme;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeDao; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeDao;
import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; import ml.docilealligator.infinityforreddit.multireddit.MultiReddit;
import ml.docilealligator.infinityforreddit.multireddit.MultiRedditDao; import ml.docilealligator.infinityforreddit.multireddit.MultiRedditDao;
import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.postfilter.PostFilterDao;
import ml.docilealligator.infinityforreddit.postfilter.PostFilterUsage;
import ml.docilealligator.infinityforreddit.postfilter.PostFilterUsageDao;
import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.readpost.ReadPost;
import ml.docilealligator.infinityforreddit.readpost.ReadPostDao; import ml.docilealligator.infinityforreddit.readpost.ReadPostDao;
import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery; import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery;
@ -33,7 +37,7 @@ import ml.docilealligator.infinityforreddit.user.UserData;
@Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class, @Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class,
SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class, SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class,
SubredditFilter.class, ReadPost.class}, version = 14) SubredditFilter.class, ReadPost.class, PostFilter.class, PostFilterUsage.class}, version = 15)
public abstract class RedditDataRoomDatabase extends RoomDatabase { public abstract class RedditDataRoomDatabase extends RoomDatabase {
private static RedditDataRoomDatabase INSTANCE; private static RedditDataRoomDatabase INSTANCE;
@ -46,7 +50,7 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5,
MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9,
MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13, MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13,
MIGRATION_13_14) MIGRATION_13_14, MIGRATION_14_15)
.build(); .build();
} }
} }
@ -74,6 +78,10 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
public abstract ReadPostDao readPostDao(); public abstract ReadPostDao readPostDao();
public abstract PostFilterDao postFilterDao();
public abstract PostFilterUsageDao postFilterUsageDao();
private static final Migration MIGRATION_1_2 = new Migration(1, 2) { private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override @Override
public void migrate(SupportSQLiteDatabase database) { public void migrate(SupportSQLiteDatabase database) {
@ -281,4 +289,21 @@ public abstract class RedditDataRoomDatabase extends RoomDatabase {
database.execSQL("ALTER TABLE custom_themes ADD COLUMN read_post_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#F5F5F5") + " NOT NULL"); database.execSQL("ALTER TABLE custom_themes ADD COLUMN read_post_card_view_background_color INTEGER DEFAULT " + Color.parseColor("#F5F5F5") + " NOT NULL");
} }
}; };
private static final Migration MIGRATION_14_15 = new Migration(14, 15) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE post_filter"
+ "(name TEXT NOT NULL PRIMARY KEY, max_vote INTEGER NOT NULL, min_vote INTEGER NOT NULL, " +
"max_comments INTEGER NOT NULL, min_comments INTEGER NOT NULL, max_awards INTEGER NOT NULL, " +
"min_awards INTEGER NOT NULL, only_nsfw INTEGER NOT NULL, only_spoiler INTEGER NOT NULL, " +
"post_title_excludes_regex TEXT, post_title_excludes_strings TEXT, exclude_subreddits TEXT, " +
"exclude_users TEXT, contain_flairs TEXT, exclude_flairs TEXT, contain_text_type INTEGER NOT NULL, " +
"contain_link_type INTEGER NOT NULL, contain_image_type INTEGER NOT NULL, " +
"contain_gif_type INTEGER NOT NULL, contain_video_type INTEGER NOT NULL, " +
"contain_gallery_type INTEGER NOT NULL)");
database.execSQL("CREATE TABLE post_filter_usage (name TEXT NOT NULL, usage INTEGER NOT NULL, " +
"name_of_usage TEXT NOT NULL, PRIMARY KEY(name, usage, name_of_usage), FOREIGN KEY(name) REFERENCES post_filter(name) ON DELETE CASCADE)");
}
};
} }

View File

@ -154,8 +154,8 @@ public class CustomThemeListingActivity extends BaseActivity implements
@Override @Override
public void changeName(String oldThemeName) { public void changeName(String oldThemeName) {
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_name, null);
EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_name_dialog);
themeNameEditText.setText(oldThemeName); themeNameEditText.setText(oldThemeName);
themeNameEditText.requestFocus(); themeNameEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -293,8 +293,8 @@ public class CustomThemeListingActivity extends BaseActivity implements
.setMessage(getString(R.string.duplicate_theme_name_dialog_message, customTheme.name)) .setMessage(getString(R.string.duplicate_theme_name_dialog_message, customTheme.name))
.setPositiveButton(R.string.rename, (dialogInterface, i) .setPositiveButton(R.string.rename, (dialogInterface, i)
-> { -> {
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_name, null);
EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_name_dialog);
themeNameEditText.setText(customTheme.name); themeNameEditText.setText(customTheme.name);
themeNameEditText.requestFocus(); themeNameEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

View File

@ -1,15 +1,21 @@
package ml.docilealligator.infinityforreddit.activities; package ml.docilealligator.infinityforreddit.activities;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
@ -18,21 +24,25 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.switchmaterial.SwitchMaterial; import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.Slidr;
import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.PostFilter;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.postfilter.SavePostFilter;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
public class CustomizePostFilterActivity extends BaseActivity { public class CustomizePostFilterActivity extends BaseActivity {
@ -152,6 +162,8 @@ public class CustomizePostFilterActivity extends BaseActivity {
SharedPreferences mSharedPreferences; SharedPreferences mSharedPreferences;
@Inject @Inject
CustomThemeWrapper mCustomThemeWrapper; CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
private PostFilter postFilter; private PostFilter postFilter;
@Override @Override
@ -223,18 +235,18 @@ public class CustomizePostFilterActivity extends BaseActivity {
} }
private void bindView() { private void bindView() {
postTypeTextCheckBox.setChecked(postFilter.containsTextType); postTypeTextCheckBox.setChecked(postFilter.containTextType);
postTypeLinkCheckBox.setChecked(postFilter.containsLinkType); postTypeLinkCheckBox.setChecked(postFilter.containLinkType);
postTypeImageCheckBox.setChecked(postFilter.containsImageType); postTypeImageCheckBox.setChecked(postFilter.containImageType);
postTypeGifCheckBox.setChecked(postFilter.containsGifType); postTypeGifCheckBox.setChecked(postFilter.containGifType);
postTypeVideoCheckBox.setChecked(postFilter.containsVideoType); postTypeVideoCheckBox.setChecked(postFilter.containVideoType);
postTypeGalleryCheckBox.setChecked(postFilter.containsGalleryType); postTypeGalleryCheckBox.setChecked(postFilter.containGalleryType);
titleExcludesStringsTextInputEditText.setText(postFilter.postTitleExcludesStrings); titleExcludesStringsTextInputEditText.setText(postFilter.postTitleExcludesStrings);
titleExcludesRegexTextInputEditText.setText(postFilter.postTitleExcludesRegex); titleExcludesRegexTextInputEditText.setText(postFilter.postTitleExcludesRegex);
excludesSubredditsTextInputEditText.setText(postFilter.excludesSubreddits); excludesSubredditsTextInputEditText.setText(postFilter.excludeSubreddits);
excludesUsersTextInputEditText.setText(postFilter.excludesUsers); excludesUsersTextInputEditText.setText(postFilter.excludeUsers);
excludesFlairsTextInputEditText.setText(postFilter.excludesFlairs); excludesFlairsTextInputEditText.setText(postFilter.excludeFlairs);
containsFlairsTextInputEditText.setText(postFilter.containsFlairs); containsFlairsTextInputEditText.setText(postFilter.containFlairs);
minVoteTextInputEditText.setText(Integer.toString(postFilter.minVote)); minVoteTextInputEditText.setText(Integer.toString(postFilter.minVote));
maxVoteTextInputEditText.setText(Integer.toString(postFilter.maxVote)); maxVoteTextInputEditText.setText(Integer.toString(postFilter.maxVote));
minCommentsTextInputEditText.setText(Integer.toString(postFilter.minComments)); minCommentsTextInputEditText.setText(Integer.toString(postFilter.minComments));
@ -317,38 +329,95 @@ public class CustomizePostFilterActivity extends BaseActivity {
finish(); finish();
return true; return true;
} else if (item.getItemId() == R.id.action_save_customize_post_filter_activity) { } else if (item.getItemId() == R.id.action_save_customize_post_filter_activity) {
PostFilter postFilter = new PostFilter(); PostFilter postFilter = constructPostFilter();
postFilter.maxVote = maxVoteTextInputEditText.getText() == null || maxVoteTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxVoteTextInputEditText.getText().toString());
postFilter.minVote = minVoteTextInputEditText.getText() == null || minVoteTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minVoteTextInputEditText.getText().toString());
postFilter.maxComments = maxCommentsTextInputEditText.getText() == null || maxCommentsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxCommentsTextInputEditText.getText().toString());
postFilter.minComments = minCommentsTextInputEditText.getText() == null || minCommentsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minCommentsTextInputEditText.getText().toString());
postFilter.maxAwards = maxAwardsTextInputEditText.getText() == null || maxAwardsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxAwardsTextInputEditText.getText().toString());
postFilter.minAwards = minAwardsTextInputEditText.getText() == null || minAwardsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minAwardsTextInputEditText.getText().toString());
postFilter.postTitleExcludesRegex = titleExcludesRegexTextInputEditText.getText().toString();
postFilter.postTitleExcludesStrings = titleExcludesStringsTextInputEditText.getText().toString();
postFilter.excludesSubreddits = excludesSubredditsTextInputEditText.getText().toString();
postFilter.excludesUsers = excludesUsersTextInputEditText.getText().toString();
postFilter.excludesFlairs = excludesUsersTextInputEditText.getText().toString();
postFilter.containsFlairs = containsFlairsTextInputEditText.getText().toString();
postFilter.containsTextType = postTypeTextCheckBox.isChecked();
postFilter.containsLinkType = postTypeLinkCheckBox.isChecked();
postFilter.containsImageType = postTypeImageCheckBox.isChecked();
postFilter.containsGifType = postTypeGifCheckBox.isChecked();
postFilter.containsVideoType = postTypeVideoCheckBox.isChecked();
postFilter.containsGalleryType = postTypeGalleryCheckBox.isChecked();
postFilter.onlyNSFW = onlyNSFWSwitch.isChecked();
postFilter.onlySpoiler = onlySpoilerSwitch.isChecked();
Intent returnIntent = new Intent(); Intent returnIntent = new Intent();
returnIntent.putExtra(RETURN_EXTRA_POST_FILTER, postFilter); returnIntent.putExtra(RETURN_EXTRA_POST_FILTER, postFilter);
setResult(Activity.RESULT_OK, returnIntent); setResult(Activity.RESULT_OK, returnIntent);
finish(); finish();
return true; return true;
} else if (item.getItemId() == R.id.action_save_to_database_customize_post_filter_activity) {
PostFilter postFilter = constructPostFilter();
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_name, null);
EditText nameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_name_dialog);
nameEditText.setHint(R.string.post_filter_name_hint);
nameEditText.setText(postFilter.name);
nameEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme)
.setTitle(R.string.edit_theme_name)
.setView(dialogView)
.setPositiveButton(R.string.ok, (dialogInterface, i)
-> {
if (imm != null) {
imm.hideSoftInputFromWindow(nameEditText.getWindowToken(), 0);
}
if (!nameEditText.getText().toString().equals("")) {
postFilter.name = nameEditText.getText().toString();
Handler handler = new Handler();
SavePostFilter.savePostFilter(mRedditDataRoomDatabase, mExecutor, postFilter, new SavePostFilter.SavePostFilterListener() {
@Override
public void success() {
handler.post(() -> {
Intent returnIntent = new Intent();
returnIntent.putExtra(RETURN_EXTRA_POST_FILTER, postFilter);
setResult(Activity.RESULT_OK, returnIntent);
finish();
});
}
@Override
public void failed(int errorCode) {
handler.post(() -> Toast.makeText(CustomizePostFilterActivity.this, R.string.duplicate_post_filter, Toast.LENGTH_LONG).show());
}
});
}
})
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
if (imm != null) {
imm.hideSoftInputFromWindow(nameEditText.getWindowToken(), 0);
}
})
.setOnDismissListener(dialogInterface -> {
if (imm != null) {
imm.hideSoftInputFromWindow(nameEditText.getWindowToken(), 0);
}
})
.show();
} }
return false; return false;
} }
private PostFilter constructPostFilter() {
PostFilter postFilter = new PostFilter();
postFilter.maxVote = maxVoteTextInputEditText.getText() == null || maxVoteTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxVoteTextInputEditText.getText().toString());
postFilter.minVote = minVoteTextInputEditText.getText() == null || minVoteTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minVoteTextInputEditText.getText().toString());
postFilter.maxComments = maxCommentsTextInputEditText.getText() == null || maxCommentsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxCommentsTextInputEditText.getText().toString());
postFilter.minComments = minCommentsTextInputEditText.getText() == null || minCommentsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minCommentsTextInputEditText.getText().toString());
postFilter.maxAwards = maxAwardsTextInputEditText.getText() == null || maxAwardsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(maxAwardsTextInputEditText.getText().toString());
postFilter.minAwards = minAwardsTextInputEditText.getText() == null || minAwardsTextInputEditText.getText().toString().equals("") ? -1 : Integer.parseInt(minAwardsTextInputEditText.getText().toString());
postFilter.postTitleExcludesRegex = titleExcludesRegexTextInputEditText.getText().toString();
postFilter.postTitleExcludesStrings = titleExcludesStringsTextInputEditText.getText().toString();
postFilter.excludeSubreddits = excludesSubredditsTextInputEditText.getText().toString();
postFilter.excludeUsers = excludesUsersTextInputEditText.getText().toString();
postFilter.excludeFlairs = excludesUsersTextInputEditText.getText().toString();
postFilter.containFlairs = containsFlairsTextInputEditText.getText().toString();
postFilter.containTextType = postTypeTextCheckBox.isChecked();
postFilter.containLinkType = postTypeLinkCheckBox.isChecked();
postFilter.containImageType = postTypeImageCheckBox.isChecked();
postFilter.containGifType = postTypeGifCheckBox.isChecked();
postFilter.containVideoType = postTypeVideoCheckBox.isChecked();
postFilter.containGalleryType = postTypeGalleryCheckBox.isChecked();
postFilter.onlyNSFW = onlyNSFWSwitch.isChecked();
postFilter.onlySpoiler = onlySpoilerSwitch.isChecked();
return postFilter;
}
@Override @Override
protected void onSaveInstanceState(@NonNull Bundle outState) { protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);

View File

@ -33,7 +33,7 @@ import ml.docilealligator.infinityforreddit.ActivityToolbarInterface;
import ml.docilealligator.infinityforreddit.FragmentCommunicator; import ml.docilealligator.infinityforreddit.FragmentCommunicator;
import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.MarkPostAsReadInterface; import ml.docilealligator.infinityforreddit.MarkPostAsReadInterface;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.PostFragmentContentScrollingInterface; import ml.docilealligator.infinityforreddit.PostFragmentContentScrollingInterface;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
@ -170,52 +170,52 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec
postFilter.onlyNSFW = true; postFilter.onlyNSFW = true;
break; break;
case Post.TEXT_TYPE: case Post.TEXT_TYPE:
postFilter.containsTextType = true; postFilter.containTextType = true;
postFilter.containsLinkType = false; postFilter.containLinkType = false;
postFilter.containsImageType = false; postFilter.containImageType = false;
postFilter.containsGifType = false; postFilter.containGifType = false;
postFilter.containsVideoType = false; postFilter.containVideoType = false;
postFilter.containsGalleryType = false; postFilter.containGalleryType = false;
break; break;
case Post.LINK_TYPE: case Post.LINK_TYPE:
postFilter.containsTextType = false; postFilter.containTextType = false;
postFilter.containsLinkType = true; postFilter.containLinkType = true;
postFilter.containsImageType = false; postFilter.containImageType = false;
postFilter.containsGifType = false; postFilter.containGifType = false;
postFilter.containsVideoType = false; postFilter.containVideoType = false;
postFilter.containsGalleryType = false; postFilter.containGalleryType = false;
break; break;
case Post.IMAGE_TYPE: case Post.IMAGE_TYPE:
postFilter.containsTextType = false; postFilter.containTextType = false;
postFilter.containsLinkType = false; postFilter.containLinkType = false;
postFilter.containsImageType = true; postFilter.containImageType = true;
postFilter.containsGifType = false; postFilter.containGifType = false;
postFilter.containsVideoType = false; postFilter.containVideoType = false;
postFilter.containsGalleryType = false; postFilter.containGalleryType = false;
break; break;
case Post.GIF_TYPE: case Post.GIF_TYPE:
postFilter.containsTextType = false; postFilter.containTextType = false;
postFilter.containsLinkType = false; postFilter.containLinkType = false;
postFilter.containsImageType = false; postFilter.containImageType = false;
postFilter.containsGifType = true; postFilter.containGifType = true;
postFilter.containsVideoType = false; postFilter.containVideoType = false;
postFilter.containsGalleryType = false; postFilter.containGalleryType = false;
break; break;
case Post.VIDEO_TYPE: case Post.VIDEO_TYPE:
postFilter.containsTextType = false; postFilter.containTextType = false;
postFilter.containsLinkType = false; postFilter.containLinkType = false;
postFilter.containsImageType = false; postFilter.containImageType = false;
postFilter.containsGifType = false; postFilter.containGifType = false;
postFilter.containsVideoType = true; postFilter.containVideoType = true;
postFilter.containsGalleryType = false; postFilter.containGalleryType = false;
break; break;
case Post.GALLERY_TYPE: case Post.GALLERY_TYPE:
postFilter.containsTextType = false; postFilter.containTextType = false;
postFilter.containsLinkType = false; postFilter.containLinkType = false;
postFilter.containsImageType = false; postFilter.containImageType = false;
postFilter.containsGifType = false; postFilter.containGifType = false;
postFilter.containsVideoType = false; postFilter.containVideoType = false;
postFilter.containsGalleryType = true; postFilter.containGalleryType = true;
break; break;
} }

View File

@ -87,8 +87,8 @@ public class CustomizeThemeRecyclerViewAdapter extends RecyclerView.Adapter<Recy
} else if (holder instanceof ThemeNameItemViewHolder) { } else if (holder instanceof ThemeNameItemViewHolder) {
((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName); ((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName);
holder.itemView.setOnClickListener(view -> { holder.itemView.setOnClickListener(view -> {
View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_name, null);
EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_name_dialog);
themeNameEditText.setText(themeName); themeNameEditText.setText(themeName);
themeNameEditText.requestFocus(); themeNameEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);

View File

@ -66,7 +66,7 @@ import ml.docilealligator.infinityforreddit.ActivityToolbarInterface;
import ml.docilealligator.infinityforreddit.FragmentCommunicator; import ml.docilealligator.infinityforreddit.FragmentCommunicator;
import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.PostFragmentContentScrollingInterface; import ml.docilealligator.infinityforreddit.PostFragmentContentScrollingInterface;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;

View File

@ -14,7 +14,7 @@ import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.readpost.ReadPost;
import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter;
import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.JSONUtils;

View File

@ -11,7 +11,7 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortType;
import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.apis.RedditAPI;
import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.readpost.ReadPost;

View File

@ -9,7 +9,7 @@ import androidx.paging.DataSource;
import java.util.List; import java.util.List;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortType;
import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.readpost.ReadPost;
import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter;

View File

@ -16,7 +16,7 @@ import androidx.paging.PagedList;
import java.util.List; import java.util.List;
import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.NetworkState;
import ml.docilealligator.infinityforreddit.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortType;
import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.readpost.ReadPost;
import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter;

View File

@ -1,35 +1,71 @@
package ml.docilealligator.infinityforreddit; package ml.docilealligator.infinityforreddit.postfilter;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.Post;
@Entity(tableName = "post_filter")
public class PostFilter implements Parcelable { public class PostFilter implements Parcelable {
@PrimaryKey
@NonNull
@ColumnInfo(name = "name")
public String name = "New Filter";
@ColumnInfo(name = "max_vote")
public int maxVote = -1; public int maxVote = -1;
@ColumnInfo(name = "min_vote")
public int minVote = -1; public int minVote = -1;
@ColumnInfo(name = "max_comments")
public int maxComments = -1; public int maxComments = -1;
@ColumnInfo(name = "min_comments")
public int minComments = -1; public int minComments = -1;
@ColumnInfo(name = "max_awards")
public int maxAwards = -1; public int maxAwards = -1;
@ColumnInfo(name = "min_awards")
public int minAwards = -1; public int minAwards = -1;
@Ignore
public boolean allowNSFW; public boolean allowNSFW;
@ColumnInfo(name = "only_nsfw")
public boolean onlyNSFW; public boolean onlyNSFW;
@ColumnInfo(name = "only_spoiler")
public boolean onlySpoiler; public boolean onlySpoiler;
@ColumnInfo(name = "post_title_excludes_regex")
public String postTitleExcludesRegex; public String postTitleExcludesRegex;
@ColumnInfo(name = "post_title_excludes_strings")
public String postTitleExcludesStrings; public String postTitleExcludesStrings;
public String excludesSubreddits; @ColumnInfo(name = "exclude_subreddits")
public String excludesUsers; public String excludeSubreddits;
public String containsFlairs; @ColumnInfo(name = "exclude_users")
public String excludesFlairs; public String excludeUsers;
public boolean containsTextType = true; @ColumnInfo(name = "contain_flairs")
public boolean containsLinkType = true; public String containFlairs;
public boolean containsImageType = true; @ColumnInfo(name = "exclude_flairs")
public boolean containsGifType = true; public String excludeFlairs;
public boolean containsVideoType = true; @ColumnInfo(name = "contain_text_type")
public boolean containsGalleryType = true; public boolean containTextType = true;
@ColumnInfo(name = "contain_link_type")
public boolean containLinkType = true;
@ColumnInfo(name = "contain_image_type")
public boolean containImageType = true;
@ColumnInfo(name = "contain_gif_type")
public boolean containGifType = true;
@ColumnInfo(name = "contain_video_type")
public boolean containVideoType = true;
@ColumnInfo(name = "contain_gallery_type")
public boolean containGalleryType = true;
public PostFilter() {
}
public static boolean isPostAllowed(Post post, PostFilter postFilter) { public static boolean isPostAllowed(Post post, PostFilter postFilter) {
if (postFilter == null || post == null) { if (postFilter == null || post == null) {
@ -62,22 +98,22 @@ public class PostFilter implements Parcelable {
if (postFilter.onlySpoiler && !post.isSpoiler()) { if (postFilter.onlySpoiler && !post.isSpoiler()) {
return false; return false;
} }
if (!postFilter.containsTextType && post.getPostType() == Post.TEXT_TYPE) { if (!postFilter.containTextType && post.getPostType() == Post.TEXT_TYPE) {
return false; return false;
} }
if (!postFilter.containsLinkType && (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE)) { if (!postFilter.containLinkType && (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE)) {
return false; return false;
} }
if (!postFilter.containsImageType && post.getPostType() == Post.IMAGE_TYPE) { if (!postFilter.containImageType && post.getPostType() == Post.IMAGE_TYPE) {
return false; return false;
} }
if (!postFilter.containsGifType && post.getPostType() == Post.GIF_TYPE) { if (!postFilter.containGifType && post.getPostType() == Post.GIF_TYPE) {
return false; return false;
} }
if (!postFilter.containsVideoType && post.getPostType() == Post.VIDEO_TYPE) { if (!postFilter.containVideoType && post.getPostType() == Post.VIDEO_TYPE) {
return false; return false;
} }
if (!postFilter.containsGalleryType && post.getPostType() == Post.GALLERY_TYPE) { if (!postFilter.containGalleryType && post.getPostType() == Post.GALLERY_TYPE) {
return false; return false;
} }
if (postFilter.postTitleExcludesRegex != null && !postFilter.postTitleExcludesRegex.equals("")) { if (postFilter.postTitleExcludesRegex != null && !postFilter.postTitleExcludesRegex.equals("")) {
@ -95,32 +131,32 @@ public class PostFilter implements Parcelable {
} }
} }
} }
if (postFilter.excludesSubreddits != null && !postFilter.excludesSubreddits.equals("")) { if (postFilter.excludeSubreddits != null && !postFilter.excludeSubreddits.equals("")) {
String[] subreddits = postFilter.excludesSubreddits.split(",", 0); String[] subreddits = postFilter.excludeSubreddits.split(",", 0);
for (String s : subreddits) { for (String s : subreddits) {
if (post.getSubredditName().equalsIgnoreCase(s)) { if (post.getSubredditName().equalsIgnoreCase(s)) {
return false; return false;
} }
} }
} }
if (postFilter.excludesUsers != null && !postFilter.excludesUsers.equals("")) { if (postFilter.excludeUsers != null && !postFilter.excludeUsers.equals("")) {
String[] users = postFilter.excludesUsers.split(",", 0); String[] users = postFilter.excludeUsers.split(",", 0);
for (String u : users) { for (String u : users) {
if (post.getAuthor().equalsIgnoreCase(u)) { if (post.getAuthor().equalsIgnoreCase(u)) {
return false; return false;
} }
} }
} }
if (postFilter.excludesFlairs != null && !postFilter.excludesFlairs.equals("")) { if (postFilter.excludeFlairs != null && !postFilter.excludeFlairs.equals("")) {
String[] flairs = postFilter.excludesFlairs.split(",", 0); String[] flairs = postFilter.excludeFlairs.split(",", 0);
for (String f : flairs) { for (String f : flairs) {
if (post.getFlair().equalsIgnoreCase(f)) { if (post.getFlair().equalsIgnoreCase(f)) {
return false; return false;
} }
} }
} }
if (postFilter.containsFlairs != null && !postFilter.containsFlairs.equals("")) { if (postFilter.containFlairs != null && !postFilter.containFlairs.equals("")) {
String[] flairs = postFilter.containsFlairs.split(",", 0); String[] flairs = postFilter.containFlairs.split(",", 0);
for (String f : flairs) { for (String f : flairs) {
if (post.getFlair().equalsIgnoreCase(f)) { if (post.getFlair().equalsIgnoreCase(f)) {
return false; return false;
@ -131,10 +167,6 @@ public class PostFilter implements Parcelable {
return true; return true;
} }
public PostFilter() {
}
protected PostFilter(Parcel in) { protected PostFilter(Parcel in) {
maxVote = in.readInt(); maxVote = in.readInt();
minVote = in.readInt(); minVote = in.readInt();
@ -147,15 +179,15 @@ public class PostFilter implements Parcelable {
onlySpoiler = in.readByte() != 0; onlySpoiler = in.readByte() != 0;
postTitleExcludesRegex = in.readString(); postTitleExcludesRegex = in.readString();
postTitleExcludesStrings = in.readString(); postTitleExcludesStrings = in.readString();
excludesSubreddits = in.readString(); excludeSubreddits = in.readString();
excludesUsers = in.readString(); excludeUsers = in.readString();
containsFlairs = in.readString(); containFlairs = in.readString();
excludesFlairs = in.readString(); excludeFlairs = in.readString();
containsTextType = in.readByte() != 0; containTextType = in.readByte() != 0;
containsLinkType = in.readByte() != 0; containLinkType = in.readByte() != 0;
containsImageType = in.readByte() != 0; containImageType = in.readByte() != 0;
containsVideoType = in.readByte() != 0; containVideoType = in.readByte() != 0;
containsGalleryType = in.readByte() != 0; containGalleryType = in.readByte() != 0;
} }
public static final Creator<PostFilter> CREATOR = new Creator<PostFilter>() { public static final Creator<PostFilter> CREATOR = new Creator<PostFilter>() {
@ -188,14 +220,14 @@ public class PostFilter implements Parcelable {
parcel.writeByte((byte) (onlySpoiler ? 1 : 0)); parcel.writeByte((byte) (onlySpoiler ? 1 : 0));
parcel.writeString(postTitleExcludesRegex); parcel.writeString(postTitleExcludesRegex);
parcel.writeString(postTitleExcludesStrings); parcel.writeString(postTitleExcludesStrings);
parcel.writeString(excludesSubreddits); parcel.writeString(excludeSubreddits);
parcel.writeString(excludesUsers); parcel.writeString(excludeUsers);
parcel.writeString(containsFlairs); parcel.writeString(containFlairs);
parcel.writeString(excludesFlairs); parcel.writeString(excludeFlairs);
parcel.writeByte((byte) (containsTextType ? 1 : 0)); parcel.writeByte((byte) (containTextType ? 1 : 0));
parcel.writeByte((byte) (containsLinkType ? 1 : 0)); parcel.writeByte((byte) (containLinkType ? 1 : 0));
parcel.writeByte((byte) (containsImageType ? 1 : 0)); parcel.writeByte((byte) (containImageType ? 1 : 0));
parcel.writeByte((byte) (containsVideoType ? 1 : 0)); parcel.writeByte((byte) (containVideoType ? 1 : 0));
parcel.writeByte((byte) (containsGalleryType ? 1 : 0)); parcel.writeByte((byte) (containGalleryType ? 1 : 0));
} }
} }

View File

@ -0,0 +1,22 @@
package ml.docilealligator.infinityforreddit.postfilter;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
@Dao
public interface PostFilterDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(PostFilter postFilter);
@Query("DELETE FROM post_filter")
void deleteAllPostFilters();
@Query("SELECT * FROM post_filter WHERE name = :name LIMIT 1")
PostFilter getPostFilter(String name);
@Query("SELECT * FROM post_filter")
LiveData<PostFilter> getAllPostFiltersLiveData();
}

View File

@ -0,0 +1,26 @@
package ml.docilealligator.infinityforreddit.postfilter;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
@Entity(tableName = "post_filter_usage", primaryKeys = {"name", "usage", "name_of_usage"},
foreignKeys = @ForeignKey(entity = PostFilter.class, parentColumns = "name",
childColumns = "name", onDelete = ForeignKey.CASCADE))
public class PostFilterUsage {
@NonNull
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "usage")
public int usage;
@NonNull
@ColumnInfo(name = "name_of_usage")
public String nameOfUsage;
public PostFilterUsage(@NonNull String name, int usage, String nameOfUsage) {
this.name = name;
this.usage = usage;
this.nameOfUsage = nameOfUsage;
}
}

View File

@ -0,0 +1,7 @@
package ml.docilealligator.infinityforreddit.postfilter;
import androidx.room.Dao;
@Dao
public interface PostFilterUsageDao {
}

View File

@ -0,0 +1,27 @@
package ml.docilealligator.infinityforreddit.postfilter;
import java.util.concurrent.Executor;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
public class SavePostFilter {
public static final int ERROR_DUPLICATE_NAME = 1;
public interface SavePostFilterListener {
//Need to make sure it is running in the UI thread.
void success();
void failed(int errorCode);
}
public static void savePostFilter(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor,
PostFilter postFilter, SavePostFilterListener savePostFilterListener) {
executor.execute(() -> {
if (redditDataRoomDatabase.postFilterDao().getPostFilter(postFilter.name) == null) {
redditDataRoomDatabase.postFilterDao().insert(postFilter);
savePostFilterListener.success();
} else {
savePostFilterListener.failed(ERROR_DUPLICATE_NAME);
}
});
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"
android:fillColor="#FFFFFF"/>
</vector>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android" <EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/theme_name_edit_text_edit_theme_name_dialog" android:id="@+id/theme_name_edit_text_edit_name_dialog"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="24dp" android:padding="24dp"

View File

@ -7,4 +7,11 @@
android:title="@string/action_save" android:title="@string/action_save"
android:icon="@drawable/ic_check_circle_toolbar_24dp" android:icon="@drawable/ic_check_circle_toolbar_24dp"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_save_to_database_customize_post_filter_activity"
android:orderInCategory="2"
android:title="@string/action_save_to_database"
android:icon="@drawable/ic_save_to_database_24dp"
app:showAsAction="ifRoom" />
</menu> </menu>

View File

@ -73,6 +73,7 @@
<string name="action_block_user">Block User</string> <string name="action_block_user">Block User</string>
<string name="action_select_user_flair">Select User Flair</string> <string name="action_select_user_flair">Select User Flair</string>
<string name="action_give_award">Give Award</string> <string name="action_give_award">Give Award</string>
<string name="action_save_to_database">Save to Database</string>
<string name="parse_json_response_error">Error occurred when parsing the JSON response</string> <string name="parse_json_response_error">Error occurred when parsing the JSON response</string>
<string name="retrieve_token_error">Error Retrieving the token</string> <string name="retrieve_token_error">Error Retrieving the token</string>
@ -974,5 +975,8 @@
<string name="max_comments_hint">Max comments</string> <string name="max_comments_hint">Max comments</string>
<string name="min_awards_hint">Min awards</string> <string name="min_awards_hint">Min awards</string>
<string name="max_awards_hint">Max awards</string> <string name="max_awards_hint">Max awards</string>
<string name="post_filter_name_hint">Post Filter Name</string>
<string name="duplicate_post_filter">Duplicate post filter found. Please use another name.</string>
</resources> </resources>