default filter list settings android
This commit is contained in:
@@ -910,6 +910,7 @@ brave_java_resources = [
|
||||
"java/res/layout/icon_row_menu_footer.xml",
|
||||
"java/res/layout/item_create_account.xml",
|
||||
"java/res/layout/item_custom_filter.xml",
|
||||
"java/res/layout/item_filter_list.xml",
|
||||
"java/res/layout/item_filter_title.xml",
|
||||
"java/res/layout/item_fragment_two_line_divider_item.xml",
|
||||
"java/res/layout/item_fragment_two_line_item.xml",
|
||||
|
||||
@@ -9,4 +9,5 @@ public interface BraveContentFilteringListener {
|
||||
public void onAddCustomFiltering();
|
||||
public void onCustomFilterToggle(int position, boolean isEnable);
|
||||
public void onCustomFilterDelete(int position);
|
||||
public void onDefaultFilterToggle(String uuid, boolean isEnable);
|
||||
}
|
||||
|
||||
@@ -20,15 +20,23 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.chromium.brave_shields.mojom.SubscriptionInfo;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.mojo_base.mojom.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static int TYPE_CUSTOM_FILTER_HEADER = 1;
|
||||
private static int TYPE_FILTER_HEADER = 1;
|
||||
private static int TYPE_CUSTOM_FILTER_LIST = 2;
|
||||
private static int TYPE_FILTER_LIST = 3;
|
||||
|
||||
private static final int ONE_ITEM_SPACE = 1;
|
||||
private static final int TWO_ITEMS_SPACE = 2;
|
||||
private static final int THREE_ITEMS_SPACE = 3;
|
||||
|
||||
private BraveContentFilteringListener mBraveContentFileringListener;
|
||||
private ArrayList<SubscriptionInfo> mCustomFilterLists;
|
||||
private Value mFilterLists[];
|
||||
private Context mContext;
|
||||
private boolean mIsEdit;
|
||||
|
||||
@@ -40,16 +48,22 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
if (holder instanceof CustomFilterHeaderViewHolder) {
|
||||
CustomFilterHeaderViewHolder customFilterHeaderViewHolder =
|
||||
(CustomFilterHeaderViewHolder) holder;
|
||||
customFilterHeaderViewHolder.titleText.setText(R.string.custom_filter_lists);
|
||||
customFilterHeaderViewHolder.summaryText.setVisibility(View.GONE);
|
||||
if (holder instanceof FilterListHeaderViewHolder) {
|
||||
FilterListHeaderViewHolder filterListHeaderViewHolder =
|
||||
(FilterListHeaderViewHolder) holder;
|
||||
if (holder.getAdapterPosition() == 0) {
|
||||
filterListHeaderViewHolder.titleText.setText(R.string.custom_filter_lists);
|
||||
filterListHeaderViewHolder.summaryText.setVisibility(View.GONE);
|
||||
} else {
|
||||
filterListHeaderViewHolder.titleText.setText(R.string.filter_lists);
|
||||
filterListHeaderViewHolder.summaryText.setText(R.string.filter_lists_summary);
|
||||
filterListHeaderViewHolder.summaryText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else if (holder instanceof CustomFilterListViewHolder) {
|
||||
CustomFilterListViewHolder customFilterListViewHolder =
|
||||
(CustomFilterListViewHolder) holder;
|
||||
|
||||
if (holder.getAdapterPosition() == mCustomFilterLists.size() + 1) {
|
||||
if (holder.getAdapterPosition() == mCustomFilterLists.size() + ONE_ITEM_SPACE) {
|
||||
customFilterListViewHolder.titleText.setText(R.string.add_custom_filter_list);
|
||||
customFilterListViewHolder.lastUpdateText.setVisibility(View.GONE);
|
||||
customFilterListViewHolder.toggleSwitch.setVisibility(View.GONE);
|
||||
@@ -59,7 +73,7 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
|
||||
} else {
|
||||
SubscriptionInfo customFilter =
|
||||
mCustomFilterLists.get(holder.getAdapterPosition() - 1);
|
||||
mCustomFilterLists.get(holder.getAdapterPosition() - ONE_ITEM_SPACE);
|
||||
String url = customFilter.subscriptionUrl.url;
|
||||
if (customFilter.title != null && customFilter.title.length() > 0) {
|
||||
customFilterListViewHolder.titleText.setText(customFilter.title);
|
||||
@@ -118,15 +132,11 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
customFilterListViewHolder.urlText.setText(url);
|
||||
customFilterListViewHolder.toggleSwitch.setChecked(customFilter.enabled);
|
||||
|
||||
customFilterListViewHolder.toggleSwitch.setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
customFilter.enabled = !customFilter.enabled;
|
||||
mBraveContentFileringListener.onCustomFilterToggle(
|
||||
holder.getAdapterPosition() - 1, customFilter.enabled);
|
||||
}
|
||||
});
|
||||
customFilterListViewHolder.toggleSwitch.setOnClickListener(view -> {
|
||||
customFilter.enabled = !customFilter.enabled;
|
||||
mBraveContentFileringListener.onCustomFilterToggle(
|
||||
holder.getAdapterPosition() - ONE_ITEM_SPACE, customFilter.enabled);
|
||||
});
|
||||
|
||||
if (mIsEdit) {
|
||||
customFilterListViewHolder.deleteImageView.setVisibility(View.VISIBLE);
|
||||
@@ -139,7 +149,7 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
customFilterListViewHolder.deleteImageView.setOnClickListener(view -> {
|
||||
if (mIsEdit) {
|
||||
mBraveContentFileringListener.onCustomFilterDelete(
|
||||
holder.getAdapterPosition() - 1);
|
||||
holder.getAdapterPosition() - ONE_ITEM_SPACE);
|
||||
}
|
||||
});
|
||||
customFilterListViewHolder.urlText.setVisibility(View.VISIBLE);
|
||||
@@ -147,60 +157,96 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
}
|
||||
|
||||
customFilterListViewHolder.itemView.setOnClickListener(view -> {
|
||||
if (holder.getAdapterPosition() == mCustomFilterLists.size() + 1) {
|
||||
if (holder.getAdapterPosition() == mCustomFilterLists.size() + ONE_ITEM_SPACE) {
|
||||
mBraveContentFileringListener.onAddCustomFiltering();
|
||||
}
|
||||
});
|
||||
} else if (holder instanceof FilterListViewHolder) {
|
||||
FilterListViewHolder filterListViewHolder = (FilterListViewHolder) holder;
|
||||
int filterPosition = position - mCustomFilterLists.size() - THREE_ITEMS_SPACE;
|
||||
if (filterPosition < mFilterLists.length) {
|
||||
Map<String, Value> storage =
|
||||
mFilterLists[filterPosition].getDictionaryValue().storage;
|
||||
String title = storage.get("title").getStringValue();
|
||||
String description = storage.get("desc").getStringValue();
|
||||
boolean isEnabled = storage.get("enabled").getBoolValue();
|
||||
String uuid = storage.get("uuid").getStringValue();
|
||||
filterListViewHolder.titleText.setText(title);
|
||||
filterListViewHolder.descriptionText.setText(description);
|
||||
filterListViewHolder.toggleSwitch.setChecked(isEnabled);
|
||||
|
||||
filterListViewHolder.toggleSwitch.setOnClickListener(view -> {
|
||||
storage.get("enabled").setBoolValue(!isEnabled);
|
||||
mBraveContentFileringListener.onDefaultFilterToggle(uuid, !isEnabled);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mCustomFilterLists.size() + 2;
|
||||
int count = mCustomFilterLists.size() + THREE_ITEMS_SPACE;
|
||||
if (mFilterLists != null) {
|
||||
count += mFilterLists.length;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
if (viewType == TYPE_CUSTOM_FILTER_HEADER) {
|
||||
|
||||
if (viewType == TYPE_FILTER_HEADER) {
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_filter_title, parent, false);
|
||||
return new CustomFilterHeaderViewHolder(view);
|
||||
} else {
|
||||
return new FilterListHeaderViewHolder(view);
|
||||
} else if (viewType == TYPE_CUSTOM_FILTER_LIST) {
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_custom_filter, parent, false);
|
||||
return new CustomFilterListViewHolder(view);
|
||||
} else {
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_filter_list, parent, false);
|
||||
return new FilterListViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0) {
|
||||
return TYPE_CUSTOM_FILTER_HEADER;
|
||||
} else {
|
||||
if (position == 0 || position == mCustomFilterLists.size() + TWO_ITEMS_SPACE) {
|
||||
return TYPE_FILTER_HEADER;
|
||||
} else if (position > 0 && position <= mCustomFilterLists.size() + ONE_ITEM_SPACE) {
|
||||
return TYPE_CUSTOM_FILTER_LIST;
|
||||
} else {
|
||||
return TYPE_FILTER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
public void setEditable(boolean isEdit) {
|
||||
mIsEdit = isEdit;
|
||||
notifyItemRangeChanged(1, mCustomFilterLists.size());
|
||||
notifyItemRangeChanged(ONE_ITEM_SPACE, mCustomFilterLists.size());
|
||||
}
|
||||
|
||||
public void setCustomFilterLists(ArrayList<SubscriptionInfo> customFilterLists) {
|
||||
if (mCustomFilterLists != null && mCustomFilterLists.size() > 0) {
|
||||
notifyItemRangeRemoved(1, mCustomFilterLists.size());
|
||||
notifyItemRangeRemoved(ONE_ITEM_SPACE, mCustomFilterLists.size());
|
||||
}
|
||||
mCustomFilterLists = customFilterLists;
|
||||
notifyItemRangeInserted(1, mCustomFilterLists.size());
|
||||
notifyItemRangeInserted(ONE_ITEM_SPACE, mCustomFilterLists.size());
|
||||
}
|
||||
|
||||
public static class CustomFilterHeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
public void setFilterLists(Value filterLists[]) {
|
||||
mFilterLists = filterLists;
|
||||
notifyItemRangeInserted(
|
||||
mCustomFilterLists.size() + TWO_ITEMS_SPACE, mFilterLists.length + ONE_ITEM_SPACE);
|
||||
}
|
||||
|
||||
public static class FilterListHeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView titleText;
|
||||
TextView summaryText;
|
||||
|
||||
CustomFilterHeaderViewHolder(View itemView) {
|
||||
FilterListHeaderViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
this.titleText = (TextView) itemView.findViewById(R.id.title_text);
|
||||
this.summaryText = (TextView) itemView.findViewById(R.id.summary_text);
|
||||
@@ -227,4 +273,17 @@ public class ContentFilteringAdapter extends RecyclerView.Adapter<RecyclerView.V
|
||||
this.divider = itemView.findViewById(R.id.divider);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterListViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView titleText;
|
||||
TextView descriptionText;
|
||||
SwitchCompat toggleSwitch;
|
||||
|
||||
FilterListViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
this.titleText = (TextView) itemView.findViewById(R.id.title_text);
|
||||
this.descriptionText = (TextView) itemView.findViewById(R.id.description_text);
|
||||
this.toggleSwitch = (SwitchCompat) itemView.findViewById(R.id.toggle_switch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,19 +31,19 @@ import org.chromium.components.browser_ui.settings.FragmentSettingsLauncher;
|
||||
import org.chromium.components.browser_ui.settings.SettingsLauncher;
|
||||
import org.chromium.mojo.bindings.ConnectionErrorHandler;
|
||||
import org.chromium.mojo.system.MojoException;
|
||||
import org.chromium.mojo_base.mojom.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ContentFilteringFragment extends BravePreferenceFragment
|
||||
implements FragmentSettingsLauncher, BraveContentFilteringListener, ConnectionErrorHandler {
|
||||
private static final int REQUEST_CODE_ADD_CUSTOM_FILTER = 1;
|
||||
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
private ContentFilteringAdapter mAdapter;
|
||||
private FilterListAndroidHandler mFilterListAndroidHandler;
|
||||
private ArrayList<SubscriptionInfo> mCustomFilterLists;
|
||||
private Value mFilterLists[];
|
||||
private MenuItem mEditItem;
|
||||
private MenuItem mDoneItem;
|
||||
private boolean mIsMenuLoaded;
|
||||
@@ -62,7 +62,7 @@ public class ContentFilteringFragment extends BravePreferenceFragment
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().setTitle(R.string.filter_lists_title);
|
||||
getActivity().setTitle(R.string.content_filters_title);
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setData();
|
||||
@@ -89,6 +89,7 @@ public class ContentFilteringFragment extends BravePreferenceFragment
|
||||
mAdapter = new ContentFilteringAdapter(getActivity(), this);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
getCustomFilterLists();
|
||||
getFilterLists();
|
||||
}
|
||||
|
||||
private void getCustomFilterLists() {
|
||||
@@ -104,6 +105,15 @@ public class ContentFilteringFragment extends BravePreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void getFilterLists() {
|
||||
if (mFilterListAndroidHandler != null) {
|
||||
mFilterListAndroidHandler.getFilterLists(filterLists -> {
|
||||
mFilterLists = filterLists.storage;
|
||||
mAdapter.setFilterLists(mFilterLists);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCustomFilterToggle(int position, boolean isEnable) {
|
||||
if (mFilterListAndroidHandler != null) {
|
||||
@@ -135,6 +145,13 @@ public class ContentFilteringFragment extends BravePreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDefaultFilterToggle(String uuid, boolean isEnable) {
|
||||
if (mFilterListAndroidHandler != null) {
|
||||
mFilterListAndroidHandler.enableFilter(uuid, isEnable);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForEmptyCustomFilterLists(boolean shouldEditVisible) {
|
||||
if (mCustomFilterLists.size() == 0) {
|
||||
isEditSelected(false);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
app:layout_constraintEnd_toStartOf="@id/toggle_switch"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:visibility="gone"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/filter_summary_color"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2023 The Brave Authors. All rights reserved.
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/toggle_switch"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/filter_title_color"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_text"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/toggle_switch"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/filter_summary_color"/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/toggle_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="16dp"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/description_text"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@color/filter_divider_color"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -18,7 +18,7 @@
|
||||
android:id="@+id/title_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/filter_title_color"/>
|
||||
|
||||
@@ -512,8 +512,14 @@ This file contains all "about" strings. It is set to NOT be translated, in tran
|
||||
<message name="IDS_CONTENT_FILTERING_SUMMARY" desc="Summary for Content Filtering settings.">
|
||||
Enable custom filters that block regional and language-specific trackers and Annoyances
|
||||
</message>
|
||||
<message name="IDS_FILTER_LISTS_TITLE" desc="Title for Filter Lists settings.">
|
||||
Filter Lists
|
||||
<message name="IDS_CONTENT_FILTERS_TITLE" desc="Title for Content Filters settings.">
|
||||
Content Filters
|
||||
</message>
|
||||
<message name="IDS_FILTER_LISTS" desc="Title for filter lists.">
|
||||
Filter lists
|
||||
</message>
|
||||
<message name="IDS_FILTER_LISTS_SUMMARY" desc="Summary text for Filter lists.">
|
||||
Additional popular community lists. Note that enabling too many filters will degrade browsing speeds.
|
||||
</message>
|
||||
<message name="IDS_CUSTOM_FILTER_LISTS" desc="Title for Custom filter lists.">
|
||||
Custom filter lists
|
||||
|
||||
@@ -288,6 +288,7 @@ base::Value::List AdBlockRegionalServiceManager::GetRegionalLists() {
|
||||
dict.Set("uuid", region_list.uuid);
|
||||
dict.Set("url", region_list.url);
|
||||
dict.Set("title", region_list.title);
|
||||
dict.Set("desc", region_list.desc);
|
||||
dict.Set("support_url", region_list.support_url);
|
||||
dict.Set("component_id", region_list.component_id);
|
||||
dict.Set("base64_public_key", region_list.base64_public_key);
|
||||
|
||||
@@ -54,6 +54,11 @@ void FilterListService::EnableFilter(const std::string& filterListUuid,
|
||||
filterListUuid, shouldEnableFilter);
|
||||
}
|
||||
|
||||
void FilterListService::GetFilterLists(GetFilterListsCallback callback) {
|
||||
std::move(callback).Run(
|
||||
ad_block_service_->regional_service_manager()->GetRegionalLists());
|
||||
}
|
||||
|
||||
void FilterListService::GetSubscriptions(GetSubscriptionsCallback callback) {
|
||||
std::vector<mojom::SubscriptionInfoPtr> items;
|
||||
std::vector<SubscriptionInfo> subscriptions_ =
|
||||
|
||||
@@ -37,6 +37,7 @@ class FilterListService : public KeyedService,
|
||||
void CreateSubscription(const GURL& subscription_url) override;
|
||||
void EnableSubscription(const GURL& sub_url, bool enabled) override;
|
||||
void DeleteSubscription(const GURL& sub_url) override;
|
||||
void GetFilterLists(GetFilterListsCallback callback) override;
|
||||
|
||||
private:
|
||||
raw_ptr<AdBlockService> ad_block_service_ = nullptr;
|
||||
|
||||
@@ -7,6 +7,7 @@ module brave_shields.mojom;
|
||||
|
||||
import "url/mojom/url.mojom";
|
||||
import "mojo/public/mojom/base/time.mojom";
|
||||
import "mojo/public/mojom/base/values.mojom";
|
||||
|
||||
struct SubscriptionInfo {
|
||||
bool enabled;
|
||||
@@ -26,6 +27,7 @@ interface FilterListAndroidHandler {
|
||||
CreateSubscription(url.mojom.Url subscription_url);
|
||||
EnableSubscription(url.mojom.Url sub_url, bool enabled);
|
||||
DeleteSubscription(url.mojom.Url sub_url);
|
||||
GetFilterLists() => (mojo_base.mojom.ListValue filterLists);
|
||||
};
|
||||
|
||||
const string kSwitchToAppUuid = "2F3DCE16-A19A-493C-A88F-2E110FBD37D6";
|
||||
|
||||
Reference in New Issue
Block a user