Manage filters - end

This commit is contained in:
stom79 2018-09-06 18:45:43 +02:00
parent c8545a32b7
commit 3f2d1bcd24
5 changed files with 240 additions and 172 deletions

View File

@ -1430,7 +1430,7 @@ public abstract class BaseMainActivity extends BaseActivity
}else{ }else{
delete_all.setVisibility(View.VISIBLE); delete_all.setVisibility(View.VISIBLE);
} }
if( id != R.id.nav_list){ if( id != R.id.nav_list && id != R.id.nav_filters){
add_new.setVisibility(View.GONE); add_new.setVisibility(View.GONE);
}else{ }else{
add_new.setVisibility(View.VISIBLE); add_new.setVisibility(View.VISIBLE);

View File

@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -36,6 +35,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.client.Entities.*; import fr.gouv.etalab.mastodon.client.Entities.*;
import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Error;
@ -1415,10 +1415,9 @@ public class API {
*/ */
public APIResponse getFilters(){ public APIResponse getFilters(){
List<fr.gouv.etalab.mastodon.client.Entities.Filters> filters = new ArrayList<>(); List<Filters> filters = null;
try { try {
String response = new HttpsConnection(context).get(getAbsoluteUrl("/filters"), 60, null, prefKeyOauthTokenT); String response = new HttpsConnection(context).get(getAbsoluteUrl("/filters"), 60, null, prefKeyOauthTokenT);
Log.v(Helper.TAG,"resp: " + response);
filters = parseFilters(new JSONArray(response)); filters = parseFilters(new JSONArray(response));
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
@ -1446,7 +1445,6 @@ public class API {
fr.gouv.etalab.mastodon.client.Entities.Filters filter; fr.gouv.etalab.mastodon.client.Entities.Filters filter;
try { try {
String response = new HttpsConnection(context).get(getAbsoluteUrl(String.format("/filters/%s", filterId)), 60, null, prefKeyOauthTokenT); String response = new HttpsConnection(context).get(getAbsoluteUrl(String.format("/filters/%s", filterId)), 60, null, prefKeyOauthTokenT);
Log.v(Helper.TAG,"resp: " + response);
filter = parseFilter(new JSONObject(response)); filter = parseFilter(new JSONObject(response));
filters.add(filter); filters.add(filter);
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
@ -1472,14 +1470,22 @@ public class API {
*/ */
public APIResponse addFilters(Filters filter){ public APIResponse addFilters(Filters filter){
HashMap<String, String> params = new HashMap<>(); HashMap<String, String> params = new HashMap<>();
params.put("custom_filter[phrase]", filter.getPhrase()); params.put("phrase", filter.getPhrase());
StringBuilder parameters = new StringBuilder();
for(String context: filter.getContext()) for(String context: filter.getContext())
params.put("custom_filter[context]", context); parameters.append("context[]=").append(context).append("&");
params.put("custom_filter[irreversible]", String.valueOf(filter.isIrreversible())); if( parameters.length() > 0) {
params.put("custom_filter[whole_word]", String.valueOf(filter.isWhole_word())); parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(10));
params.put("custom_filter[expires_in]", String.valueOf(filter.getExpires_in())); params.put("context[]", parameters.toString());
}
params.put("irreversible", String.valueOf(filter.isIrreversible()));
params.put("whole_word", String.valueOf(filter.isWhole_word()));
params.put("expires_in", String.valueOf(filter.getExpires_in()));
ArrayList<Filters> filters = new ArrayList<>();
try { try {
new HttpsConnection(context).post(getAbsoluteUrl("/filters"), 60, params, prefKeyOauthTokenT); String response = new HttpsConnection(context).post(getAbsoluteUrl("/filters"), 60, params, prefKeyOauthTokenT);
Filters resfilter = parseFilter(new JSONObject(response));
filters.add(resfilter);
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
@ -1488,7 +1494,10 @@ public class API {
e.printStackTrace(); e.printStackTrace();
} catch (KeyManagementException e) { } catch (KeyManagementException e) {
e.printStackTrace(); e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} }
apiResponse.setFilters(filters);
return apiResponse; return apiResponse;
} }
@ -1501,7 +1510,7 @@ public class API {
try { try {
HttpsConnection httpsConnection = new HttpsConnection(context); HttpsConnection httpsConnection = new HttpsConnection(context);
new HttpsConnection(context).delete(getAbsoluteUrl(String.format("/filters/%s", filter.getId())), 60, null, prefKeyOauthTokenT); httpsConnection.delete(getAbsoluteUrl(String.format("/filters/%s", filter.getId())), 60, null, prefKeyOauthTokenT);
actionCode = httpsConnection.getActionCode(); actionCode = httpsConnection.getActionCode();
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
@ -1522,14 +1531,22 @@ public class API {
*/ */
public APIResponse updateFilters(Filters filter){ public APIResponse updateFilters(Filters filter){
HashMap<String, String> params = new HashMap<>(); HashMap<String, String> params = new HashMap<>();
params.put("custom_filter[phrase]", filter.getPhrase()); params.put("phrase", filter.getPhrase());
StringBuilder parameters = new StringBuilder();
for(String context: filter.getContext()) for(String context: filter.getContext())
params.put("custom_filter[context]", context); parameters.append("context[]=").append(context).append("&");
params.put("custom_filter[irreversible]", String.valueOf(filter.isIrreversible())); if( parameters.length() > 0) {
params.put("custom_filter[whole_word]", String.valueOf(filter.isWhole_word())); parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(10));
params.put("custom_filter[expires_in]", String.valueOf(filter.getExpires_in())); params.put("context[]", parameters.toString());
}
params.put("irreversible", String.valueOf(filter.isIrreversible()));
params.put("whole_word", String.valueOf(filter.isWhole_word()));
params.put("expires_in", String.valueOf(filter.getExpires_in()));
ArrayList<Filters> filters = new ArrayList<>();
try { try {
new HttpsConnection(context).put(getAbsoluteUrl(String.format("/filters/%s", filter.getId())), 60, params, prefKeyOauthTokenT); String response = new HttpsConnection(context).put(getAbsoluteUrl(String.format("/filters/%s", filter.getId())), 60, params, prefKeyOauthTokenT);
Filters resfilter = parseFilter(new JSONObject(response));
filters.add(resfilter);
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
@ -1538,7 +1555,10 @@ public class API {
e.printStackTrace(); e.printStackTrace();
} catch (KeyManagementException e) { } catch (KeyManagementException e) {
e.printStackTrace(); e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} }
apiResponse.setFilters(filters);
return apiResponse; return apiResponse;
} }
@ -2192,13 +2212,13 @@ public class API {
* @param jsonArray JSONArray * @param jsonArray JSONArray
* @return List<Filters> of filters * @return List<Filters> of filters
*/ */
private List<fr.gouv.etalab.mastodon.client.Entities.Filters> parseFilters(JSONArray jsonArray){ private List<Filters> parseFilters(JSONArray jsonArray){
List<fr.gouv.etalab.mastodon.client.Entities.Filters> filters = new ArrayList<>(); List<Filters> filters = new ArrayList<>();
try { try {
int i = 0; int i = 0;
while (i < jsonArray.length() ) { while (i < jsonArray.length() ) {
JSONObject resobj = jsonArray.getJSONObject(i); JSONObject resobj = jsonArray.getJSONObject(i);
fr.gouv.etalab.mastodon.client.Entities.Filters filter = parseFilter(resobj); Filters filter = parseFilter(resobj);
filters.add(filter); filters.add(filter);
i++; i++;
} }
@ -2216,6 +2236,7 @@ public class API {
private fr.gouv.etalab.mastodon.client.Entities.Filters parseFilter(JSONObject resobj){ private fr.gouv.etalab.mastodon.client.Entities.Filters parseFilter(JSONObject resobj){
fr.gouv.etalab.mastodon.client.Entities.Filters filter = new fr.gouv.etalab.mastodon.client.Entities.Filters(); fr.gouv.etalab.mastodon.client.Entities.Filters filter = new fr.gouv.etalab.mastodon.client.Entities.Filters();
try { try {
filter.setId(resobj.get("id").toString());
filter.setPhrase(resobj.get("phrase").toString()); filter.setPhrase(resobj.get("phrase").toString());
filter.setSetExpires_at(Helper.mstStringToDate(context, resobj.get("expires_at").toString())); filter.setSetExpires_at(Helper.mstStringToDate(context, resobj.get("expires_at").toString()));
filter.setWhole_word(Boolean.parseBoolean(resobj.get("whole_word").toString())); filter.setWhole_word(Boolean.parseBoolean(resobj.get("whole_word").toString()));
@ -2233,9 +2254,9 @@ public class API {
filter.setContext(finalContext); filter.setContext(finalContext);
} }
} }
return filter;
}catch (Exception ignored){ return null;}
}catch (Exception ignored){}
return filter;
} }

View File

@ -18,6 +18,7 @@ package fr.gouv.etalab.mastodon.drawers;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
@ -31,12 +32,10 @@ import android.widget.ArrayAdapter;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
@ -44,6 +43,7 @@ import fr.gouv.etalab.mastodon.activities.BaseMainActivity;
import fr.gouv.etalab.mastodon.asynctasks.ManageFiltersAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.ManageFiltersAsyncTask;
import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Filters; import fr.gouv.etalab.mastodon.client.Entities.Filters;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnFilterActionInterface; import fr.gouv.etalab.mastodon.interfaces.OnFilterActionInterface;
@ -158,14 +158,20 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac
add_phrase.setText(filter.getPhrase()); add_phrase.setText(filter.getPhrase());
if( filter.getContext() != null) if( filter.getContext() != null)
for(String val: filter.getContext()){ for(String val: filter.getContext()){
if(val.equals("home")) switch (val) {
context_home.setChecked(true); case "home":
else if(val.equals("public")) context_home.setChecked(true);
context_public.setChecked(true); break;
else if(val.equals("notifications")) case "public":
context_notification.setChecked(true); context_public.setChecked(true);
else if(val.equals("thread")) break;
context_conversation.setChecked(true); case "notifications":
context_notification.setChecked(true);
break;
case "thread":
context_conversation.setChecked(true);
break;
}
} }
context_whole_word.setChecked(filter.isWhole_word()); context_whole_word.setChecked(filter.isWhole_word());
context_drop.setChecked(filter.isIrreversible()); context_drop.setChecked(filter.isIrreversible());
@ -175,7 +181,8 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
if( add_phrase.getText() != null && add_phrase.getText().toString().trim().length() > 0 ) { if( add_phrase.getText() != null && add_phrase.getText().toString().trim().length() > 0 ) {
Filters filter = new Filters(); Filters filterSent = new Filters();
filterSent.setId(filter.getId());
ArrayList<String> contextFilter = new ArrayList<>(); ArrayList<String> contextFilter = new ArrayList<>();
if( context_home.isChecked()) if( context_home.isChecked())
contextFilter.add("home"); contextFilter.add("home");
@ -185,12 +192,12 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac
contextFilter.add("notifications"); contextFilter.add("notifications");
if( context_conversation.isChecked()) if( context_conversation.isChecked())
contextFilter.add("thread"); contextFilter.add("thread");
filter.setContext(contextFilter); filterSent.setContext(contextFilter);
filter.setExpires_in(expire[0]); filterSent.setExpires_in(expire[0]);
filter.setPhrase(add_phrase.getText().toString()); filterSent.setPhrase(add_phrase.getText().toString());
filter.setWhole_word(context_whole_word.isChecked()); filterSent.setWhole_word(context_whole_word.isChecked());
filter.setIrreversible(context_drop.isChecked()); filterSent.setIrreversible(context_drop.isChecked());
new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.UPDATE_FILTER, filter, FilterAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.UPDATE_FILTER, filterSent, FilterAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
dialog.dismiss(); dialog.dismiss();
} }
@ -219,10 +226,9 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac
alertDialog.show(); alertDialog.show();
} }
}); });
holder.delete_filter.setOnClickListener(new View.OnClickListener() {
holder.delete_filter.setOnLongClickListener(new View.OnLongClickListener() {
@Override @Override
public boolean onLongClick(View view) { public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getString(R.string.action_filter_delete) ); builder.setTitle(context.getString(R.string.action_filter_delete) );
builder.setMessage(context.getString(R.string.action_lists_confirm_delete) ); builder.setMessage(context.getString(R.string.action_lists_confirm_delete) );
@ -245,15 +251,47 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac
} }
}) })
.show(); .show();
return false;
} }
}); });
return convertView; return convertView;
} }
private Filters getItemAt(int position){
if( filters.size() > position)
return filters.get(position);
else
return null;
}
@Override @Override
public void onActionDone(ManageFiltersAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { public void onActionDone(ManageFiltersAsyncTask.action actionType, APIResponse apiResponse, int statusCode) {
if( apiResponse != null) {
if (apiResponse.getError() != null) {
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
if (show_error_messages)
Toast.makeText(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
}
List<Filters> filtersRes = apiResponse.getFilters();
if (filtersRes != null && filtersRes.size() > 0) {
notifyStatusChanged(filtersRes.get(0));
}
}
}
private void notifyStatusChanged(Filters filter){
for (int i = 0; i < filterAdapter.getCount(); i++) {
//noinspection ConstantConditions
if (filterAdapter.getItemAt(i) != null && filterAdapter.getItemAt(i).getId().equals(filter.getId())) {
filters.set(i, filter);
try {
filterAdapter.notifyDataSetChanged();
} catch (Exception ignored) {
}
return;
}
}
} }
private class ViewHolder { private class ViewHolder {

View File

@ -36,11 +36,11 @@ import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.MainActivity; import fr.gouv.etalab.mastodon.activities.MainActivity;
@ -62,10 +62,11 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn
private Context context; private Context context;
private AsyncTask<Void, Void, Void> asyncTask; private AsyncTask<Void, Void, Void> asyncTask;
private List<fr.gouv.etalab.mastodon.client.Entities.Filters> filters; private List<fr.gouv.etalab.mastodon.client.Entities.Filters> filters;
private TextView no_action_text;
private RelativeLayout mainLoader; private RelativeLayout mainLoader;
private FloatingActionButton add_new; private FloatingActionButton add_new;
private FilterAdapter filterAdapter; private FilterAdapter filterAdapter;
private RelativeLayout textviewNoAction;
private ListView lv_filters;
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -77,16 +78,14 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn
filters = new ArrayList<>(); filters = new ArrayList<>();
ListView lv_filters = rootView.findViewById(R.id.lv_filters); lv_filters = rootView.findViewById(R.id.lv_filters);
RelativeLayout textviewNoAction = rootView.findViewById(R.id.no_action); textviewNoAction = rootView.findViewById(R.id.no_action);
no_action_text = rootView.findViewById(R.id.no_action_text);
mainLoader = rootView.findViewById(R.id.loader); mainLoader = rootView.findViewById(R.id.loader);
RelativeLayout nextElementLoader = rootView.findViewById(R.id.loading_next_items); RelativeLayout nextElementLoader = rootView.findViewById(R.id.loading_next_items);
mainLoader.setVisibility(View.VISIBLE); mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE);
filterAdapter = new FilterAdapter(context, filters, textviewNoAction); filterAdapter = new FilterAdapter(context, filters, textviewNoAction);
lv_filters.setAdapter(filterAdapter); lv_filters.setAdapter(filterAdapter);
no_action_text.setVisibility(View.GONE);
asyncTask = new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.GET_ALL_FILTER, null, DisplayFiltersFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); asyncTask = new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.GET_ALL_FILTER, null, DisplayFiltersFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
try { try {
add_new = ((MainActivity) context).findViewById(R.id.add_new); add_new = ((MainActivity) context).findViewById(R.id.add_new);
@ -108,7 +107,7 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn
CheckBox context_whole_word = dialogView.findViewById(R.id.context_whole_word); CheckBox context_whole_word = dialogView.findViewById(R.id.context_whole_word);
CheckBox context_drop = dialogView.findViewById(R.id.context_drop); CheckBox context_drop = dialogView.findViewById(R.id.context_drop);
Spinner filter_expire = dialogView.findViewById(R.id.filter_expire); Spinner filter_expire = dialogView.findViewById(R.id.filter_expire);
ArrayAdapter<CharSequence> adapterResize = ArrayAdapter.createFromResource(getContext(), ArrayAdapter<CharSequence> adapterResize = ArrayAdapter.createFromResource(Objects.requireNonNull(getContext()),
R.array.filter_expire, android.R.layout.simple_spinner_item); R.array.filter_expire, android.R.layout.simple_spinner_item);
filter_expire.setAdapter(adapterResize); filter_expire.setAdapter(adapterResize);
final int[] expire = {-1}; final int[] expire = {-1};
@ -230,20 +229,25 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn
} }
if( actionType == ManageFiltersAsyncTask.action.GET_ALL_FILTER) { if( actionType == ManageFiltersAsyncTask.action.GET_ALL_FILTER) {
if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) { if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) {
this.filters.addAll(apiResponse.getFilters()); this.filters.addAll(apiResponse.getFilters());
filterAdapter.notifyDataSetChanged(); filterAdapter.notifyDataSetChanged();
textviewNoAction.setVisibility(View.GONE);
lv_filters.setVisibility(View.VISIBLE);
} else { } else {
no_action_text.setVisibility(View.VISIBLE); textviewNoAction.setVisibility(View.VISIBLE);
lv_filters.setVisibility(View.GONE);
} }
}else if( actionType == ManageFiltersAsyncTask.action.CREATE_FILTER){ }else if( actionType == ManageFiltersAsyncTask.action.CREATE_FILTER){
if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) { if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) {
this.filters.add(0, apiResponse.getFilters().get(0)); this.filters.add(0, apiResponse.getFilters().get(0));
filterAdapter.notifyDataSetChanged(); filterAdapter.notifyDataSetChanged();
textviewNoAction.setVisibility(View.GONE);
lv_filters.setVisibility(View.VISIBLE);
}else{ }else{
Toast.makeText(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show();
} }
} }
} }
} }

View File

@ -15,123 +15,128 @@
You should have received a copy of the GNU General Public License along with Mastalab; if not, You should have received a copy of the GNU General Public License along with Mastalab; if not,
see <http://www.gnu.org/licenses>. see <http://www.gnu.org/licenses>.
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent" android:layout_width="match_parent"
android:padding="10dp" android:layout_height="wrap_content"
android:layout_height="wrap_content"> >
<TextView <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:orientation="vertical" android:layout_width="match_parent"
android:text="@string/filter_keyword" android:padding="10dp"
android:layout_height="wrap_content" /> android:layout_height="wrap_content">
<TextView
android:textSize="12sp"
android:text="@string/filter_keyword_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/add_phrase"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
/>
<TextView
android:textSize="12sp"
android:text="@string/filter_context"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/filter_context_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/context_home"
android:layout_width="0dp"
android:text="@string/context_home"
android:layout_weight="1"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/context_public"
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/context_public"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/context_notification"
android:layout_width="0dp"
android:text="@string/context_notification"
android:layout_weight="1"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/context_conversation"
android:layout_width="0dp"
android:text="@string/context_conversation"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<CheckBox
android:id="@+id/context_drop"
android:layout_width="match_parent"
android:text="@string/context_drop"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/context_drop_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"/>
<CheckBox
android:id="@+id/context_whole_word"
android:layout_width="match_parent"
android:checked="true"
android:text="@string/context_whole_word"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/context_whole_word_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView <TextView
android:text="@string/filter_expire" android:layout_width="match_parent"
android:layout_width="wrap_content" android:text="@string/filter_keyword"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Spinner <TextView
android:layout_marginStart="30dp" android:textSize="12sp"
android:id="@+id/filter_expire" android:text="@string/filter_keyword_explanations"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/add_phrase"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="30dp" /> android:maxLines="1"
/>
<TextView
android:textSize="12sp"
android:text="@string/filter_context"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/filter_context_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/context_home"
android:layout_width="0dp"
android:text="@string/context_home"
android:layout_weight="1"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/context_public"
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/context_public"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/context_notification"
android:layout_width="0dp"
android:text="@string/context_notification"
android:layout_weight="1"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/context_conversation"
android:layout_width="0dp"
android:text="@string/context_conversation"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<CheckBox
android:id="@+id/context_drop"
android:layout_width="match_parent"
android:text="@string/context_drop"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/context_drop_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"/>
<CheckBox
android:id="@+id/context_whole_word"
android:layout_width="match_parent"
android:checked="true"
android:text="@string/context_whole_word"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:text="@string/context_whole_word_explanations"
android:layout_width="match_parent"
android:textColor="?colorAccent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:text="@string/filter_expire"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Spinner
android:layout_marginStart="30dp"
android:id="@+id/filter_expire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </ScrollView>