diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java index 19e93481b..978dc9df4 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java @@ -1430,7 +1430,7 @@ public abstract class BaseMainActivity extends BaseActivity }else{ 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); }else{ add_new.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java index 100513648..fadec1e6b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java @@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; import org.json.JSONArray; import org.json.JSONException; @@ -36,6 +35,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; + import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.client.Entities.*; import fr.gouv.etalab.mastodon.client.Entities.Error; @@ -1415,10 +1415,9 @@ public class API { */ public APIResponse getFilters(){ - List filters = new ArrayList<>(); + List filters = null; try { String response = new HttpsConnection(context).get(getAbsoluteUrl("/filters"), 60, null, prefKeyOauthTokenT); - Log.v(Helper.TAG,"resp: " + response); filters = parseFilters(new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); @@ -1446,7 +1445,6 @@ public class API { fr.gouv.etalab.mastodon.client.Entities.Filters filter; try { 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)); filters.add(filter); } catch (HttpsConnection.HttpsConnectionException e) { @@ -1472,14 +1470,22 @@ public class API { */ public APIResponse addFilters(Filters filter){ HashMap params = new HashMap<>(); - params.put("custom_filter[phrase]", filter.getPhrase()); + params.put("phrase", filter.getPhrase()); + StringBuilder parameters = new StringBuilder(); for(String context: filter.getContext()) - params.put("custom_filter[context]", context); - params.put("custom_filter[irreversible]", String.valueOf(filter.isIrreversible())); - params.put("custom_filter[whole_word]", String.valueOf(filter.isWhole_word())); - params.put("custom_filter[expires_in]", String.valueOf(filter.getExpires_in())); + parameters.append("context[]=").append(context).append("&"); + if( parameters.length() > 0) { + parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(10)); + 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 = new ArrayList<>(); 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) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException e) { @@ -1488,7 +1494,10 @@ public class API { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); } + apiResponse.setFilters(filters); return apiResponse; } @@ -1501,7 +1510,7 @@ public class API { try { 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(); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); @@ -1522,14 +1531,22 @@ public class API { */ public APIResponse updateFilters(Filters filter){ HashMap params = new HashMap<>(); - params.put("custom_filter[phrase]", filter.getPhrase()); + params.put("phrase", filter.getPhrase()); + StringBuilder parameters = new StringBuilder(); for(String context: filter.getContext()) - params.put("custom_filter[context]", context); - params.put("custom_filter[irreversible]", String.valueOf(filter.isIrreversible())); - params.put("custom_filter[whole_word]", String.valueOf(filter.isWhole_word())); - params.put("custom_filter[expires_in]", String.valueOf(filter.getExpires_in())); + parameters.append("context[]=").append(context).append("&"); + if( parameters.length() > 0) { + parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(10)); + 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 = new ArrayList<>(); 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) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException e) { @@ -1538,7 +1555,10 @@ public class API { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); } + apiResponse.setFilters(filters); return apiResponse; } @@ -2192,13 +2212,13 @@ public class API { * @param jsonArray JSONArray * @return List of filters */ - private List parseFilters(JSONArray jsonArray){ - List filters = new ArrayList<>(); + private List parseFilters(JSONArray jsonArray){ + List filters = new ArrayList<>(); try { int i = 0; while (i < jsonArray.length() ) { JSONObject resobj = jsonArray.getJSONObject(i); - fr.gouv.etalab.mastodon.client.Entities.Filters filter = parseFilter(resobj); + Filters filter = parseFilter(resobj); filters.add(filter); i++; } @@ -2216,6 +2236,7 @@ public class API { 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(); try { + filter.setId(resobj.get("id").toString()); filter.setPhrase(resobj.get("phrase").toString()); filter.setSetExpires_at(Helper.mstStringToDate(context, resobj.get("expires_at").toString())); filter.setWhole_word(Boolean.parseBoolean(resobj.get("whole_word").toString())); @@ -2233,9 +2254,9 @@ public class API { filter.setContext(finalContext); } } + return filter; + }catch (Exception ignored){ return null;} - }catch (Exception ignored){} - return filter; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/FilterAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/FilterAdapter.java index 95890d846..06a40173b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/FilterAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/FilterAdapter.java @@ -18,6 +18,7 @@ package fr.gouv.etalab.mastodon.drawers; import android.annotation.SuppressLint; import android.content.Context; import android.content.DialogInterface; +import android.content.SharedPreferences; import android.os.AsyncTask; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AlertDialog; @@ -31,12 +32,10 @@ import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.EditText; -import android.widget.Filter; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Spinner; import android.widget.TextView; - +import android.widget.Toast; import java.util.ArrayList; import java.util.List; 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.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Filters; +import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnFilterActionInterface; @@ -158,14 +158,20 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac add_phrase.setText(filter.getPhrase()); if( filter.getContext() != null) for(String val: filter.getContext()){ - if(val.equals("home")) - context_home.setChecked(true); - else if(val.equals("public")) - context_public.setChecked(true); - else if(val.equals("notifications")) - context_notification.setChecked(true); - else if(val.equals("thread")) - context_conversation.setChecked(true); + switch (val) { + case "home": + context_home.setChecked(true); + break; + case "public": + context_public.setChecked(true); + break; + case "notifications": + context_notification.setChecked(true); + break; + case "thread": + context_conversation.setChecked(true); + break; + } } context_whole_word.setChecked(filter.isWhole_word()); context_drop.setChecked(filter.isIrreversible()); @@ -175,7 +181,8 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac public void onClick(DialogInterface dialog, int id) { 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 contextFilter = new ArrayList<>(); if( context_home.isChecked()) contextFilter.add("home"); @@ -185,12 +192,12 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac contextFilter.add("notifications"); if( context_conversation.isChecked()) contextFilter.add("thread"); - filter.setContext(contextFilter); - filter.setExpires_in(expire[0]); - filter.setPhrase(add_phrase.getText().toString()); - filter.setWhole_word(context_whole_word.isChecked()); - filter.setIrreversible(context_drop.isChecked()); - new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.UPDATE_FILTER, filter, FilterAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + filterSent.setContext(contextFilter); + filterSent.setExpires_in(expire[0]); + filterSent.setPhrase(add_phrase.getText().toString()); + filterSent.setWhole_word(context_whole_word.isChecked()); + filterSent.setIrreversible(context_drop.isChecked()); + new ManageFiltersAsyncTask(context, ManageFiltersAsyncTask.action.UPDATE_FILTER, filterSent, FilterAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } dialog.dismiss(); } @@ -219,10 +226,9 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac alertDialog.show(); } }); - - holder.delete_filter.setOnLongClickListener(new View.OnLongClickListener() { + holder.delete_filter.setOnClickListener(new View.OnClickListener() { @Override - public boolean onLongClick(View view) { + public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(context.getString(R.string.action_filter_delete) ); builder.setMessage(context.getString(R.string.action_lists_confirm_delete) ); @@ -245,15 +251,47 @@ public class FilterAdapter extends BaseAdapter implements OnFilterActionInterfac } }) .show(); - return false; } }); return convertView; } + + private Filters getItemAt(int position){ + if( filters.size() > position) + return filters.get(position); + else + return null; + } + @Override 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 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 { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayFiltersFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayFiltersFragment.java index 79f00f728..dade59f1c 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayFiltersFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayFiltersFragment.java @@ -36,11 +36,11 @@ import android.widget.EditText; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Spinner; -import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.activities.MainActivity; @@ -62,10 +62,11 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn private Context context; private AsyncTask asyncTask; private List filters; - private TextView no_action_text; private RelativeLayout mainLoader; private FloatingActionButton add_new; private FilterAdapter filterAdapter; + private RelativeLayout textviewNoAction; + private ListView lv_filters; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -77,16 +78,14 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn filters = new ArrayList<>(); - ListView lv_filters = rootView.findViewById(R.id.lv_filters); - RelativeLayout textviewNoAction = rootView.findViewById(R.id.no_action); - no_action_text = rootView.findViewById(R.id.no_action_text); + lv_filters = rootView.findViewById(R.id.lv_filters); + textviewNoAction = rootView.findViewById(R.id.no_action); mainLoader = rootView.findViewById(R.id.loader); RelativeLayout nextElementLoader = rootView.findViewById(R.id.loading_next_items); mainLoader.setVisibility(View.VISIBLE); nextElementLoader.setVisibility(View.GONE); filterAdapter = new FilterAdapter(context, filters, textviewNoAction); 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); try { 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_drop = dialogView.findViewById(R.id.context_drop); Spinner filter_expire = dialogView.findViewById(R.id.filter_expire); - ArrayAdapter adapterResize = ArrayAdapter.createFromResource(getContext(), + ArrayAdapter adapterResize = ArrayAdapter.createFromResource(Objects.requireNonNull(getContext()), R.array.filter_expire, android.R.layout.simple_spinner_item); filter_expire.setAdapter(adapterResize); final int[] expire = {-1}; @@ -230,20 +229,25 @@ public class DisplayFiltersFragment extends Fragment implements OnFilterActionIn } if( actionType == ManageFiltersAsyncTask.action.GET_ALL_FILTER) { if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) { + this.filters.addAll(apiResponse.getFilters()); filterAdapter.notifyDataSetChanged(); - + textviewNoAction.setVisibility(View.GONE); + lv_filters.setVisibility(View.VISIBLE); } else { - no_action_text.setVisibility(View.VISIBLE); + textviewNoAction.setVisibility(View.VISIBLE); + lv_filters.setVisibility(View.GONE); } }else if( actionType == ManageFiltersAsyncTask.action.CREATE_FILTER){ if (apiResponse.getFilters() != null && apiResponse.getFilters().size() > 0) { - this.filters.add(0, apiResponse.getFilters().get(0)); filterAdapter.notifyDataSetChanged(); + textviewNoAction.setVisibility(View.GONE); + lv_filters.setVisibility(View.VISIBLE); }else{ - Toast.makeText(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show(); + Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show(); } } } + } diff --git a/app/src/main/res/layout/add_filter.xml b/app/src/main/res/layout/add_filter.xml index cf82c1863..3e013b52a 100644 --- a/app/src/main/res/layout/add_filter.xml +++ b/app/src/main/res/layout/add_filter.xml @@ -15,123 +15,128 @@ You should have received a copy of the GNU General Public License along with Mastalab; if not, see . --> - - - - - - - - - - - - - - - - - - - - - - - + + - + + android:maxLines="1" + /> + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file