implementing messages refresh
This commit is contained in:
parent
90cb5770e9
commit
23dd621445
|
@ -432,8 +432,11 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, APIEditorDi
|
|||
}.alwaysUi {
|
||||
val activity = weakThis.get() ?: return@alwaysUi
|
||||
if (activity.isFinishing) return@alwaysUi
|
||||
val df = weakDf.get() ?: supportFragmentManager.findFragmentByTag(FRAGMENT_TAG_LOADING_DEFAULT_FEATURES) as? DialogFragment
|
||||
df?.dismiss()
|
||||
activity.executeAfterFragmentResumed { activity ->
|
||||
val fm = activity.supportFragmentManager
|
||||
val df = weakDf.get() ?: fm.findFragmentByTag(FRAGMENT_TAG_LOADING_DEFAULT_FEATURES) as? DialogFragment
|
||||
df?.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,24 @@
|
|||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.accounts.AccountManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager
|
||||
import android.support.v4.content.Loader
|
||||
import com.squareup.otto.Subscribe
|
||||
import org.mariotaku.kpreferences.get
|
||||
import org.mariotaku.ktextension.toNulls
|
||||
import org.mariotaku.sqliteqb.library.OrderBy
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.adapter.MessagesEntriesAdapter
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
||||
import org.mariotaku.twidere.annotation.AccountType
|
||||
import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||
import org.mariotaku.twidere.extension.model.user
|
||||
import org.mariotaku.twidere.loader.ObjectCursorLoader
|
||||
import org.mariotaku.twidere.model.ParcelableMessageConversation
|
||||
import org.mariotaku.twidere.model.ParcelableMessageConversationCursorIndices
|
||||
import org.mariotaku.twidere.model.SimpleRefreshTaskParam
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||
import org.mariotaku.twidere.task.GetMessagesTask
|
||||
import org.mariotaku.twidere.util.DataStoreUtils
|
||||
import org.mariotaku.twidere.util.ErrorInfoStore
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
|
@ -45,6 +42,16 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
|
|||
loaderManager.initLoader(0, null, this)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
bus.register(this)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
bus.unregister(this)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ParcelableMessageConversation>?> {
|
||||
val loader = ObjectCursorLoader(context, ParcelableMessageConversationCursorIndices::class.java)
|
||||
loader.uri = Conversations.CONTENT_URI
|
||||
|
@ -69,37 +76,8 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
|
|||
|
||||
override fun triggerRefresh(): Boolean {
|
||||
super.triggerRefresh()
|
||||
twitterWrapper.getMessagesAsync(object : SimpleRefreshTaskParam() {
|
||||
private val accounts by lazy {
|
||||
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
|
||||
}
|
||||
|
||||
override val accountKeys: Array<UserKey> by lazy {
|
||||
this@MessagesEntriesFragment.accountKeys
|
||||
}
|
||||
|
||||
override val sinceIds: Array<String?>?
|
||||
get() {
|
||||
val result = arrayOfNulls<String>(accountKeys.size)
|
||||
val hasSinceAccountKeys = accounts.mapNotNull { account ->
|
||||
when (account?.type) {
|
||||
AccountType.FANFOU -> {
|
||||
return@mapNotNull null
|
||||
}
|
||||
}
|
||||
return@mapNotNull account?.key
|
||||
}.toTypedArray()
|
||||
val incomingIds = DataStoreUtils.getMessageIds(context, Messages.CONTENT_URI,
|
||||
hasSinceAccountKeys.toNulls(), false)
|
||||
val outgoingIds = DataStoreUtils.getMessageIds(context, Messages.CONTENT_URI,
|
||||
hasSinceAccountKeys.toNulls(), true)
|
||||
loop@ for (idx in 0..accountKeys.lastIndex) {
|
||||
|
||||
}
|
||||
return result
|
||||
}
|
||||
override val hasSinceIds: Boolean = true
|
||||
override val hasMaxIds: Boolean = false
|
||||
twitterWrapper.getMessagesAsync(GetMessagesTask.RefreshNewTaskParam(context) {
|
||||
this@MessagesEntriesFragment.accountKeys
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
@ -119,6 +97,13 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
|
|||
IntentUtils.openUserProfile(context, user, preferences[newDocumentApiKey])
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onGetMessagesTaskEvent(event: GetMessagesTaskEvent) {
|
||||
if (!event.running) {
|
||||
refreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun showContentOrError() {
|
||||
val accountKeys = this.accountKeys
|
||||
if (adapter.itemCount > 0) {
|
||||
|
@ -135,4 +120,6 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
|
|||
showError(R.drawable.ic_info_accounts, getString(R.string.message_toast_no_account_selected))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,12 +16,15 @@ import org.mariotaku.twidere.extension.model.setFrom
|
|||
import org.mariotaku.twidere.extension.model.timestamp
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
|
||||
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
|
||||
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||
import org.mariotaku.twidere.util.DataStoreUtils
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
||||
|
||||
/**
|
||||
|
@ -46,6 +49,7 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
|||
|
||||
override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Unit) {
|
||||
callback?.invoke(true)
|
||||
bus.post(GetMessagesTaskEvent(Messages.CONTENT_URI, false, null))
|
||||
}
|
||||
|
||||
private fun getMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshTaskParam, index: Int): GetMessagesData {
|
||||
|
@ -86,7 +90,7 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
|||
if (maxId != null) {
|
||||
maxId(maxId)
|
||||
}
|
||||
if (sinceIds != null) {
|
||||
if (sinceId != null) {
|
||||
sinceId(sinceId)
|
||||
}
|
||||
})
|
||||
|
@ -111,8 +115,8 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
|||
received.forEach {
|
||||
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
||||
}
|
||||
received.forEach {
|
||||
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
||||
sent.forEach {
|
||||
conversationIds.add(ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId))
|
||||
}
|
||||
|
||||
conversations.addLocalConversations(accountKey, conversationIds)
|
||||
|
@ -215,5 +219,38 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
|
|||
val conversations: Collection<ParcelableMessageConversation>,
|
||||
val messages: Collection<ParcelableMessage>
|
||||
)
|
||||
|
||||
class RefreshNewTaskParam(
|
||||
val context: Context,
|
||||
val getAccountKeys: () -> Array<UserKey>
|
||||
) : SimpleRefreshTaskParam() {
|
||||
|
||||
private val accounts by lazy {
|
||||
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
|
||||
}
|
||||
|
||||
override val accountKeys: Array<UserKey>
|
||||
get() = getAccountKeys()
|
||||
|
||||
override val sinceIds: Array<String?>?
|
||||
get() {
|
||||
val keys = accounts.map { account ->
|
||||
when (account?.type) {
|
||||
AccountType.FANFOU -> {
|
||||
return@map null
|
||||
}
|
||||
}
|
||||
return@map account?.key
|
||||
}.toTypedArray()
|
||||
val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
||||
keys, false)
|
||||
val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
||||
keys, true)
|
||||
return incomingIds + outgoingIds
|
||||
}
|
||||
|
||||
override val hasSinceIds: Boolean = true
|
||||
override val hasMaxIds: Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,13 +165,8 @@ object DataStoreUtils {
|
|||
OrderBy(SQLFunctions.MAX(Statuses.STATUS_TIMESTAMP)), null, null)
|
||||
}
|
||||
|
||||
fun getMessageIds(context: Context, uri: Uri, accountKeys: Array<UserKey?>, outgoing: Boolean): Array<String?> {
|
||||
val having: Expression
|
||||
if (outgoing) {
|
||||
having = Expression.equals(Messages.IS_OUTGOING, 1)
|
||||
} else {
|
||||
having = Expression.notEquals(Messages.IS_OUTGOING, 1)
|
||||
}
|
||||
fun getNewestMessageIds(context: Context, uri: Uri, accountKeys: Array<UserKey?>, outgoing: Boolean): Array<String?> {
|
||||
val having: Expression = Expression.equals(Messages.IS_OUTGOING, if (outgoing) 1 else 0)
|
||||
return getStringFieldArray(context, uri, accountKeys, Messages.ACCOUNT_KEY, Messages.MESSAGE_ID,
|
||||
OrderBy(SQLFunctions.MAX(Messages.LOCAL_TIMESTAMP)), having, null)
|
||||
}
|
||||
|
@ -439,27 +434,27 @@ object DataStoreUtils {
|
|||
.from(Tables(table, Filters.Sources.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_SOURCE),
|
||||
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'"),
|
||||
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'"),
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_QUOTE_SOURCE),
|
||||
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'")
|
||||
"'%>'||${Filters.Sources.TABLE_NAME}.${Filters.Sources.VALUE}||'</a>%'")
|
||||
))
|
||||
.union()
|
||||
.select(Columns(Column(Table(table), Activities._ID)))
|
||||
.from(Tables(table, Filters.Keywords.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_TEXT_PLAIN),
|
||||
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'"),
|
||||
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'"),
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_QUOTE_TEXT_PLAIN),
|
||||
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")
|
||||
"'%'||${Filters.Keywords.TABLE_NAME}.${Filters.Keywords.VALUE}||'%'")
|
||||
))
|
||||
.union()
|
||||
.select(Columns(Column(Table(table), Activities._ID)))
|
||||
.from(Tables(table, Filters.Links.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_SPANS),
|
||||
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'"),
|
||||
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'"),
|
||||
Expression.likeRaw(Column(Table(table), Activities.STATUS_QUOTE_SPANS),
|
||||
"'%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%'")
|
||||
"'%'||${Filters.Links.TABLE_NAME}.${Filters.Links.VALUE}||'%'")
|
||||
))
|
||||
val filterExpression = Expression.or(
|
||||
Expression.notIn(Column(Table(table), Activities._ID), filteredIdsQueryBuilder.build()),
|
||||
|
@ -626,36 +621,36 @@ object DataStoreUtils {
|
|||
}
|
||||
|
||||
@SuppressLint("Recycle")
|
||||
private fun <T> getFieldArray(context: Context, uri: Uri,
|
||||
keys: Array<UserKey?>, keyField: String,
|
||||
valueField: String, sortExpression: OrderBy?,
|
||||
extraHaving: Expression?, extraHavingArgs: Array<String>?,
|
||||
creator: FieldArrayCreator<T>): T {
|
||||
private fun <T> getFieldArray(
|
||||
context: Context, uri: Uri,
|
||||
keys: Array<UserKey?>, keyField: String,
|
||||
valueField: String, sortExpression: OrderBy?,
|
||||
extraWhere: Expression?, extraWhereArgs: Array<String>?,
|
||||
creator: FieldArrayCreator<T>
|
||||
): T {
|
||||
val resolver = context.contentResolver
|
||||
val resultArray = creator.newArray(keys.size)
|
||||
val nonNullKeys = keys.mapNotNull { it?.toString() }.toTypedArray()
|
||||
val tableName = getTableNameByUri(uri) ?: throw NullPointerException()
|
||||
val having: Expression
|
||||
if (extraHaving != null) {
|
||||
having = Expression.and(extraHaving, Expression.inArgs(keyField, nonNullKeys.size))
|
||||
val having = Expression.inArgs(keyField, nonNullKeys.size)
|
||||
val bindingArgs: Array<String>
|
||||
if (extraWhereArgs != null) {
|
||||
bindingArgs = extraWhereArgs + nonNullKeys
|
||||
} else {
|
||||
having = Expression.inArgs(keyField, nonNullKeys.size)
|
||||
}
|
||||
val havingArgs: Array<String>
|
||||
if (extraHavingArgs != null) {
|
||||
havingArgs = extraHavingArgs + nonNullKeys
|
||||
} else {
|
||||
havingArgs = nonNullKeys
|
||||
bindingArgs = nonNullKeys
|
||||
}
|
||||
val builder = SQLQueryBuilder.select(Columns(keyField, valueField))
|
||||
.from(Table(tableName))
|
||||
.groupBy(Column(keyField))
|
||||
.having(having)
|
||||
builder.from(Table(tableName))
|
||||
if (extraWhere != null) {
|
||||
builder.where(extraWhere)
|
||||
}
|
||||
builder.groupBy(Column(keyField))
|
||||
builder.having(having)
|
||||
if (sortExpression != null) {
|
||||
builder.orderBy(sortExpression)
|
||||
}
|
||||
val rawUri = Uri.withAppendedPath(TwidereDataStore.CONTENT_URI_RAW_QUERY, builder.buildSQL())
|
||||
resolver.query(rawUri, null, null, havingArgs, null)?.useCursor { cur ->
|
||||
resolver.query(rawUri, null, null, bindingArgs, null)?.useCursor { cur ->
|
||||
cur.moveToFirst()
|
||||
while (!cur.isAfterLast) {
|
||||
val string = cur.getString(0)
|
||||
|
|
|
@ -70,8 +70,10 @@ class TaskServiceRunner(
|
|||
}
|
||||
ACTION_REFRESH_DIRECT_MESSAGES -> {
|
||||
val task = GetMessagesTask(context)
|
||||
task.params = AutoRefreshTaskParam(context, AccountPreferences::isAutoRefreshDirectMessagesEnabled) { accountKeys ->
|
||||
arrayOfNulls(accountKeys.size)
|
||||
task.params = GetMessagesTask.RefreshNewTaskParam(context) {
|
||||
AccountPreferences.getAccountPreferences(context, DataStoreUtils.getAccountKeys(context)).filter {
|
||||
it.isAutoRefreshEnabled && it.isAutoRefreshDirectMessagesEnabled
|
||||
}.map(AccountPreferences::getAccountKey).toTypedArray()
|
||||
}
|
||||
return task
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue