From 3ca1e3b402d61ea84ae15d321fe45d73ecbe1864 Mon Sep 17 00:00:00 2001 From: stom79 Date: Sat, 17 Feb 2018 14:43:12 +0100 Subject: [PATCH] Adds filters --- .../activities/OwnerStatusActivity.java | 104 +++++++-- .../asynctasks/RetrieveFeedsAsyncTask.java | 13 +- .../etalab/mastodon/helper/FilterToots.java | 133 +++++++++++ .../mastodon/sqlite/StatusCacheDAO.java | 35 ++- .../main/res/layout/filter_owner_toots.xml | 221 ++++++++++++------ app/src/main/res/values/strings.xml | 9 +- 6 files changed, 405 insertions(+), 110 deletions(-) create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/FilterToots.java diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/OwnerStatusActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/OwnerStatusActivity.java index 82d1d414a..e49accac4 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/OwnerStatusActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/OwnerStatusActivity.java @@ -33,16 +33,17 @@ import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.CheckBox; import android.widget.DatePicker; import android.widget.ImageView; import android.widget.RelativeLayout; +import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; @@ -59,6 +60,7 @@ import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.drawers.StatusListAdapter; +import fr.gouv.etalab.mastodon.helper.FilterToots; import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface; import fr.gouv.etalab.mastodon.services.BackupStatusInDataBaseService; @@ -91,6 +93,8 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds LinearLayoutManager mLayoutManager; private int style; private Button settings_time_from, settings_time_to; + private FilterToots filterToots; + private Date dateIni, dateEnd; @Override protected void onCreate(Bundle savedInstanceState) { @@ -105,6 +109,8 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds } setContentView(R.layout.activity_ower_status); + filterToots = new FilterToots(); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); @@ -181,15 +187,18 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds isRefreshed = false; swipeRefreshLayout = findViewById(R.id.swipeContainer); - new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, RetrieveFeedsAsyncTask.Type.CACHE_STATUS, null, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, filterToots, null, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4, R.color.mastodonC2, R.color.mastodonC3); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { - isRefreshed = true; - new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, RetrieveFeedsAsyncTask.Type.CACHE_STATUS, null, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + max_id = null; + firstLoad = true; + flag_loading = true; + swiped = true; + new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, filterToots, null, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); @@ -203,7 +212,7 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds if(firstVisibleItem + visibleItemCount == totalItemCount ) { if(!flag_loading ) { flag_loading = true; - new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, RetrieveFeedsAsyncTask.Type.CACHE_STATUS, max_id, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, filterToots, max_id, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); nextElementLoader.setVisibility(View.VISIBLE); } } else { @@ -229,6 +238,7 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth, 0, 0); + dateIni = new Date(c.getTimeInMillis()); settings_time_from.setText(Helper.shortDateToString(new Date(c.getTimeInMillis()))); } @@ -240,6 +250,8 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth, 23, 59); + + dateEnd = new Date(c.getTimeInMillis()); settings_time_to.setText(Helper.shortDateToString(new Date(c.getTimeInMillis()))); } @@ -259,36 +271,46 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds LayoutInflater inflater = this.getLayoutInflater(); @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.filter_owner_toots, null); dialogBuilder.setView(dialogView); - dialogBuilder - .setTitle(R.string.action_filter) - .setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - final AlertDialog alertDialog = dialogBuilder.create(); + SQLiteDatabase db = Sqlite.getInstance(OwnerStatusActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); - Date dateInit = new StatusCacheDAO(OwnerStatusActivity.this, db).getSmallerDate(StatusCacheDAO.ARCHIVE_CACHE); - Date dateEnd = new StatusCacheDAO(OwnerStatusActivity.this, db).getGreaterDate(StatusCacheDAO.ARCHIVE_CACHE); - String dateInitString = Helper.shortDateToString(dateInit); + dateIni = new StatusCacheDAO(OwnerStatusActivity.this, db).getSmallerDate(StatusCacheDAO.ARCHIVE_CACHE); + dateEnd = new StatusCacheDAO(OwnerStatusActivity.this, db).getGreaterDate(StatusCacheDAO.ARCHIVE_CACHE); + String dateInitString = Helper.shortDateToString(dateIni); String dateEndString = Helper.shortDateToString(dateEnd); + //Initializes settings for filter settings_time_from = dialogView.findViewById(R.id.settings_time_from); settings_time_to = dialogView.findViewById(R.id.settings_time_to); + final CheckBox filter_visibility_public = dialogView.findViewById(R.id.filter_visibility_public); + final CheckBox filter_visibility_unlisted = dialogView.findViewById(R.id.filter_visibility_unlisted); + final CheckBox filter_visibility_private = dialogView.findViewById(R.id.filter_visibility_private); + CheckBox filter_visibility_direct = dialogView.findViewById(R.id.filter_visibility_direct); + + filter_visibility_public.setChecked(filterToots.isV_public()); + filter_visibility_unlisted.setChecked(filterToots.isV_unlisted()); + filter_visibility_private.setChecked(filterToots.isV_private()); + filter_visibility_direct.setChecked(filterToots.isV_direct()); + + final Spinner filter_boost = dialogView.findViewById(R.id.filter_boost); + final Spinner filter_replies = dialogView.findViewById(R.id.filter_replies); + final Spinner filter_media = dialogView.findViewById(R.id.filter_media); + final Spinner filter_pinned = dialogView.findViewById(R.id.filter_pinned); + + filter_boost.setSelection(filterToots.getBoosts().ordinal()); + filter_replies.setSelection(filterToots.getReplies().ordinal()); + filter_media.setSelection(filterToots.getMedia().ordinal()); + filter_pinned.setSelection(filterToots.getPinned().ordinal()); + + final TextView filter_keywords = dialogView.findViewById(R.id.filter_keywords); + settings_time_from.setText(dateInitString); settings_time_to.setText(dateEndString); + Calendar c = Calendar.getInstance(); - c.setTime(dateInit); + c.setTime(dateIni); int yearIni = c.get(Calendar.YEAR); int monthIni = c.get(Calendar.MONTH); int dayIni = c.get(Calendar.DAY_OF_MONTH); @@ -314,7 +336,41 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds dateEndPickerDialog.show(); } }); + dialogBuilder + .setTitle(R.string.action_filter) + .setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + filterToots.setBoosts(FilterToots.typeFilter.values()[filter_boost.getSelectedItemPosition()]); + filterToots.setReplies(FilterToots.typeFilter.values()[filter_replies.getSelectedItemPosition()]); + filterToots.setMedia(FilterToots.typeFilter.values()[filter_media.getSelectedItemPosition()]); + filterToots.setPinned(FilterToots.typeFilter.values()[filter_pinned.getSelectedItemPosition()]); + filterToots.setV_public(filter_visibility_public.isChecked()); + filterToots.setV_unlisted(filter_visibility_unlisted.isChecked()); + filterToots.setV_private(filter_visibility_private.isChecked()); + filterToots.setV_direct(filter_visibility_public.isChecked()); + + filterToots.setDateIni(Helper.dateToString(OwnerStatusActivity.this,dateIni)); + filterToots.setDateEnd(Helper.dateToString(OwnerStatusActivity.this,dateEnd)); + + filterToots.setFilter(filter_keywords.getText().toString()); + swipeRefreshLayout.setRefreshing(true); + max_id = null; + firstLoad = true; + flag_loading = true; + swiped = true; + new RetrieveFeedsAsyncTask(OwnerStatusActivity.this, filterToots, null, OwnerStatusActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + final AlertDialog alertDialog = dialogBuilder.create(); alertDialog.show(); return true; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java index 12e1cbe93..67e20ee90 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java @@ -24,6 +24,7 @@ import java.util.List; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Status; +import fr.gouv.etalab.mastodon.helper.FilterToots; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.StatusCacheDAO; @@ -46,6 +47,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { private boolean showMediaOnly = false; private boolean showPinned = false; private WeakReference contextReference; + private FilterToots filterToots; public enum Type{ HOME, @@ -62,6 +64,15 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { CACHE_STATUS } + + public RetrieveFeedsAsyncTask(Context context, FilterToots filterToots, String max_id, OnRetrieveFeedsInterface onRetrieveFeedsInterface){ + this.contextReference = new WeakReference<>(context); + this.action = Type.CACHE_STATUS; + this.max_id = max_id; + this.listener = onRetrieveFeedsInterface; + this.filterToots = filterToots; + } + public RetrieveFeedsAsyncTask(Context context, Type action, String max_id, OnRetrieveFeedsInterface onRetrieveFeedsInterface){ this.contextReference = new WeakReference<>(context); this.action = action; @@ -127,7 +138,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { case CACHE_STATUS: apiResponse = new APIResponse(); db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); - statuses = new StatusCacheDAO(contextReference.get(), db).getStatusFromID(StatusCacheDAO.ARCHIVE_CACHE, max_id); + statuses = new StatusCacheDAO(contextReference.get(), db).getStatusFromID(StatusCacheDAO.ARCHIVE_CACHE, filterToots, max_id); if( statuses != null && statuses.size() > 0) { apiResponse.setStatuses(statuses); apiResponse.setMax_id(statuses.get(0).getId()); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/FilterToots.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/FilterToots.java new file mode 100644 index 000000000..d32fdcb02 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/FilterToots.java @@ -0,0 +1,133 @@ +/* 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.helper; + +/** + * Created by Thomas on 17/02/2018. + * Helper class for filtering toots + */ + +public class FilterToots { + + public enum typeFilter{ + NONE, + ONLY, + BOTH + } + + private typeFilter pinned = typeFilter.BOTH; + private typeFilter boosts = typeFilter.BOTH; + private typeFilter replies = typeFilter.BOTH; + private typeFilter media = typeFilter.BOTH; + + private boolean v_public = true; + private boolean v_unlisted = true; + private boolean v_direct = true; + private boolean v_private = true; + + private String filter = null; + + + private String dateIni = null; + private String dateEnd = null; + + public typeFilter getPinned() { + return pinned; + } + + public void setPinned(typeFilter pinned) { + this.pinned = pinned; + } + + public typeFilter getBoosts() { + return boosts; + } + + public void setBoosts(typeFilter boosts) { + this.boosts = boosts; + } + + public typeFilter getReplies() { + return replies; + } + + public void setReplies(typeFilter replies) { + this.replies = replies; + } + + public typeFilter getMedia() { + return media; + } + + public void setMedia(typeFilter media) { + this.media = media; + } + + public boolean isV_public() { + return v_public; + } + + public void setV_public(boolean v_public) { + this.v_public = v_public; + } + + public boolean isV_unlisted() { + return v_unlisted; + } + + public void setV_unlisted(boolean v_unlisted) { + this.v_unlisted = v_unlisted; + } + + public boolean isV_direct() { + return v_direct; + } + + public void setV_direct(boolean v_direct) { + this.v_direct = v_direct; + } + + public boolean isV_private() { + return v_private; + } + + public void setV_private(boolean v_private) { + this.v_private = v_private; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + + public String getDateIni() { + return dateIni; + } + + public void setDateIni(String dateIni) { + this.dateIni = dateIni; + } + + public String getDateEnd() { + return dateEnd; + } + + public void setDateEnd(String dateEnd) { + this.dateEnd = dateEnd; + } +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/StatusCacheDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/StatusCacheDAO.java index c5d586027..129f0e24c 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/StatusCacheDAO.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/StatusCacheDAO.java @@ -25,6 +25,7 @@ import java.util.Date; import java.util.List; import fr.gouv.etalab.mastodon.client.Entities.Status; +import fr.gouv.etalab.mastodon.helper.FilterToots; import fr.gouv.etalab.mastodon.helper.Helper; @@ -164,18 +165,40 @@ public class StatusCacheDAO { * Returns all cached Statuses in db depending of their cache type * @return stored status List */ - public List getStatusFromID(int cacheType, String max_id){ + public List getStatusFromID(int cacheType, FilterToots filterToots, String max_id){ SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); String instance = Helper.getLiveInstance(context); + //That the basic selection for all toots + String selection = Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'"; + if( max_id != null) + selection += " AND " + Sqlite.COL_STATUS_ID + " < '" + max_id+ "'"; + //BOOST + if(filterToots.getBoosts() == FilterToots.typeFilter.NONE) + selection += " AND (" + Sqlite.COL_REBLOG + " IS NULL OR "+ Sqlite.COL_REBLOG + " = 'null')"; + else if(filterToots.getBoosts() == FilterToots.typeFilter.ONLY) + selection += " AND " + Sqlite.COL_REBLOG + " IS NOT NULL AND "+ Sqlite.COL_REBLOG + " <> 'null'"; + //REPLIES + if(filterToots.getReplies() == FilterToots.typeFilter.NONE) + selection += " AND (" + Sqlite.COL_IN_REPLY_TO_ID + " IS NULL OR "+ Sqlite.COL_IN_REPLY_TO_ID + " = 'null')"; + else if(filterToots.getReplies() == FilterToots.typeFilter.ONLY) + selection += " AND " + Sqlite.COL_IN_REPLY_TO_ID + " IS NOT NULL AND "+ Sqlite.COL_IN_REPLY_TO_ID + " <> 'null'"; + //PINNED + if(filterToots.getPinned() == FilterToots.typeFilter.NONE) + selection += " AND " + Sqlite.COL_PINNED + " = 0"; + else if(filterToots.getPinned() == FilterToots.typeFilter.ONLY) + selection += " AND " + Sqlite.COL_PINNED + " = 1"; + //PINNED + if(filterToots.getMedia() == FilterToots.typeFilter.NONE) + selection += " AND " + Sqlite.COL_MEDIA_ATTACHMENTS + " = '[]'"; + else if(filterToots.getMedia() == FilterToots.typeFilter.ONLY) + selection += " AND " + Sqlite.COL_MEDIA_ATTACHMENTS + " <> '[]'"; + try { - Cursor c; - if( max_id != null) - c = db.query(Sqlite.TABLE_STATUSES_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_STATUS_ID + " < '" + max_id+ "'", null, null, null, Sqlite.COL_CREATED_AT + " DESC", "80"); - else - c = db.query(Sqlite.TABLE_STATUSES_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_CREATED_AT + " DESC", "80"); + Cursor c = db.query(Sqlite.TABLE_STATUSES_CACHE, null, selection, null, null, null, Sqlite.COL_CREATED_AT + " DESC", "80"); return cursorToListStatuses(c); } catch (Exception e) { + e.printStackTrace(); return null; } } diff --git a/app/src/main/res/layout/filter_owner_toots.xml b/app/src/main/res/layout/filter_owner_toots.xml index 23227cef5..efe713774 100644 --- a/app/src/main/res/layout/filter_owner_toots.xml +++ b/app/src/main/res/layout/filter_owner_toots.xml @@ -15,94 +15,161 @@ You should have received a copy of the GNU General Public License along with Mastalab; if not, see . --> - - + + +