diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/SearchResultActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/SearchResultActivity.java index 82a661e4d..2cab4fc4d 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/SearchResultActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/SearchResultActivity.java @@ -24,10 +24,14 @@ import android.view.View; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Toast; + +import java.util.ArrayList; import java.util.List; import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAsyncTask; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveTootsAsyncTask; +import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Results; @@ -35,7 +39,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.drawers.SearchListAdapter; import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchInterface; - +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchStatusInterface; /** @@ -43,7 +47,7 @@ import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchInterface; * Show search results within two tabs: Toots and accounts */ -public class SearchResultActivity extends AppCompatActivity implements OnRetrieveSearchInterface { +public class SearchResultActivity extends AppCompatActivity implements OnRetrieveSearchInterface, OnRetrieveSearchStatusInterface { private String search; @@ -68,8 +72,11 @@ public class SearchResultActivity extends AppCompatActivity implements OnRetriev Bundle b = getIntent().getExtras(); if(b != null){ search = b.getString("search"); - if( search != null) + boolean tootOnly = b.getBoolean("tootOnly", false); + if( !tootOnly && search != null) new RetrieveSearchAsyncTask(getApplicationContext(), search.trim(), SearchResultActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + else if(tootOnly) + new RetrieveTootsAsyncTask(getApplicationContext(), search.trim(), SearchResultActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); else Toast.makeText(this,R.string.toast_error_search,Toast.LENGTH_LONG).show(); }else{ @@ -124,5 +131,23 @@ public class SearchResultActivity extends AppCompatActivity implements OnRetriev } + @Override + public void onRetrieveSearchStatus(APIResponse apiResponse, Error error) { + loader.setVisibility(View.GONE); + if( apiResponse.getError() != null){ + final SharedPreferences sharedpreferences = 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(getApplicationContext(), error.getError(),Toast.LENGTH_LONG).show(); + return; + } + lv_search.setVisibility(View.VISIBLE); + List tags = new ArrayList<>(); + List accounts = new ArrayList<>(); + List statuses = apiResponse.getStatuses(); + SearchListAdapter searchListAdapter = new SearchListAdapter(SearchResultActivity.this, statuses, accounts, tags); + lv_search.setAdapter(searchListAdapter); + searchListAdapter.notifyDataSetChanged(); + } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveTootsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveTootsAsyncTask.java new file mode 100644 index 000000000..011445717 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveTootsAsyncTask.java @@ -0,0 +1,59 @@ +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ +package fr.gouv.etalab.mastodon.asynctasks; + +import android.content.Context; +import android.os.AsyncTask; + +import java.lang.ref.WeakReference; + +import fr.gouv.etalab.mastodon.client.API; +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchStatusInterface; + + +/** + * Created by Thomas on 22/11/2017. + * Retrieves toots from search + */ + +public class RetrieveTootsAsyncTask extends AsyncTask { + + private String query; + private APIResponse apiResponse; + private OnRetrieveSearchStatusInterface listener; + private API api; + private WeakReference contextReference; + + public RetrieveTootsAsyncTask(Context context, String query, OnRetrieveSearchStatusInterface onRetrieveSearchStatusInterface){ + this.contextReference = new WeakReference<>(context); + this.query = query; + this.listener = onRetrieveSearchStatusInterface; + } + + + @Override + protected Void doInBackground(Void... params) { + api = new API(this.contextReference.get()); + apiResponse = api.searchStatus(query, 40); + return null; + } + + @Override + protected void onPostExecute(Void result) { + listener.onRetrieveSearchStatus(apiResponse, api.getError()); + } + +} 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 64b17941c..b7a52e612 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 @@ -1133,6 +1133,39 @@ public class API { return apiResponse; } + + /** + * Retrieves Accounts when searching (ie: via @...) *synchronously* + * + * @param query String search + * @return APIResponse + */ + public APIResponse searchStatus(String query, int count) { + + HashMap params = new HashMap<>(); + params.put("q", query); + if( count < 5) + count = 5; + if( count > 40 ) + count = 40; + params.put("limit", String.valueOf(count)); + + try { + HttpsConnection httpsConnection = new HttpsConnection(); + String response = httpsConnection.get(getAbsoluteUrl("/statuses/search"), 60, params, null); + statuses = parseStatuses(new JSONArray(response)); + apiResponse.setSince_id(httpsConnection.getSince_id()); + apiResponse.setMax_id(httpsConnection.getMax_id()); + } catch (HttpsConnection.HttpsConnectionException e) { + setError(e.getStatusCode(), e); + }catch (Exception e) { + setDefaultError(); + e.printStackTrace(); + } + apiResponse.setStatuses(statuses); + return apiResponse; + } + /** * Parse json response an unique account * @param resobj JSONObject diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/SearchTootsListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/SearchTootsListAdapter.java index 3d5ae9f35..515d95ea8 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/SearchTootsListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/SearchTootsListAdapter.java @@ -16,14 +16,22 @@ package fr.gouv.etalab.mastodon.drawers; import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.database.sqlite.SQLiteDatabase; +import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import android.widget.LinearLayout; import android.widget.TextView; import java.util.List; import fr.gouv.etalab.mastodon.R; +import fr.gouv.etalab.mastodon.activities.SearchResultActivity; +import fr.gouv.etalab.mastodon.sqlite.SearchDAO; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; /** @@ -34,10 +42,14 @@ public class SearchTootsListAdapter extends BaseAdapter { private List searches; private LayoutInflater layoutInflater; + private Context context; + private SearchTootsListAdapter searchTootsListAdapter; public SearchTootsListAdapter(Context context, List searches){ this.searches = searches; layoutInflater = LayoutInflater.from(context); + this.context = context; + this.searchTootsListAdapter = this; } @Override @@ -59,21 +71,52 @@ public class SearchTootsListAdapter extends BaseAdapter { @Override public View getView(final int position, View convertView, ViewGroup parent) { - final String tag = searches.get(position); + final String search = searches.get(position); final ViewHolder holder; if (convertView == null) { convertView = layoutInflater.inflate(R.layout.drawer_search, parent, false); holder = new ViewHolder(); holder.search_title = convertView.findViewById(R.id.search_keyword); + holder.search_container = convertView.findViewById(R.id.search_container); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } - holder.search_title.setText(tag); + holder.search_title.setText(search); holder.search_title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + Intent intent = new Intent(context, SearchResultActivity.class); + intent.putExtra("search", search); + intent.putExtra("tootOnly", true); + context.startActivity(intent); + } + }); + final SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + holder.search_container.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.delete + ": " + search); + builder.setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new SearchDAO(context, db).remove(search.trim()); + searches.remove(search); + searchTootsListAdapter.notifyDataSetChanged(); + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .show(); } }); return convertView; @@ -81,6 +124,7 @@ public class SearchTootsListAdapter extends BaseAdapter { private class ViewHolder { + LinearLayout search_container; TextView search_title; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplaySearchFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplaySearchFragment.java index 8b5fec273..7a5f819e7 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplaySearchFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplaySearchFragment.java @@ -23,16 +23,20 @@ import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.ListView; import android.widget.RelativeLayout; + +import java.util.ArrayList; import java.util.List; import fr.gouv.etalab.mastodon.activities.MainActivity; import fr.gouv.etalab.mastodon.drawers.SearchTootsListAdapter; +import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.sqlite.SearchDAO; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.R; @@ -51,7 +55,7 @@ public class DisplaySearchFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_drafts, container, false); + View rootView = inflater.inflate(R.layout.fragment_search, container, false); context = getContext(); final ListView lv_search_toots = rootView.findViewById(R.id.lv_search_toots); @@ -61,11 +65,13 @@ public class DisplaySearchFragment extends Fragment { mainLoader.setVisibility(View.VISIBLE); final SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); List searches = new SearchDAO(context, db).getAllSearch(); - if( searches != null && searches.size() > 0) { - searchTootsListAdapter = new SearchTootsListAdapter(context, searches); - lv_search_toots.setAdapter(searchTootsListAdapter); - searchTootsListAdapter.notifyDataSetChanged(); - }else { + if( searches == null) + searches = new ArrayList<>(); + Log.v(Helper.TAG,"searches: " + searches); + searchTootsListAdapter = new SearchTootsListAdapter(context, searches); + lv_search_toots.setAdapter(searchTootsListAdapter); + searchTootsListAdapter.notifyDataSetChanged(); + if( searches.size() == 0) { textviewNoAction.setVisibility(View.VISIBLE); } mainLoader.setVisibility(View.GONE); @@ -77,43 +83,32 @@ public class DisplaySearchFragment extends Fragment { add_new.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.search); - builder.setIcon(android.R.drawable.ic_menu_search) - .setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogConfirm, int which) { - - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context); - LayoutInflater inflater = getLayoutInflater(); - @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.search_toot, null); - dialogBuilder.setView(dialogView); - final EditText editText = dialogView.findViewById(R.id.search_toot); - dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - String keyword = editText.getText().toString().trim(); - //Already in db - List searches = new SearchDAO(context, db).getSearchByKeyword(keyword); - if( searches.size() > 0){ - return; - } - new SearchDAO(context, db).insertSearch(keyword); - searches.add(keyword); - searchTootsListAdapter.notifyDataSetChanged(); - } - }); - AlertDialog alertDialog = dialogBuilder.create(); - alertDialog.show(); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogConfirm, int which) { - dialogConfirm.dismiss(); - } - }) - .show(); + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context); + LayoutInflater inflater = getLayoutInflater(); + @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.search_toot, null); + dialogBuilder.setView(dialogView); + final EditText editText = dialogView.findViewById(R.id.search_toot); + dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + String keyword = editText.getText().toString().trim(); + //Empty + if( keyword.length() == 0) + return; + //Already in db + List searches = new SearchDAO(context, db).getSearchByKeyword(keyword); + if( searches == null) + searches = new ArrayList<>(); + if( searches.size() > 0){ + return; + } + new SearchDAO(context, db).insertSearch(keyword); + searches.add(keyword); + searchTootsListAdapter.notifyDataSetChanged(); + } + }); + AlertDialog alertDialog = dialogBuilder.create(); + alertDialog.show(); } }); return rootView; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearchStatusInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearchStatusInterface.java new file mode 100644 index 000000000..c531d7c04 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearchStatusInterface.java @@ -0,0 +1,26 @@ +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ +package fr.gouv.etalab.mastodon.interfaces; + +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.client.Entities.Error; + +/** + * Created by Thomas on 22/11/2017. + * Interface for search + */ +public interface OnRetrieveSearchStatusInterface { + void onRetrieveSearchStatus(APIResponse apiResponse, Error error); +} diff --git a/app/src/main/res/layout/drawer_search.xml b/app/src/main/res/layout/drawer_search.xml index 72e6c00d2..33f22f6b7 100644 --- a/app/src/main/res/layout/drawer_search.xml +++ b/app/src/main/res/layout/drawer_search.xml @@ -18,13 +18,12 @@ Live notifications Mit regulären Ausdrücken filtern Suche + Löschen diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 645828d43..7f3a318be 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -441,4 +441,5 @@ Filtrer avec une expression rationnelle Rechercher + Supprimer diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 9d1f62dc1..0ddef77b0 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -437,4 +437,5 @@ Live notifications Wegfilteren met reguliere expressies Zoeken + Verwijderen diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c703743af..7e64a35da 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -439,4 +439,5 @@ Live notifications Filtrar com uma expressão regular Pesquisar + Eliminar diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 739943faf..76cb78368 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -446,4 +446,5 @@ Filter out by regular expressions Search + Delete \ No newline at end of file