1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-12 09:40:50 +01:00

improved filters

This commit is contained in:
Mariotaku Lee 2016-12-24 23:52:34 +08:00
parent 24e5781b8c
commit 1cd8580f45
7 changed files with 121 additions and 90 deletions

View File

@ -116,6 +116,7 @@ import org.mariotaku.twidere.receiver.NotificationReceiver;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.util.ActivityTracker;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.DataStoreFunctionsKt;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ImagePreloader;
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
@ -1249,7 +1250,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
final NotificationManagerWrapper nm = mNotificationManager;
final Expression selection = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_KEY),
Expression.greaterThan(Statuses.POSITION_KEY, position));
final String filteredSelection = DataStoreUtils.buildStatusFilterWhereClause(preferences,
final String filteredSelection = DataStoreFunctionsKt.buildStatusFilterWhereClause(preferences,
Statuses.TABLE_NAME, selection).getSQL();
final String[] selectionArgs = {accountKey.toString()};
final String[] userProjection = {Statuses.USER_KEY, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME};

View File

@ -42,7 +42,6 @@ import com.bluelinelabs.logansquare.LoganSquare;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.mariotaku.kpreferences.SharedPreferencesExtensionsKt;
import org.mariotaku.microblog.library.twitter.model.Activity;
import org.mariotaku.sqliteqb.library.ArgsArray;
import org.mariotaku.sqliteqb.library.Columns;
@ -56,7 +55,6 @@ import org.mariotaku.sqliteqb.library.Tables;
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.constant.PreferenceKeysKt;
import org.mariotaku.twidere.extension.AccountExtensionsKt;
import org.mariotaku.twidere.model.FiltersData;
import org.mariotaku.twidere.model.FiltersData$BaseItemValuesCreator;
@ -325,69 +323,6 @@ public class DataStoreUtils implements Constants {
}
}
@NonNull
public static Expression buildStatusFilterWhereClause(@NonNull final SharedPreferences preferences,
@NonNull final String table,
@Nullable final Expression extraSelection) {
final SQLSelectQuery filteredUsersQuery = SQLQueryBuilder
.select(new Column(new Table(Filters.Users.TABLE_NAME), Filters.Users.USER_KEY))
.from(new Tables(Filters.Users.TABLE_NAME))
.build();
final Expression filteredUsersWhere = Expression.or(
Expression.in(new Column(new Table(table), Statuses.USER_KEY), filteredUsersQuery),
Expression.in(new Column(new Table(table), Statuses.RETWEETED_BY_USER_KEY), filteredUsersQuery),
Expression.in(new Column(new Table(table), Statuses.QUOTED_USER_KEY), filteredUsersQuery)
);
final SQLSelectQuery.Builder filteredIdsQueryBuilder = SQLQueryBuilder
.select(new Column(new Table(table), Statuses._ID))
.from(new Tables(table))
.where(filteredUsersWhere)
.union()
.select(new Columns(new Column(new Table(table), Statuses._ID)))
.from(new Tables(table, Filters.Sources.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(new Column(new Table(table), Statuses.SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'"),
Expression.likeRaw(new Column(new Table(table), Statuses.QUOTED_SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'")
))
.union()
.select(new Columns(new Column(new Table(table), Statuses._ID)))
.from(new Tables(table, Filters.Keywords.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(new Column(new Table(table), Statuses.TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'"),
Expression.likeRaw(new Column(new Table(table), Statuses.QUOTED_TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")
))
.union()
.select(new Columns(new Column(new Table(table), Statuses._ID)))
.from(new Tables(table, Filters.Links.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(new Column(new Table(table), Statuses.SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'"),
Expression.likeRaw(new Column(new Table(table), Statuses.QUOTED_SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'")
));
int filterFlags = 0;
if (SharedPreferencesExtensionsKt.get(preferences, PreferenceKeysKt.getFilterUnavailableQuoteStatusesKey())) {
filterFlags |= ParcelableStatus.FilterFlags.QUOTE_NOT_AVAILABLE;
}
final Expression filterExpression = Expression.or(
Expression.and(
new Expression("(" + Statuses.FILTER_FLAGS + " & " + filterFlags + ") == 0"),
Expression.notIn(new Column(new Table(table), Statuses._ID), filteredIdsQueryBuilder.build())
),
Expression.equals(new Column(new Table(table), Statuses.IS_GAP), 1)
);
if (extraSelection != null) {
return Expression.and(filterExpression, extraSelection);
}
return filterExpression;
}
public static String getAccountDisplayName(final Context context, final UserKey accountKey, final boolean nameFirst) {
final String name;
if (nameFirst) {
@ -458,7 +393,7 @@ public class DataStoreUtils implements Constants {
}
expressionArgs.add(String.valueOf(compare));
expressions.add(buildStatusFilterWhereClause(preferences, getTableNameByUri(uri), null));
expressions.add(DataStoreFunctionsKt.buildStatusFilterWhereClause(preferences, getTableNameByUri(uri), null));
if (extraArgs != null) {
Parcelable extras = extraArgs.getParcelable(EXTRA_EXTRAS);

View File

@ -77,18 +77,6 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
showProgress()
}
// @Override
// public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
// final View view = super.onCreateView(inflater, container, savedInstanceState);
// assert view != null;
// final ListView listView = (ListView) view.findViewById(R.id.list_view);
// final Resources res = getResources();
// final float density = res.getDisplayMetrics().density;
// final int padding = (int) density * 16;
// listView.setPadding(padding, 0, padding, 0);
// return view;
// }
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (!isVisibleToUser && actionMode != null) {
@ -170,7 +158,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
}
override fun onLoadFinished(loader: Loader<Cursor?>, data: Cursor?) {
adapter!!.swapCursor(data)
adapter.swapCursor(data)
if (data != null && data.count > 0) {
showContent()
} else {
@ -179,14 +167,13 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
}
override fun onLoaderReset(loader: Loader<Cursor?>) {
adapter!!.swapCursor(null)
adapter.swapCursor(null)
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater!!.inflate(R.menu.menu_filters, menu)
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_filters, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.add -> {
@ -338,6 +325,11 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
class FilteredUsersFragment : BaseFiltersFragment() {
public override val contentColumns: Array<String>
get() = Filters.Users.COLUMNS
override val contentUri: Uri
get() = Filters.Users.CONTENT_URI
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
@ -355,11 +347,9 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
}
}
public override val contentColumns: Array<String>
get() = Filters.Users.COLUMNS
override val contentUri: Uri
get() = Filters.Users.CONTENT_URI
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_filters_users, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {

View File

@ -47,6 +47,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.ErrorInfoStore
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.buildStatusFilterWhereClause
/**
* Created by mariotaku on 14/12/3.
@ -222,7 +223,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
protected fun getFiltersWhere(table: String): Expression? {
if (!isFilterEnabled) return null
return DataStoreUtils.buildStatusFilterWhereClause(preferences, table, null)
return buildStatusFilterWhereClause(preferences, table, null)
}
protected fun getNewestStatusIds(accountKeys: Array<UserKey>): Array<String?>? {

View File

@ -0,0 +1,74 @@
package org.mariotaku.twidere.util
import android.content.SharedPreferences
import org.mariotaku.kpreferences.get
import org.mariotaku.sqliteqb.library.*
import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey
import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
/**
* Created by mariotaku on 2016/12/24.
*/
fun buildStatusFilterWhereClause(preferences: SharedPreferences,
table: String,
extraSelection: Expression?): Expression {
val filteredUsersQuery = SQLQueryBuilder
.select(Columns.Column(Table(Filters.Users.TABLE_NAME), Filters.Users.USER_KEY))
.from(Tables(Filters.Users.TABLE_NAME))
.build()
val filteredUsersWhere = Expression.or(
Expression.`in`(Columns.Column(Table(table), Statuses.USER_KEY), filteredUsersQuery),
Expression.`in`(Columns.Column(Table(table), Statuses.RETWEETED_BY_USER_KEY), filteredUsersQuery),
Expression.`in`(Columns.Column(Table(table), Statuses.QUOTED_USER_KEY), filteredUsersQuery)
)
val filteredIdsQueryBuilder = SQLQueryBuilder
.select(Columns.Column(Table(table), Statuses._ID))
.from(Tables(table))
.where(filteredUsersWhere)
.union()
.select(Columns(Columns.Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Sources.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Columns.Column(Table(table), Statuses.SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'"),
Expression.likeRaw(Columns.Column(Table(table), Statuses.QUOTED_SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'")
))
.union()
.select(Columns(Columns.Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Keywords.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Columns.Column(Table(table), Statuses.TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'"),
Expression.likeRaw(Columns.Column(Table(table), Statuses.QUOTED_TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")
))
.union()
.select(Columns(Columns.Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Links.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Columns.Column(Table(table), Statuses.SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'"),
Expression.likeRaw(Columns.Column(Table(table), Statuses.QUOTED_SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'")
))
var filterFlags: Long = 0
if (preferences[filterUnavailableQuoteStatusesKey]) {
filterFlags = filterFlags or FilterFlags.QUOTE_NOT_AVAILABLE
}
val filterExpression = Expression.or(
Expression.and(
Expression("(" + Statuses.FILTER_FLAGS + " & " + filterFlags + ") == 0"),
Expression.notIn(Columns.Column(Table(table), Statuses._ID), filteredIdsQueryBuilder.build())
),
Expression.equals(Columns.Column(Table(table), Statuses.IS_GAP), 1)
)
if (extraSelection != null) {
return Expression.and(filterExpression, extraSelection)
}
return filterExpression
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/add_submenu"
android:icon="@drawable/ic_action_add"
android:title="@string/add"
app:showAsAction="always">
<menu>
<item
android:id="@id/add"
android:title="@string/select_user"/>
<item
android:id="@+id/import_from_blocked_users"
android:enabled="@bool/is_debug"
android:title="@string/action_filter_import_from_blocked_users"
android:visible="@bool/is_debug"/>
<item
android:id="@+id/import_from_muted_users"
android:enabled="@bool/is_debug"
android:title="@string/action_filter_import_from_muted_users"
android:visible="@bool/is_debug"/>
</menu>
</item>
</menu>

View File

@ -828,4 +828,6 @@
<string name="status_format_time_source"><xliff:g example="0:00, Jan 1 2017" id="time">%1$s</xliff:g> · <xliff:g example="Twidere for Android" id="source">%2$s</xliff:g></string>
<string name="status_format_source"><xliff:g example="Twidere for Android" id="source">%s</xliff:g></string>
<string name="preference_filter_unavailable_quote_statuses">Filter unavailable quotes</string>
<string name="action_filter_import_from_blocked_users">Import from blocked users</string>
<string name="action_filter_import_from_muted_users">Import from muted users</string>
</resources>