fixed source file name
This commit is contained in:
parent
fda48b3b9e
commit
43a80bdb70
|
@ -37,6 +37,13 @@ public class NewDm extends SimpleValueMap {
|
||||||
put("conversation_id", conversationId);
|
put("conversation_id", conversationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help you identify which is new message, this id will be attached in request result
|
||||||
|
*/
|
||||||
|
public void setRequestId(String requestId) {
|
||||||
|
put("request_id", requestId);
|
||||||
|
}
|
||||||
|
|
||||||
public void setRecipientIds(String[] recipientIds) {
|
public void setRecipientIds(String[] recipientIds) {
|
||||||
put("recipient_ids", InternalArrayUtil.join(recipientIds, ","));
|
put("recipient_ids", InternalArrayUtil.join(recipientIds, ","));
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
||||||
String QUERY_PARAM_NEW_ITEMS_COUNT = "new_items_count";
|
String QUERY_PARAM_NEW_ITEMS_COUNT = "new_items_count";
|
||||||
String QUERY_PARAM_CONVERSATION_ID = "conversation_id";
|
String QUERY_PARAM_CONVERSATION_ID = "conversation_id";
|
||||||
String QUERY_PARAM_READ_POSITION = "param_read_position";
|
String QUERY_PARAM_READ_POSITION = "param_read_position";
|
||||||
String QUERY_PARAM_READ_POSITIONS = "param_read_positions";
|
|
||||||
String QUERY_PARAM_LIMIT = "limit";
|
String QUERY_PARAM_LIMIT = "limit";
|
||||||
String QUERY_PARAM_EXTRA = "extra";
|
String QUERY_PARAM_EXTRA = "extra";
|
||||||
String QUERY_PARAM_TIMESTAMP = "timestamp";
|
String QUERY_PARAM_TIMESTAMP = "timestamp";
|
||||||
|
|
|
@ -142,6 +142,10 @@ public class ParcelableMessageConversation implements Parcelable {
|
||||||
@CursorField(value = Conversations.REQUEST_CURSOR)
|
@CursorField(value = Conversations.REQUEST_CURSOR)
|
||||||
public String request_cursor;
|
public String request_cursor;
|
||||||
|
|
||||||
|
@JsonField(name = "last_read_id")
|
||||||
|
@CursorField(value = Conversations.LAST_READ_ID)
|
||||||
|
public String last_read_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if this is a temporary conversation, i.e. Created by user but haven't send any message
|
* True if this is a temporary conversation, i.e. Created by user but haven't send any message
|
||||||
* yet.
|
* yet.
|
||||||
|
|
|
@ -382,6 +382,7 @@ public interface TwidereDataStore {
|
||||||
String SENDER_KEY = "sender_key";
|
String SENDER_KEY = "sender_key";
|
||||||
String RECIPIENT_KEY = "recipient_key";
|
String RECIPIENT_KEY = "recipient_key";
|
||||||
String REQUEST_CURSOR = "request_cursor";
|
String REQUEST_CURSOR = "request_cursor";
|
||||||
|
String LAST_READ_ID = "last_read_id";
|
||||||
String IS_OUTGOING = "is_outgoing";
|
String IS_OUTGOING = "is_outgoing";
|
||||||
String IS_TEMP = "is_temp";
|
String IS_TEMP = "is_temp";
|
||||||
String CONVERSATION_EXTRAS = "conversation_extras";
|
String CONVERSATION_EXTRAS = "conversation_extras";
|
||||||
|
|
|
@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING;
|
||||||
public interface Constants extends TwidereConstants {
|
public interface Constants extends TwidereConstants {
|
||||||
|
|
||||||
String DATABASES_NAME = "twidere.sqlite";
|
String DATABASES_NAME = "twidere.sqlite";
|
||||||
int DATABASES_VERSION = 176;
|
int DATABASES_VERSION = 177;
|
||||||
|
|
||||||
int EXTRA_FEATURES_NOTICE_VERSION = 0;
|
int EXTRA_FEATURES_NOTICE_VERSION = 0;
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,11 @@ package org.mariotaku.twidere.extension
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.net.Uri
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore
|
import org.mariotaku.twidere.provider.TwidereDataStore
|
||||||
|
|
||||||
@SuppressLint("Recycle")
|
@SuppressLint("Recycle")
|
||||||
fun ContentResolver.rawQuery(sql: String, selectionArgs: Array<String>?): Cursor {
|
fun ContentResolver.rawQuery(sql: String, selectionArgs: Array<String>?): Cursor? {
|
||||||
val rawUri = Uri.withAppendedPath(TwidereDataStore.CONTENT_URI_RAW_QUERY, sql)
|
val rawUri = TwidereDataStore.CONTENT_URI_RAW_QUERY.buildUpon().appendPath(sql).build()
|
||||||
return query(rawUri, null, null, selectionArgs, null)
|
return query(rawUri, null, null, selectionArgs, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,7 +541,6 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
|
||||||
val prefs = AccountPreferences.getNotificationEnabledPreferences(context,
|
val prefs = AccountPreferences.getNotificationEnabledPreferences(context,
|
||||||
DataStoreUtils.getAccountKeys(context))
|
DataStoreUtils.getAccountKeys(context))
|
||||||
prefs.filter(AccountPreferences::isDirectMessagesNotificationEnabled).forEach {
|
prefs.filter(AccountPreferences::isDirectMessagesNotificationEnabled).forEach {
|
||||||
val pairs = readStateManager.getPositionPairs(CustomTabType.DIRECT_MESSAGES)
|
|
||||||
// TODO show messages notifications
|
// TODO show messages notifications
|
||||||
}
|
}
|
||||||
notifyUnreadCountChanged(NOTIFICATION_ID_DIRECT_MESSAGES)
|
notifyUnreadCountChanged(NOTIFICATION_ID_DIRECT_MESSAGES)
|
||||||
|
|
|
@ -64,23 +64,12 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||||
}
|
}
|
||||||
val manager = holder.readStateManager
|
val manager = holder.readStateManager
|
||||||
val paramReadPosition = uri.getQueryParameter(QUERY_PARAM_READ_POSITION)
|
val paramReadPosition = uri.getQueryParameter(QUERY_PARAM_READ_POSITION)
|
||||||
val paramReadPositions = uri.getQueryParameter(QUERY_PARAM_READ_POSITIONS)
|
|
||||||
@ReadPositionTag
|
@ReadPositionTag
|
||||||
val tag = getPositionTag(notificationType)
|
val tag = getPositionTag(notificationType)
|
||||||
|
|
||||||
if (tag != null && !TextUtils.isEmpty(paramReadPosition)) {
|
if (tag != null && !TextUtils.isEmpty(paramReadPosition)) {
|
||||||
manager.setPosition(Utils.getReadPositionTagWithAccount(tag, accountKey),
|
manager.setPosition(Utils.getReadPositionTagWithAccount(tag, accountKey),
|
||||||
paramReadPosition.toLong(-1))
|
paramReadPosition.toLong(-1))
|
||||||
} else if (!TextUtils.isEmpty(paramReadPositions)) {
|
|
||||||
try {
|
|
||||||
val pairs = StringLongPair.valuesOf(paramReadPositions)
|
|
||||||
for (pair in pairs) {
|
|
||||||
manager.setPosition(tag!!, pair.key, pair.value)
|
|
||||||
}
|
|
||||||
} catch (ignore: NumberFormatException) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,23 +24,31 @@ import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.ktextension.toInt
|
import org.mariotaku.ktextension.toInt
|
||||||
import org.mariotaku.ktextension.useCursor
|
import org.mariotaku.ktextension.useCursor
|
||||||
|
import org.mariotaku.microblog.library.MicroBlog
|
||||||
|
import org.mariotaku.microblog.library.MicroBlogException
|
||||||
import org.mariotaku.microblog.library.twitter.model.DMResponse
|
import org.mariotaku.microblog.library.twitter.model.DMResponse
|
||||||
|
import org.mariotaku.microblog.library.twitter.model.Paging
|
||||||
import org.mariotaku.microblog.library.twitter.model.User
|
import org.mariotaku.microblog.library.twitter.model.User
|
||||||
import org.mariotaku.microblog.library.twitter.model.fixMedia
|
import org.mariotaku.microblog.library.twitter.model.fixMedia
|
||||||
import org.mariotaku.sqliteqb.library.Expression
|
import org.mariotaku.sqliteqb.library.Expression
|
||||||
|
import org.mariotaku.twidere.annotation.AccountType
|
||||||
import org.mariotaku.twidere.extension.model.applyFrom
|
import org.mariotaku.twidere.extension.model.applyFrom
|
||||||
import org.mariotaku.twidere.extension.model.isOfficial
|
import org.mariotaku.twidere.extension.model.isOfficial
|
||||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||||
import org.mariotaku.twidere.extension.model.timestamp
|
import org.mariotaku.twidere.extension.model.timestamp
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.*
|
||||||
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
|
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
|
||||||
|
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
||||||
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
|
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
|
||||||
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
|
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.ParcelableUserUtils
|
||||||
import org.mariotaku.twidere.model.util.UserKeyUtils
|
import org.mariotaku.twidere.model.util.UserKeyUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
import org.mariotaku.twidere.task.BaseAbstractTask
|
import org.mariotaku.twidere.task.BaseAbstractTask
|
||||||
|
import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -56,10 +64,10 @@ class GetMessagesTask(
|
||||||
val am = android.accounts.AccountManager.get(context)
|
val am = android.accounts.AccountManager.get(context)
|
||||||
accountKeys.forEachIndexed { i, accountKey ->
|
accountKeys.forEachIndexed { i, accountKey ->
|
||||||
val details = getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
|
val details = getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
|
||||||
val microBlog = details.newMicroBlogInstance(context, true, cls = org.mariotaku.microblog.library.MicroBlog::class.java)
|
val microBlog = details.newMicroBlogInstance(context, true, cls = MicroBlog::class.java)
|
||||||
val messages = try {
|
val messages = try {
|
||||||
getMessages(microBlog, details, param, i)
|
getMessages(microBlog, details, param, i)
|
||||||
} catch (e: org.mariotaku.microblog.library.MicroBlogException) {
|
} catch (e: MicroBlogException) {
|
||||||
return@forEachIndexed
|
return@forEachIndexed
|
||||||
}
|
}
|
||||||
Companion.storeMessages(context, messages, details)
|
Companion.storeMessages(context, messages, details)
|
||||||
|
@ -68,16 +76,16 @@ class GetMessagesTask(
|
||||||
|
|
||||||
override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Unit) {
|
override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Unit) {
|
||||||
callback?.invoke(true)
|
callback?.invoke(true)
|
||||||
bus.post(org.mariotaku.twidere.model.event.GetMessagesTaskEvent(Messages.CONTENT_URI, params?.taskTag, false, null))
|
bus.post(GetMessagesTaskEvent(Messages.CONTENT_URI, params?.taskTag, false, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
when (details.type) {
|
when (details.type) {
|
||||||
org.mariotaku.twidere.annotation.AccountType.FANFOU -> {
|
AccountType.FANFOU -> {
|
||||||
// Use fanfou DM api, disabled since it's conversation api is not suitable for paging
|
// Use fanfou DM api, disabled since it's conversation api is not suitable for paging
|
||||||
// return getFanfouMessages(microBlog, details, param, index)
|
// return getFanfouMessages(microBlog, details, param, index)
|
||||||
}
|
}
|
||||||
org.mariotaku.twidere.annotation.AccountType.TWITTER -> {
|
AccountType.TWITTER -> {
|
||||||
// Use official DM api
|
// Use official DM api
|
||||||
if (details.isOfficial(context)) {
|
if (details.isOfficial(context)) {
|
||||||
return getTwitterOfficialMessages(microBlog, details, param, index)
|
return getTwitterOfficialMessages(microBlog, details, param, index)
|
||||||
|
@ -88,7 +96,7 @@ class GetMessagesTask(
|
||||||
return getDefaultMessages(microBlog, details, param, index)
|
return getDefaultMessages(microBlog, details, param, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialMessages(microBlog: MicroBlog, details: AccountDetails,
|
||||||
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val conversationId = param.conversationId
|
val conversationId = param.conversationId
|
||||||
if (conversationId == null) {
|
if (conversationId == null) {
|
||||||
|
@ -98,7 +106,7 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFanfouMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getFanfouMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val conversationId = param.conversationId
|
val conversationId = param.conversationId
|
||||||
if (conversationId == null) {
|
if (conversationId == null) {
|
||||||
return getFanfouConversations(microBlog, details, param, index)
|
return getFanfouConversations(microBlog, details, param, index)
|
||||||
|
@ -107,13 +115,13 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDefaultMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getDefaultMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val accountKey = details.key
|
val accountKey = details.key
|
||||||
|
|
||||||
val sinceIds = if (param.hasSinceIds) param.sinceIds else null
|
val sinceIds = if (param.hasSinceIds) param.sinceIds else null
|
||||||
val maxIds = if (param.hasMaxIds) param.maxIds else null
|
val maxIds = if (param.hasMaxIds) param.maxIds else null
|
||||||
|
|
||||||
val received = microBlog.getDirectMessages(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
val received = microBlog.getDirectMessages(Paging().apply {
|
||||||
count(100)
|
count(100)
|
||||||
val maxId = maxIds?.get(index)
|
val maxId = maxIds?.get(index)
|
||||||
val sinceId = sinceIds?.get(index)
|
val sinceId = sinceIds?.get(index)
|
||||||
|
@ -124,7 +132,7 @@ class GetMessagesTask(
|
||||||
sinceId(sinceId)
|
sinceId(sinceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
val sent = microBlog.getSentDirectMessages(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
val sent = microBlog.getSentDirectMessages(Paging().apply {
|
||||||
count(100)
|
count(100)
|
||||||
val accountsCount = param.accountKeys.size
|
val accountsCount = param.accountKeys.size
|
||||||
val maxId = maxIds?.get(accountsCount + index)
|
val maxId = maxIds?.get(accountsCount + index)
|
||||||
|
@ -143,22 +151,22 @@ class GetMessagesTask(
|
||||||
|
|
||||||
val conversationIds = hashSetOf<String>()
|
val conversationIds = hashSetOf<String>()
|
||||||
received.forEach {
|
received.forEach {
|
||||||
conversationIds.add(org.mariotaku.twidere.model.util.ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
||||||
}
|
}
|
||||||
sent.forEach {
|
sent.forEach {
|
||||||
conversationIds.add(org.mariotaku.twidere.model.util.ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId))
|
conversationIds.add(ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId))
|
||||||
}
|
}
|
||||||
|
|
||||||
conversations.addLocalConversations(context, accountKey, conversationIds)
|
conversations.addLocalConversations(context, accountKey, conversationIds)
|
||||||
|
|
||||||
received.forEachIndexed { i, dm ->
|
received.forEachIndexed { i, dm ->
|
||||||
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, false,
|
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, false,
|
||||||
1.0 - (i.toDouble() / received.size))
|
1.0 - (i.toDouble() / received.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
||||||
}
|
}
|
||||||
sent.forEachIndexed { i, dm ->
|
sent.forEachIndexed { i, dm ->
|
||||||
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, true,
|
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, true,
|
||||||
1.0 - (i.toDouble() / sent.size))
|
1.0 - (i.toDouble() / sent.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
||||||
|
@ -166,10 +174,10 @@ class GetMessagesTask(
|
||||||
return DatabaseUpdateData(conversations.values, insertMessages)
|
return DatabaseUpdateData(conversations.values, insertMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialConversation(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialConversation(microBlog: MicroBlog, details: AccountDetails,
|
||||||
conversationId: String, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
conversationId: String, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val maxId = param.maxIds?.get(index) ?: return DatabaseUpdateData(emptyList(), emptyList())
|
val maxId = param.maxIds?.get(index) ?: return DatabaseUpdateData(emptyList(), emptyList())
|
||||||
val paging = org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
val paging = Paging().apply {
|
||||||
maxId(maxId)
|
maxId(maxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,14 +186,14 @@ class GetMessagesTask(
|
||||||
return Companion.createDatabaseUpdateData(context, details, response)
|
return Companion.createDatabaseUpdateData(context, details, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialUserInbox(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialUserInbox(microBlog: MicroBlog, details: AccountDetails,
|
||||||
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val maxId = if (param.hasMaxIds) param.maxIds?.get(index) else null
|
val maxId = if (param.hasMaxIds) param.maxIds?.get(index) else null
|
||||||
val cursor = if (param.hasCursors) param.cursors?.get(index) else null
|
val cursor = if (param.hasCursors) param.cursors?.get(index) else null
|
||||||
val response = if (cursor != null) {
|
val response = if (cursor != null) {
|
||||||
microBlog.getUserUpdates(cursor).userEvents
|
microBlog.getUserUpdates(cursor).userEvents
|
||||||
} else {
|
} else {
|
||||||
microBlog.getUserInbox(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
microBlog.getUserInbox(Paging().apply {
|
||||||
if (maxId != null) {
|
if (maxId != null) {
|
||||||
maxId(maxId)
|
maxId(maxId)
|
||||||
}
|
}
|
||||||
|
@ -196,11 +204,11 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getFanfouConversations(microBlog: org.mariotaku.microblog.library.MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getFanfouConversations(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
||||||
val accountKey = details.key
|
val accountKey = details.key
|
||||||
val cursor = param.cursors?.get(index)
|
val cursor = param.cursors?.get(index)
|
||||||
val page = cursor?.substringAfter("page:").toInt(-1)
|
val page = cursor?.substringAfter("page:").toInt(-1)
|
||||||
val result = microBlog.getConversationList(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
val result = microBlog.getConversationList(Paging().apply {
|
||||||
count(60)
|
count(60)
|
||||||
if (page >= 0) {
|
if (page >= 0) {
|
||||||
page(page)
|
page(page)
|
||||||
|
@ -214,7 +222,7 @@ class GetMessagesTask(
|
||||||
result.forEachIndexed { i, item ->
|
result.forEachIndexed { i, item ->
|
||||||
val dm = item.dm
|
val dm = item.dm
|
||||||
// Sender is our self, treat as outgoing message
|
// Sender is our self, treat as outgoing message
|
||||||
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, dm.senderId == accountKey.id,
|
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, dm.senderId == accountKey.id,
|
||||||
1.0 - (i.toDouble() / result.size))
|
1.0 - (i.toDouble() / result.size))
|
||||||
val mc = conversations.addConversation(message.conversation_id, details, message,
|
val mc = conversations.addConversation(message.conversation_id, details, message,
|
||||||
setOf(dm.sender, dm.recipient))
|
setOf(dm.sender, dm.recipient))
|
||||||
|
@ -237,9 +245,9 @@ class GetMessagesTask(
|
||||||
|
|
||||||
override val sinceIds: Array<String?>?
|
override val sinceIds: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val incomingIds = org.mariotaku.twidere.util.DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
||||||
defaultKeys, false)
|
defaultKeys, false)
|
||||||
val outgoingIds = org.mariotaku.twidere.util.DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
||||||
defaultKeys, true)
|
defaultKeys, true)
|
||||||
return incomingIds + outgoingIds
|
return incomingIds + outgoingIds
|
||||||
}
|
}
|
||||||
|
@ -247,7 +255,7 @@ class GetMessagesTask(
|
||||||
override val cursors: Array<String?>?
|
override val cursors: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val cursors = arrayOfNulls<String>(defaultKeys.size)
|
val cursors = arrayOfNulls<String>(defaultKeys.size)
|
||||||
val newestConversations = org.mariotaku.twidere.util.DataStoreUtils.getNewestConversations(context,
|
val newestConversations = DataStoreUtils.getNewestConversations(context,
|
||||||
Conversations.CONTENT_URI, twitterOfficialKeys)
|
Conversations.CONTENT_URI, twitterOfficialKeys)
|
||||||
newestConversations.forEachIndexed { i, conversation ->
|
newestConversations.forEachIndexed { i, conversation ->
|
||||||
cursors[i] = conversation?.request_cursor
|
cursors[i] = conversation?.request_cursor
|
||||||
|
@ -265,11 +273,11 @@ class GetMessagesTask(
|
||||||
) : RefreshMessagesTaskParam(context) {
|
) : RefreshMessagesTaskParam(context) {
|
||||||
|
|
||||||
override val maxIds: Array<String?>? by lazy {
|
override val maxIds: Array<String?>? by lazy {
|
||||||
val incomingIds = org.mariotaku.twidere.util.DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
val incomingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
||||||
defaultKeys, false)
|
defaultKeys, false)
|
||||||
val outgoingIds = org.mariotaku.twidere.util.DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
val outgoingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
||||||
defaultKeys, true)
|
defaultKeys, true)
|
||||||
val oldestConversations = org.mariotaku.twidere.util.DataStoreUtils.getOldestConversations(context,
|
val oldestConversations = DataStoreUtils.getOldestConversations(context,
|
||||||
Conversations.CONTENT_URI, twitterOfficialKeys)
|
Conversations.CONTENT_URI, twitterOfficialKeys)
|
||||||
oldestConversations.forEachIndexed { i, conversation ->
|
oldestConversations.forEachIndexed { i, conversation ->
|
||||||
val extras = conversation?.conversation_extras as? TwitterOfficialConversationExtras ?: return@forEachIndexed
|
val extras = conversation?.conversation_extras as? TwitterOfficialConversationExtras ?: return@forEachIndexed
|
||||||
|
@ -305,13 +313,13 @@ class GetMessagesTask(
|
||||||
var taskTag: String? = null
|
var taskTag: String? = null
|
||||||
|
|
||||||
protected val accounts: Array<AccountDetails?> by lazy {
|
protected val accounts: Array<AccountDetails?> by lazy {
|
||||||
org.mariotaku.twidere.model.util.AccountUtils.getAllAccountDetails(android.accounts.AccountManager.get(context), accountKeys, false)
|
AccountUtils.getAllAccountDetails(android.accounts.AccountManager.get(context), accountKeys, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val defaultKeys: Array<UserKey?>by lazy {
|
protected val defaultKeys: Array<UserKey?>by lazy {
|
||||||
return@lazy accounts.map { account ->
|
return@lazy accounts.map { account ->
|
||||||
account ?: return@map null
|
account ?: return@map null
|
||||||
if (account.isOfficial(context) || account.type == org.mariotaku.twidere.annotation.AccountType.FANFOU) {
|
if (account.isOfficial(context) || account.type == AccountType.FANFOU) {
|
||||||
return@map null
|
return@map null
|
||||||
}
|
}
|
||||||
return@map account.key
|
return@map account.key
|
||||||
|
@ -358,7 +366,7 @@ class GetMessagesTask(
|
||||||
return@mapNotNullTo null
|
return@mapNotNullTo null
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
return@mapNotNullTo org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromEntry(account.key, entry, respUsers)
|
return@mapNotNullTo ParcelableMessageUtils.fromEntry(account.key, entry, respUsers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,6 +387,7 @@ class GetMessagesTask(
|
||||||
conversation.conversation_avatar = v.avatarImageHttps
|
conversation.conversation_avatar = v.avatarImageHttps
|
||||||
conversation.request_cursor = response.cursor
|
conversation.request_cursor = response.cursor
|
||||||
conversation.conversation_extras_type = ParcelableMessageConversation.ExtrasType.TWITTER_OFFICIAL
|
conversation.conversation_extras_type = ParcelableMessageConversation.ExtrasType.TWITTER_OFFICIAL
|
||||||
|
conversation.last_read_id = v.lastReadEventId
|
||||||
conversation.conversation_extras = TwitterOfficialConversationExtras().apply {
|
conversation.conversation_extras = TwitterOfficialConversationExtras().apply {
|
||||||
this.minEntryId = v.minEntryId
|
this.minEntryId = v.minEntryId
|
||||||
this.maxEntryId = v.maxEntryId
|
this.maxEntryId = v.maxEntryId
|
|
@ -38,10 +38,10 @@ import org.mariotaku.twidere.model.event.SendMessageTaskEvent
|
||||||
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask
|
import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
||||||
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addConversation
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addConversation
|
||||||
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addLocalConversations
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addLocalConversations
|
||||||
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 2017/2/8.
|
* Created by mariotaku on 2017/2/8.
|
||||||
|
@ -88,7 +88,8 @@ class SendMessageTask(
|
||||||
return sendDefaultDM(microBlog, account, message)
|
return sendDefaultDM(microBlog, account, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendTwitterOfficialDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
private fun sendTwitterOfficialDM(microBlog: MicroBlog, account: AccountDetails,
|
||||||
|
message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
||||||
var deleteOnSuccess: List<UpdateStatusTask.MediaDeletionItem>? = null
|
var deleteOnSuccess: List<UpdateStatusTask.MediaDeletionItem>? = null
|
||||||
var deleteAlways: List<UpdateStatusTask.MediaDeletionItem>? = null
|
var deleteAlways: List<UpdateStatusTask.MediaDeletionItem>? = null
|
||||||
val sendResponse = try {
|
val sendResponse = try {
|
||||||
|
|
|
@ -43,7 +43,6 @@ import org.mariotaku.twidere.constant.nameFirstKey
|
||||||
import org.mariotaku.twidere.extension.rawQuery
|
import org.mariotaku.twidere.extension.rawQuery
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.*
|
||||||
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
|
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||||
import org.mariotaku.twidere.receiver.NotificationReceiver
|
import org.mariotaku.twidere.receiver.NotificationReceiver
|
||||||
|
@ -65,6 +64,81 @@ class ContentNotificationManager(
|
||||||
private var nameFirst: Boolean = false
|
private var nameFirst: Boolean = false
|
||||||
private var useStarForLikes: Boolean = false
|
private var useStarForLikes: Boolean = false
|
||||||
|
|
||||||
|
fun showTimeline(pref: AccountPreferences, minPositionKey: Long) {
|
||||||
|
val accountKey = pref.accountKey
|
||||||
|
val resources = context.resources
|
||||||
|
val nm = notificationManager
|
||||||
|
val selection = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_KEY),
|
||||||
|
Expression.greaterThan(Statuses.POSITION_KEY, minPositionKey))
|
||||||
|
val filteredSelection = buildStatusFilterWhereClause(preferences, Statuses.TABLE_NAME,
|
||||||
|
selection)
|
||||||
|
val selectionArgs = arrayOf(accountKey.toString())
|
||||||
|
val userProjection = arrayOf(Statuses.USER_KEY, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME)
|
||||||
|
val statusProjection = arrayOf(Statuses.POSITION_KEY)
|
||||||
|
val statusCursor = context.contentResolver.query(Statuses.CONTENT_URI, statusProjection,
|
||||||
|
filteredSelection.sql, selectionArgs, Statuses.DEFAULT_SORT_ORDER) ?: return
|
||||||
|
|
||||||
|
val userCursor = context.contentResolver.rawQuery(SQLQueryBuilder.select(Columns(*userProjection))
|
||||||
|
.from(Table(Statuses.TABLE_NAME))
|
||||||
|
.where(filteredSelection)
|
||||||
|
.groupBy(Columns.Column(Statuses.USER_KEY))
|
||||||
|
.orderBy(OrderBy(Statuses.DEFAULT_SORT_ORDER)).buildSQL(), selectionArgs) ?: return
|
||||||
|
|
||||||
|
try {
|
||||||
|
val usersCount = userCursor.count
|
||||||
|
val statusesCount = statusCursor.count
|
||||||
|
if (statusesCount == 0 || usersCount == 0) return
|
||||||
|
val statusIndices = ParcelableStatusCursorIndices(statusCursor)
|
||||||
|
val userIndices = ParcelableStatusCursorIndices(userCursor)
|
||||||
|
val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices.position_key) else -1L
|
||||||
|
val notificationTitle = resources.getQuantityString(R.plurals.N_new_statuses,
|
||||||
|
statusesCount, statusesCount)
|
||||||
|
val notificationContent: String
|
||||||
|
userCursor.moveToFirst()
|
||||||
|
val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key),
|
||||||
|
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name),
|
||||||
|
nameFirst)
|
||||||
|
if (usersCount == 1) {
|
||||||
|
notificationContent = context.getString(R.string.from_name, displayName)
|
||||||
|
} else if (usersCount == 2) {
|
||||||
|
userCursor.moveToPosition(1)
|
||||||
|
val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key),
|
||||||
|
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name),
|
||||||
|
nameFirst)
|
||||||
|
notificationContent = resources.getString(R.string.from_name_and_name, displayName, othersName)
|
||||||
|
} else {
|
||||||
|
notificationContent = resources.getString(R.string.from_name_and_N_others, displayName, usersCount - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup notification
|
||||||
|
val builder = NotificationCompat.Builder(context)
|
||||||
|
builder.setAutoCancel(true)
|
||||||
|
builder.setSmallIcon(R.drawable.ic_stat_twitter)
|
||||||
|
builder.setTicker(notificationTitle)
|
||||||
|
builder.setContentTitle(notificationTitle)
|
||||||
|
builder.setContentText(notificationContent)
|
||||||
|
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
||||||
|
builder.setContentIntent(getContentIntent(context, CustomTabType.HOME_TIMELINE,
|
||||||
|
NotificationType.HOME_TIMELINE, accountKey, positionKey))
|
||||||
|
builder.setDeleteIntent(getMarkReadDeleteIntent(context, NotificationType.HOME_TIMELINE,
|
||||||
|
accountKey, positionKey, false))
|
||||||
|
builder.setNumber(statusesCount)
|
||||||
|
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
||||||
|
applyNotificationPreferences(builder, pref, pref.homeTimelineNotificationType)
|
||||||
|
try {
|
||||||
|
nm.notify("home_" + accountKey, Utils.getNotificationId(NOTIFICATION_ID_HOME_TIMELINE, accountKey), builder.build())
|
||||||
|
Utils.sendPebbleNotification(context, null, notificationContent)
|
||||||
|
} catch (e: SecurityException) {
|
||||||
|
// Silently ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
statusCursor.close()
|
||||||
|
userCursor.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun showInteractions(pref: AccountPreferences, position: Long) {
|
fun showInteractions(pref: AccountPreferences, position: Long) {
|
||||||
val cr = context.contentResolver
|
val cr = context.contentResolver
|
||||||
val accountKey = pref.accountKey
|
val accountKey = pref.accountKey
|
||||||
|
@ -163,12 +237,9 @@ class ContentNotificationManager(
|
||||||
}
|
}
|
||||||
val notificationId = Utils.getNotificationId(NOTIFICATION_ID_INTERACTIONS_TIMELINE, accountKey)
|
val notificationId = Utils.getNotificationId(NOTIFICATION_ID_INTERACTIONS_TIMELINE, accountKey)
|
||||||
notificationManager.notify("interactions", notificationId, builder.build())
|
notificationManager.notify("interactions", notificationId, builder.build())
|
||||||
|
Utils.sendPebbleNotification(context, context.getString(R.string.interactions), pebbleNotificationStringBuilder.toString())
|
||||||
Utils.sendPebbleNotification(context, context.resources.getString(R.string.interactions), pebbleNotificationStringBuilder.toString())
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun applyNotificationPreferences(builder: NotificationCompat.Builder, pref: AccountPreferences, defaultFlags: Int) {
|
private fun applyNotificationPreferences(builder: NotificationCompat.Builder, pref: AccountPreferences, defaultFlags: Int) {
|
||||||
var notificationDefaults = 0
|
var notificationDefaults = 0
|
||||||
if (AccountPreferences.isNotificationHasLight(defaultFlags)) {
|
if (AccountPreferences.isNotificationHasLight(defaultFlags)) {
|
||||||
|
@ -195,80 +266,6 @@ class ContentNotificationManager(
|
||||||
return !activityTracker.isHomeActivityStarted
|
return !activityTracker.isHomeActivityStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showTimeline(pref: AccountPreferences, position: Long) {
|
|
||||||
val accountKey = pref.accountKey
|
|
||||||
val resources = context.resources
|
|
||||||
val nm = notificationManager
|
|
||||||
val selection = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_KEY),
|
|
||||||
Expression.greaterThan(Statuses.POSITION_KEY, position))
|
|
||||||
val filteredSelection = buildStatusFilterWhereClause(preferences,
|
|
||||||
Statuses.TABLE_NAME, selection)
|
|
||||||
val selectionArgs = arrayOf(accountKey.toString())
|
|
||||||
val userProjection = arrayOf(Statuses.USER_KEY, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME)
|
|
||||||
val statusProjection = arrayOf(Statuses.POSITION_KEY)
|
|
||||||
val statusCursor = context.contentResolver.query(Statuses.CONTENT_URI, statusProjection,
|
|
||||||
filteredSelection.sql, selectionArgs, Statuses.DEFAULT_SORT_ORDER)
|
|
||||||
|
|
||||||
val userCursor = context.contentResolver.rawQuery(SQLQueryBuilder.select(Columns(*userProjection))
|
|
||||||
.from(Table(Statuses.TABLE_NAME))
|
|
||||||
.where(filteredSelection)
|
|
||||||
.groupBy(Columns.Column(Statuses.USER_KEY))
|
|
||||||
.orderBy(OrderBy(Statuses.DEFAULT_SORT_ORDER)).buildSQL(), selectionArgs)
|
|
||||||
|
|
||||||
try {
|
|
||||||
val usersCount = userCursor.count
|
|
||||||
val statusesCount = statusCursor.count
|
|
||||||
if (statusesCount == 0 || usersCount == 0) return
|
|
||||||
val statusIndices = ParcelableStatusCursorIndices(statusCursor)
|
|
||||||
val userIndices = ParcelableStatusCursorIndices(userCursor)
|
|
||||||
val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices.position_key) else -1L
|
|
||||||
val notificationTitle = resources.getQuantityString(R.plurals.N_new_statuses,
|
|
||||||
statusesCount, statusesCount)
|
|
||||||
val notificationContent: String
|
|
||||||
userCursor.moveToFirst()
|
|
||||||
val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key),
|
|
||||||
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name),
|
|
||||||
nameFirst)
|
|
||||||
if (usersCount == 1) {
|
|
||||||
notificationContent = context.getString(R.string.from_name, displayName)
|
|
||||||
} else if (usersCount == 2) {
|
|
||||||
userCursor.moveToPosition(1)
|
|
||||||
val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key),
|
|
||||||
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name),
|
|
||||||
nameFirst)
|
|
||||||
notificationContent = resources.getString(R.string.from_name_and_name, displayName, othersName)
|
|
||||||
} else {
|
|
||||||
notificationContent = resources.getString(R.string.from_name_and_N_others, displayName, usersCount - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup notification
|
|
||||||
val builder = NotificationCompat.Builder(context)
|
|
||||||
builder.setAutoCancel(true)
|
|
||||||
builder.setSmallIcon(R.drawable.ic_stat_twitter)
|
|
||||||
builder.setTicker(notificationTitle)
|
|
||||||
builder.setContentTitle(notificationTitle)
|
|
||||||
builder.setContentText(notificationContent)
|
|
||||||
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
|
||||||
builder.setContentIntent(getContentIntent(context, CustomTabType.HOME_TIMELINE,
|
|
||||||
NotificationType.HOME_TIMELINE, accountKey, positionKey))
|
|
||||||
builder.setDeleteIntent(getMarkReadDeleteIntent(context, NotificationType.HOME_TIMELINE,
|
|
||||||
accountKey, positionKey, false))
|
|
||||||
builder.setNumber(statusesCount)
|
|
||||||
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL)
|
|
||||||
applyNotificationPreferences(builder, pref, pref.homeTimelineNotificationType)
|
|
||||||
try {
|
|
||||||
nm.notify("home_" + accountKey, Utils.getNotificationId(NOTIFICATION_ID_HOME_TIMELINE, accountKey), builder.build())
|
|
||||||
Utils.sendPebbleNotification(context, null, notificationContent)
|
|
||||||
} catch (e: SecurityException) {
|
|
||||||
// Silently ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
statusCursor.close()
|
|
||||||
userCursor.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getContentIntent(context: Context, @CustomTabType type: String,
|
private fun getContentIntent(context: Context, @CustomTabType type: String,
|
||||||
@NotificationType notificationType: String, accountKey: UserKey?, readPosition: Long): PendingIntent {
|
@NotificationType notificationType: String, accountKey: UserKey?, readPosition: Long): PendingIntent {
|
||||||
|
@ -302,26 +299,6 @@ class ContentNotificationManager(
|
||||||
useStarForLikes = preferences[iWantMyStarsBackKey]
|
useStarForLikes = preferences[iWantMyStarsBackKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getMarkReadDeleteIntent(context: Context, @NotificationType notificationType: String,
|
|
||||||
accountKey: UserKey?, positions: Array<StringLongPair>): PendingIntent {
|
|
||||||
// Setup delete intent
|
|
||||||
val intent = Intent(context, NotificationReceiver::class.java)
|
|
||||||
val linkBuilder = Uri.Builder()
|
|
||||||
linkBuilder.scheme(SCHEME_TWIDERE)
|
|
||||||
linkBuilder.authority(AUTHORITY_INTERACTIONS)
|
|
||||||
linkBuilder.appendPath(notificationType)
|
|
||||||
if (accountKey != null) {
|
|
||||||
linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
|
|
||||||
}
|
|
||||||
linkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITIONS, StringLongPair.toString(positions))
|
|
||||||
linkBuilder.appendQueryParameter(QUERY_PARAM_TIMESTAMP, System.currentTimeMillis().toString())
|
|
||||||
linkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, notificationType)
|
|
||||||
intent.data = linkBuilder.build()
|
|
||||||
return PendingIntent.getBroadcast(context, 0, intent, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getMarkReadDeleteIntent(context: Context, @NotificationType type: String,
|
private fun getMarkReadDeleteIntent(context: Context, @NotificationType type: String,
|
||||||
accountKey: UserKey?, position: Long,
|
accountKey: UserKey?, position: Long,
|
||||||
extraUserFollowing: Boolean): PendingIntent {
|
extraUserFollowing: Boolean): PendingIntent {
|
||||||
|
|
|
@ -675,7 +675,7 @@ object DataStoreUtils {
|
||||||
if (sortExpression != null) {
|
if (sortExpression != null) {
|
||||||
builder.orderBy(sortExpression)
|
builder.orderBy(sortExpression)
|
||||||
}
|
}
|
||||||
resolver.rawQuery(builder.buildSQL(), bindingArgs).useCursor { cur ->
|
resolver.rawQuery(builder.buildSQL(), bindingArgs)?.useCursor { cur ->
|
||||||
cur.moveToFirst()
|
cur.moveToFirst()
|
||||||
val colIdx = creator.newIndex(cur)
|
val colIdx = creator.newIndex(cur)
|
||||||
while (!cur.isAfterLast) {
|
while (!cur.isAfterLast) {
|
||||||
|
|
|
@ -26,8 +26,6 @@ import org.mariotaku.twidere.TwidereConstants.TIMELINE_POSITIONS_PREFERENCES_NAM
|
||||||
import org.mariotaku.twidere.annotation.CustomTabType
|
import org.mariotaku.twidere.annotation.CustomTabType
|
||||||
import org.mariotaku.twidere.annotation.NotificationType
|
import org.mariotaku.twidere.annotation.NotificationType
|
||||||
import org.mariotaku.twidere.annotation.ReadPositionTag
|
import org.mariotaku.twidere.annotation.ReadPositionTag
|
||||||
import org.mariotaku.twidere.model.StringLongPair
|
|
||||||
import org.mariotaku.twidere.util.collection.CompactHashSet
|
|
||||||
|
|
||||||
class ReadStateManager(context: Context) {
|
class ReadStateManager(context: Context) {
|
||||||
|
|
||||||
|
@ -39,24 +37,6 @@ class ReadStateManager(context: Context) {
|
||||||
return preferences.getLong(key, -1)
|
return preferences.getLong(key, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPositionPairs(key: String): Array<StringLongPair> {
|
|
||||||
if (TextUtils.isEmpty(key)) return emptyArray()
|
|
||||||
val set = preferences.getStringSet(key, null) ?: return emptyArray()
|
|
||||||
try {
|
|
||||||
return set.map { StringLongPair.valueOf(it) }.toTypedArray()
|
|
||||||
} catch (e: NumberFormatException) {
|
|
||||||
return emptyArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPosition(key: String, keyId: String): Long {
|
|
||||||
if (TextUtils.isEmpty(key)) return -1
|
|
||||||
val set = preferences.getStringSet(key, null) ?: return -1
|
|
||||||
val prefix = keyId + ":"
|
|
||||||
val first = set.firstOrNull { it.startsWith(prefix) } ?: return -1
|
|
||||||
return StringLongPair.valueOf(first).value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun registerOnSharedPreferenceChangeListener(listener: OnSharedPreferenceChangeListener) {
|
fun registerOnSharedPreferenceChangeListener(listener: OnSharedPreferenceChangeListener) {
|
||||||
preferences.registerOnSharedPreferenceChangeListener(listener)
|
preferences.registerOnSharedPreferenceChangeListener(listener)
|
||||||
}
|
}
|
||||||
|
@ -65,46 +45,7 @@ class ReadStateManager(context: Context) {
|
||||||
preferences.unregisterOnSharedPreferenceChangeListener(listener)
|
preferences.unregisterOnSharedPreferenceChangeListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setPosition(key: String, keyId: String, position: Long, acceptOlder: Boolean = false): Boolean {
|
fun setPosition(key: String, position: Long, acceptOlder: Boolean = false): Boolean {
|
||||||
if (TextUtils.isEmpty(key)) return false
|
|
||||||
val set: MutableSet<String> = preferences.getStringSet(key, null) ?: CompactHashSet<String>()
|
|
||||||
val prefix = keyId + ":"
|
|
||||||
val keyValue: String? = set.firstOrNull { it.startsWith(prefix) }
|
|
||||||
val pair: StringLongPair
|
|
||||||
if (keyValue != null) {
|
|
||||||
// Found value
|
|
||||||
pair = StringLongPair.valueOf(keyValue)
|
|
||||||
if (!acceptOlder && pair.value > position) return false
|
|
||||||
set.remove(keyValue)
|
|
||||||
pair.value = position
|
|
||||||
} else {
|
|
||||||
pair = StringLongPair(keyId, position)
|
|
||||||
}
|
|
||||||
set.add(pair.toString())
|
|
||||||
val editor = preferences.edit()
|
|
||||||
editor.putStringSet(key, set)
|
|
||||||
editor.apply()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setPositionPairs(key: String, pairs: Array<StringLongPair>?): Boolean {
|
|
||||||
if (TextUtils.isEmpty(key)) return false
|
|
||||||
val editor = preferences.edit()
|
|
||||||
if (pairs == null) {
|
|
||||||
editor.remove(key)
|
|
||||||
} else {
|
|
||||||
val set = CompactHashSet<String>()
|
|
||||||
for (pair in pairs) {
|
|
||||||
set.add(pair.toString())
|
|
||||||
}
|
|
||||||
editor.putStringSet(key, set)
|
|
||||||
}
|
|
||||||
editor.apply()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmOverloads fun setPosition(key: String, position: Long, acceptOlder: Boolean = false): Boolean {
|
|
||||||
if (TextUtils.isEmpty(key) || !acceptOlder && getPosition(key) >= position) return false
|
if (TextUtils.isEmpty(key) || !acceptOlder && getPosition(key) >= position) return false
|
||||||
val editor = preferences.edit()
|
val editor = preferences.edit()
|
||||||
editor.putLong(key, position)
|
editor.putLong(key, position)
|
||||||
|
@ -112,10 +53,6 @@ class ReadStateManager(context: Context) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnReadStateChangeListener {
|
|
||||||
fun onReadStateChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@ReadPositionTag
|
@ReadPositionTag
|
||||||
|
|
|
@ -38,7 +38,7 @@ object FilterQueryBuilder {
|
||||||
val query = FilterQueryBuilder.isFilteredQuery(userKey,
|
val query = FilterQueryBuilder.isFilteredQuery(userKey,
|
||||||
textPlain, quotedTextPlain, spans, quotedSpans, source, quotedSource, retweetedByKey,
|
textPlain, quotedTextPlain, spans, quotedSpans, source, quotedSource, retweetedByKey,
|
||||||
quotedUserKey, true)
|
quotedUserKey, true)
|
||||||
val cur = cr.rawQuery(query.first, query.second)
|
val cur = cr.rawQuery(query.first, query.second) ?: return false
|
||||||
try {
|
try {
|
||||||
return cur.moveToFirst() && cur.getInt(0) != 0
|
return cur.moveToFirst() && cur.getInt(0) != 0
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in New Issue