added scope for filters

This commit is contained in:
Mariotaku Lee 2017-09-10 23:32:12 +08:00
parent 3948954973
commit b7f7944e00
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
13 changed files with 206 additions and 72 deletions

View File

@ -0,0 +1,41 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.annotation;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@IntDef(value = {FilterScope.HOME, FilterScope.INTERACTIONS, FilterScope.MESSAGES,
FilterScope.SEARCH_RESULT, FilterScope.LIST_GROUP_TIMELINE, FilterScope.FAVORITES,
FilterScope.ALL}, flag = true)
@Retention(RetentionPolicy.SOURCE)
public @interface FilterScope {
int HOME = 0x1;
int INTERACTIONS = 0x2;
int MESSAGES = 0x4;
int SEARCH_RESULT = 0x8;
int LIST_GROUP_TIMELINE = 0x16;
int FAVORITES = 0x32;
// Contains all flags
int ALL = 0xFFFFFFFF;
}

View File

@ -25,6 +25,7 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.annotation.FilterScope;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
@ -109,6 +110,10 @@ public class FiltersData {
@CursorField(value = Filters.Users.SOURCE, type = "INTEGER DEFAULT -1")
@JsonField(name = "source")
long source = -1;
@CursorField(value = Filters.Users.SCOPE, type = "INTEGER DEFAULT 0")
@JsonField(name = "scope")
@FilterScope
int scope = 0;
public UserKey getUserKey() {
return userKey;
@ -142,6 +147,15 @@ public class FiltersData {
this.source = source;
}
@FilterScope
public int getScope() {
return scope;
}
public void setScope(@FilterScope int scope) {
this.scope = scope;
}
@Override
public String toString() {
return "UserItem{" +
@ -150,6 +164,7 @@ public class FiltersData {
", name='" + name + '\'' +
", screenName='" + screenName + '\'' +
", source=" + source +
", scope=" + scope +
'}';
}
@ -192,6 +207,11 @@ public class FiltersData {
@Nullable
UserKey userKey = null;
@CursorField(value = Filters.SCOPE, type = "INTEGER DEFAULT 0")
@JsonField(name = "scope")
@FilterScope
int scope = 0;
public long getId() {
return _id;
}
@ -221,6 +241,15 @@ public class FiltersData {
this.userKey = userKey;
}
@FilterScope
public int getScope() {
return scope;
}
public void setScope(@FilterScope int scope) {
this.scope = scope;
}
@Override
public String toString() {
return "BaseItem{" +
@ -228,6 +257,7 @@ public class FiltersData {
", value='" + value + '\'' +
", source=" + source +
", userKey=" + userKey +
", scope=" + scope +
'}';
}

View File

@ -498,11 +498,7 @@ public interface TwidereDataStore {
String USER_KEY = "user_key";
String ENABLE_IN_HOME_TIMELINE = "enable_in_home_timeline";
String ENABLE_IN_MENTIONS = "enable_in_mentions";
String ENABLE_FOR_RETWEETS = "enable_for_retweets";
String SCOPE = "scope";
String[] COLUMNS = FiltersData$BaseItemTableInfo.COLUMNS;
@ -543,6 +539,7 @@ public interface TwidereDataStore {
String NAME = "name";
String SCREEN_NAME = "screen_name";
String SOURCE = "source";
String SCOPE = "scope";
String[] COLUMNS = FiltersData$UserItemTableInfo.COLUMNS;
@ -733,12 +730,6 @@ public interface TwidereDataStore {
String ACCOUNT_COLOR = "account_color";
String USER_NICKNAME = "user_nickname";
String QUOTED_USER_NICKNAME = "quoted_user_nickname";
String RETWEET_USER_NICKNAME = "retweet_user_nickname";
String IN_REPLY_TO_USER_NICKNAME = "in_reply_to_user_nickname";
String FILTER_FLAGS = "filter_flags";
String DEFAULT_SORT_ORDER = TIMESTAMP + " DESC, " + SORT_ID + " DESC, " + ID

View File

@ -30,7 +30,7 @@ import org.mariotaku.twidere.model.UserKey;
public interface Constants extends TwidereConstants {
String DATABASES_NAME = "twidere.sqlite";
int DATABASES_VERSION = 184;
int DATABASES_VERSION = 185;
int EXTRA_FEATURES_NOTICE_VERSION = 2;

View File

@ -76,6 +76,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.annotation.CustomTabType
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.annotation.NavbarStyle
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.*
@ -946,7 +947,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
}.fold(0L, Math::max)
val count = DataStoreUtils.getStatusesCount(context, preferences,
Statuses.CONTENT_URI, spec.args, Statuses.TIMESTAMP, position,
true, accountKeys)
true, accountKeys, FilterScope.HOME)
result.put(i, count)
publishProgress(TabBadge(i, count))
}

View File

@ -52,7 +52,7 @@ fun Account.toParcelable(accountKey: UserKey, position: Long = 0,
obj.is_protected = isLocked
obj.name = name
obj.screen_name = username
if (note?.isHtml ?: false) {
if (note?.isHtml == true) {
val descriptionHtml = HtmlSpanBuilder.fromHtml(note, note, MastodonSpanProcessor)
obj.description_unescaped = descriptionHtml?.toString()
obj.description_plain = obj.description_unescaped

View File

@ -37,6 +37,7 @@ import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.extension.queryOne
import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader
@ -68,6 +69,9 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() {
protected abstract val isFilterEnabled: Boolean
@FilterScope
protected abstract val filterScopes: Int
private var contentObserver: ContentObserver? = null
private val accountListener: OnAccountsUpdateListener = OnAccountsUpdateListener {
@ -213,7 +217,7 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() {
protected fun getFiltersWhere(table: String): Expression? {
if (!isFilterEnabled) return null
return DataStoreUtils.buildActivityFilterWhereClause(table, null)
return DataStoreUtils.buildActivityFilterWhereClause(table, null, filterScopes)
}
protected open fun processWhere(where: Expression, whereArgs: Array<String>): ParameterizedExpression {

View File

@ -38,6 +38,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.ListParcelableStatusesAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader
import org.mariotaku.twidere.model.ParameterizedExpression
@ -75,6 +76,8 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
abstract val isFilterEnabled: Boolean
abstract val notificationType: Int
abstract val contentUri: Uri
@FilterScope
abstract val filterScopes: Int
private var contentObserver: ContentObserver? = null
private val accountListener: OnAccountsUpdateListener = OnAccountsUpdateListener {
@ -208,7 +211,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
protected fun getFiltersWhere(table: String): Expression? {
if (!isFilterEnabled) return null
return buildStatusFilterWhereClause(preferences, table, null)
return buildStatusFilterWhereClause(preferences, table, null, filterScopes)
}
protected open fun processWhere(where: Expression, whereArgs: Array<String>): ParameterizedExpression {
@ -316,6 +319,6 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
companion object {
private val statusColumnsLite = Statuses.COLUMNS - arrayOf(Statuses.MENTIONS_JSON,
Statuses.CARD)
Statuses.CARD, Statuses.FILTER_FLAGS)
}
}

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.TwidereConstants.NOTIFICATION_ID_HOME_TIMELINE
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_EXTRAS
import org.mariotaku.twidere.model.ParameterizedExpression
@ -50,6 +51,9 @@ class HomeTimelineFragment : CursorStatusesFragment() {
override val timelineSyncTag: String?
get() = getTimelineSyncTag(accountKeys)
override val filterScopes: Int
get() = FilterScope.HOME
override fun updateRefreshState() {
val twitter = twitterWrapper
refreshing = twitter.isStatusTimelineRefreshing(contentUri)

View File

@ -25,6 +25,7 @@ import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.TwidereConstants.NOTIFICATION_ID_INTERACTIONS_TIMELINE
import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_EXTRAS
import org.mariotaku.twidere.model.ParameterizedExpression
@ -50,6 +51,9 @@ class InteractionsTimelineFragment : CursorActivitiesFragment() {
override val timelineSyncTag: String?
get() = getTimelineSyncTag(accountKeys)
override val filterScopes: Int
get() = FilterScope.INTERACTIONS
override fun onCreateAdapter(context: Context, requestManager: RequestManager): ParcelableActivitiesAdapter {
val adapter = ParcelableActivitiesAdapter(context, requestManager)
val extras: InteractionsTabExtras? = arguments.getParcelable(EXTRA_EXTRAS)

View File

@ -17,6 +17,7 @@ import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.*
import org.mariotaku.sqliteqb.library.Columns.Column
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey
import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey
import org.mariotaku.twidere.extension.model.component1
@ -32,21 +33,55 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
import org.mariotaku.twidere.util.DataStoreUtils.ACTIVITIES_URIS
import java.io.IOException
/**
* Created by mariotaku on 2016/12/24.
*/
fun buildStatusFilterWhereClause(preferences: SharedPreferences, table: String,
extraSelection: Expression?): Expression {
extraSelection: Expression?, @FilterScope filterScopes: Int = FilterScope.ALL): Expression {
val filteredUsersQuery = SQLQueryBuilder
.select(Column(Table(Filters.Users.TABLE_NAME), Filters.Users.USER_KEY))
.from(Tables(Filters.Users.TABLE_NAME))
.where(Expression.or(
Expression.equals(Column(Table(Filters.Users.TABLE_NAME), Filters.Users.SCOPE), 0),
Expression.notEquals("${Filters.Users.TABLE_NAME}.${Filters.Users.SCOPE} & $filterScopes", 0)
))
.build()
val filteredUsersWhere = Expression.or(
Expression.`in`(Column(Table(table), Statuses.USER_KEY), filteredUsersQuery),
Expression.`in`(Column(Table(table), Statuses.RETWEETED_BY_USER_KEY), filteredUsersQuery),
Expression.`in`(Column(Table(table), Statuses.QUOTED_USER_KEY), filteredUsersQuery)
)
val filteredSourcesWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Sources.TABLE_NAME), Filters.Sources.SCOPE), 0),
Expression.notEquals("${Filters.Sources.TABLE_NAME}.${Filters.Sources.SCOPE} & $filterScopes", 0)
),
Expression.or(
Expression.likeRaw(Column(Table(table), Statuses.SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'")
)
)
val filteredKeywordsWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Keywords.TABLE_NAME), Filters.Keywords.SCOPE), 0),
Expression.notEquals("${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.SCOPE} & $filterScopes", 0)
),
Expression.or(Expression.likeRaw(Column(Table(table), Statuses.TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'"))
)
val filteredLinksWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Links.TABLE_NAME), Filters.Links.SCOPE), 0),
Expression.notEquals("${Filters.Links.TABLE_NAME}.${Filters.Links.SCOPE} & $filterScopes", 0)
),
Expression.or(
Expression.likeRaw(Column(Table(table), Statuses.SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'")
)
)
val filteredIdsQueryBuilder = SQLQueryBuilder
.select(Column(Table(table), Statuses._ID))
.from(Tables(table))
@ -54,30 +89,15 @@ fun buildStatusFilterWhereClause(preferences: SharedPreferences, table: String,
.union()
.select(Columns(Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Sources.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Statuses.SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_SOURCE),
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'")
))
.where(filteredSourcesWhere)
.union()
.select(Columns(Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Keywords.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Statuses.TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_TEXT_PLAIN),
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")
))
.where(filteredKeywordsWhere)
.union()
.select(Columns(Column(Table(table), Statuses._ID)))
.from(Tables(table, Filters.Links.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Statuses.SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'"),
Expression.likeRaw(Column(Table(table), Statuses.QUOTED_SPANS),
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'")
))
.where(filteredLinksWhere)
var filterFlags: Long = 0
if (preferences[filterUnavailableQuoteStatusesKey]) {
filterFlags = filterFlags or FilterFlags.QUOTE_NOT_AVAILABLE

View File

@ -43,6 +43,7 @@ import org.mariotaku.sqliteqb.library.query.SQLSelectQuery
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.databaseItemLimitKey
import org.mariotaku.twidere.extension.model.*
@ -325,7 +326,7 @@ object DataStoreUtils {
fun getStatusesCount(context: Context, preferences: SharedPreferences, uri: Uri,
extraArgs: Bundle?, compareColumn: String, compare: Long, greaterThan: Boolean,
accountKeys: Array<UserKey>?): Int {
accountKeys: Array<UserKey>?, @FilterScope filterScopes: Int = FilterScope.ALL): Int {
val keys = accountKeys ?: getActivatedAccountKeys(context)
val expressions = ArrayList<Expression>()
@ -342,7 +343,8 @@ object DataStoreUtils {
expressions.add(Expression.lesserThan(compareColumn, compare))
}
expressions.add(buildStatusFilterWhereClause(preferences, getTableNameByUri(uri)!!, null))
expressions.add(buildStatusFilterWhereClause(preferences, getTableNameByUri(uri)!!,
null, filterScopes))
if (extraArgs != null) {
val extras = extraArgs.getParcelable<Parcelable>(EXTRA_EXTRAS)
@ -356,7 +358,8 @@ object DataStoreUtils {
}
fun getActivitiesCount(context: Context, uri: Uri, compareColumn: String,
compare: Long, greaterThan: Boolean, accountKeys: Array<UserKey>?): Int {
compare: Long, greaterThan: Boolean, accountKeys: Array<UserKey>?,
@FilterScope filterScopes: Int = FilterScope.ALL): Int {
val keys = accountKeys ?: getActivatedAccountKeys(context)
val selection = Expression.and(
Expression.inArgs(Column(Activities.ACCOUNT_KEY), keys.size),
@ -365,7 +368,8 @@ object DataStoreUtils {
} else {
Expression.lesserThan(compareColumn, compare)
},
buildActivityFilterWhereClause(getTableNameByUri(uri)!!, null)
buildActivityFilterWhereClause(getTableNameByUri(uri)!!, null,
filterScopes)
)
val whereArgs = arrayListOf<String>()
keys.mapTo(whereArgs) { it.toString() }
@ -375,12 +379,13 @@ object DataStoreUtils {
fun getActivitiesCount(context: Context, uri: Uri,
extraWhere: Expression?, extraWhereArgs: Array<String>?,
sinceColumn: String, since: Long, followingOnly: Boolean,
accountKeys: Array<UserKey>?): Int {
accountKeys: Array<UserKey>?, @FilterScope filterScopes: Int = FilterScope.ALL): Int {
val keys = (accountKeys ?: getActivatedAccountKeys(context)).mapToArray { it.toString() }
val expressions = ArrayList<Expression>()
expressions.add(Expression.inArgs(Column(Activities.ACCOUNT_KEY), keys.size))
expressions.add(Expression.greaterThan(sinceColumn, since))
expressions.add(buildActivityFilterWhereClause(getTableNameByUri(uri)!!, null))
expressions.add(buildActivityFilterWhereClause(getTableNameByUri(uri)!!, null,
filterScopes))
if (extraWhere != null) {
expressions.add(extraWhere)
}
@ -457,16 +462,57 @@ object DataStoreUtils {
return getTableNameById(getTableId(uri))
}
fun buildActivityFilterWhereClause(table: String, extraSelection: Expression?): Expression {
fun buildActivityFilterWhereClause(table: String, extraSelection: Expression?,
@FilterScope filterScopes: Int = FilterScope.ALL): Expression {
val filteredUsersQuery = SQLQueryBuilder
.select(Column(Table(Filters.Users.TABLE_NAME), Filters.Users.USER_KEY))
.from(Tables(Filters.Users.TABLE_NAME))
.where(Expression.or(
Expression.equals(Column(Table(Filters.Users.TABLE_NAME), Filters.Users.SCOPE), 0),
Expression.notEquals("${Filters.Users.TABLE_NAME}.${Filters.Users.SCOPE} & $filterScopes", 0)
))
.build()
val filteredUsersWhere = Expression.or(
Expression.`in`(Column(Table(table), Activities.USER_KEY), filteredUsersQuery),
Expression.`in`(Column(Table(table), Activities.RETWEETED_BY_USER_KEY), filteredUsersQuery),
Expression.`in`(Column(Table(table), Activities.QUOTED_USER_KEY), filteredUsersQuery)
)
val filteredSourcesWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Sources.TABLE_NAME), Filters.Sources.SCOPE), 0),
Expression.notEquals("${Filters.Sources.TABLE_NAME}.${Filters.Sources.SCOPE} & $filterScopes", 0)
),
Expression.or(
Expression.likeRaw(Column(Table(table), Activities.SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'")
)
)
val filteredKeywordsWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Keywords.TABLE_NAME), Filters.Keywords.SCOPE), 0),
Expression.notEquals("${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.SCOPE} & $filterScopes", 0)
),
Expression.or(
Expression.likeRaw(Column(Table(table), Activities.TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'")
)
)
val filteredLinksWhere = Expression.and(
Expression.or(
Expression.equals(Column(Table(Filters.Links.TABLE_NAME), Filters.Links.SCOPE), 0),
Expression.notEquals("${Filters.Links.TABLE_NAME}.${Filters.Links.SCOPE} & $filterScopes", 0)
),
Expression.or(
Expression.likeRaw(Column(Table(table), Activities.SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'")
)
)
val filteredIdsQueryBuilder = SQLQueryBuilder
.select(Column(Table(table), Activities._ID))
.from(Tables(table))
@ -474,30 +520,15 @@ object DataStoreUtils {
.union()
.select(Columns(Column(Table(table), Activities._ID)))
.from(Tables(table, Filters.Sources.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Activities.SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_SOURCE),
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'")
))
.where(filteredSourcesWhere)
.union()
.select(Columns(Column(Table(table), Activities._ID)))
.from(Tables(table, Filters.Keywords.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Activities.TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_TEXT_PLAIN),
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'")
))
.where(filteredKeywordsWhere)
.union()
.select(Columns(Column(Table(table), Activities._ID)))
.from(Tables(table, Filters.Links.TABLE_NAME))
.where(Expression.or(
Expression.likeRaw(Column(Table(table), Activities.SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'"),
Expression.likeRaw(Column(Table(table), Activities.QUOTED_SPANS),
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'")
))
.where(filteredLinksWhere)
val filterExpression = Expression.or(
Expression.notIn(Column(Table(table), Activities._ID), filteredIdsQueryBuilder.build()),
Expression.equals(Column(Table(table), Activities.IS_GAP), 1)
@ -802,7 +833,7 @@ object DataStoreUtils {
}
fun getInteractionsCount(context: Context, extraArgs: Bundle?, accountKeys: Array<UserKey>,
since: Long, sinceColumn: String): Int {
since: Long, sinceColumn: String, @FilterScope filterScopes: Int = FilterScope.ALL): Int {
var extraWhere: Expression? = null
var extraWhereArgs: Array<String>? = null
var followingOnly = false
@ -819,7 +850,7 @@ object DataStoreUtils {
}
}
return getActivitiesCount(context, Activities.AboutMe.CONTENT_URI, extraWhere, extraWhereArgs,
sinceColumn, since, followingOnly, accountKeys)
sinceColumn, since, followingOnly, accountKeys, filterScopes)
}
fun addToFilter(context: Context, users: Collection<ParcelableUser>, filterAnywhere: Boolean) {

View File

@ -42,6 +42,7 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.HomeActivity
import org.mariotaku.twidere.activity.LinkHandlerActivity
import org.mariotaku.twidere.annotation.CustomTabType
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.annotation.NotificationType
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.iWantMyStarsBackKey
@ -88,7 +89,7 @@ class ContentNotificationManager(
)
val selectionArgs = arrayOf(accountKey.toString())
val filteredSelection = buildStatusFilterWhereClause(preferences, Statuses.TABLE_NAME,
selection)
selection, FilterScope.HOME)
val userProjection = arrayOf(Statuses.USER_KEY, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME)
val statusProjection = arrayOf(Statuses.POSITION_KEY)
@ -169,12 +170,15 @@ class ContentNotificationManager(
val cr = context.contentResolver
val accountKey = pref.accountKey
val account = AccountUtils.getAccountDetails(am, accountKey, false) ?: return
val where = Expression.and(
val selection = Expression.and(
Expression.equalsArgs(Activities.ACCOUNT_KEY),
Expression.greaterThan(Activities.POSITION_KEY, position),
Expression.notEquals(Activities.IS_GAP, 1)
).sql
val whereArgs = arrayOf(accountKey.toString())
)
val selectionArgs = arrayOf(accountKey.toString())
val filteredSelection = DataStoreUtils.buildActivityFilterWhereClause(Activities.AboutMe.TABLE_NAME,
selection, FilterScope.INTERACTIONS)
val builder = NotificationChannelSpec.contentInteractions.accountNotificationBuilder(context,
accountKey)
val pebbleNotificationStringBuilder = StringBuilder()
@ -197,7 +201,8 @@ class ContentNotificationManager(
val filteredUserKeys = DataStoreUtils.getFilteredUserKeys(context)
val (remaining, consumed) = cr.queryReference(Activities.AboutMe.CONTENT_URI, Activities.COLUMNS, where, whereArgs,
val (remaining, consumed) = cr.queryReference(Activities.AboutMe.CONTENT_URI, Activities.COLUMNS,
filteredSelection.sql, selectionArgs,
OrderBy(Activities.TIMESTAMP, false).sql).use { (cur) ->
if (cur == null || cur.isEmpty) return@use Pair(-1, -1)
val ci = ObjectCursor.indicesFrom(cur, ParcelableActivity::class.java)