From 1957cd87e0306c6c1f4caa8fa0c3b8ae5755d109 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Tue, 14 Feb 2017 15:27:28 +0800 Subject: [PATCH] supports send dm --- .../library/twitter/model/NewDm.java | 5 +++ .../twidere/model/ParcelableNewMessage.java | 4 +-- .../draft/SendDirectMessageActionExtras.java | 34 ++++++++++++------ .../fragment/MessagesConversationFragment.kt | 36 ++++++++++++++++++- .../service/LengthyOperationsService.kt | 12 +++++-- .../mariotaku/twidere/task/SendMessageTask.kt | 13 +++++-- .../twidere/util/ContentValuesCreator.kt | 22 ++---------- twidere/src/main/res/values/strings.xml | 1 + 8 files changed, 89 insertions(+), 38 deletions(-) diff --git a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/NewDm.java b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/NewDm.java index 7f661fe3e..d9558ae8b 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/NewDm.java +++ b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/NewDm.java @@ -21,6 +21,7 @@ package org.mariotaku.microblog.library.twitter.model; +import org.mariotaku.microblog.library.twitter.util.InternalArrayUtil; import org.mariotaku.restfu.http.SimpleValueMap; /** @@ -36,6 +37,10 @@ public class NewDm extends SimpleValueMap { put("conversation_id", conversationId); } + public void setRecipientIds(String[] recipientIds) { + put("conversation_ids", InternalArrayUtil.join(recipientIds, ",")); + } + public void setMediaId(long mediaId) { put("media_id", mediaId); } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableNewMessage.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableNewMessage.java index b92809164..b7152e41d 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableNewMessage.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableNewMessage.java @@ -42,9 +42,9 @@ public class ParcelableNewMessage implements Parcelable { @JsonField(name = "conversation_id") @ParcelableThisPlease public String conversation_id; - @JsonField(name = "recipient_id") + @JsonField(name = "recipient_ids") @ParcelableThisPlease - public String recipient_id; + public String[] recipient_ids; @JsonField(name = "text") @ParcelableThisPlease public String text; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/SendDirectMessageActionExtras.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/SendDirectMessageActionExtras.java index 8766e4d64..36ba0f877 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/SendDirectMessageActionExtras.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/draft/SendDirectMessageActionExtras.java @@ -28,6 +28,8 @@ import com.bluelinelabs.logansquare.annotation.JsonObject; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; +import java.util.Arrays; + /** * Created by mariotaku on 16/2/21. */ @@ -35,18 +37,18 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease; @JsonObject public class SendDirectMessageActionExtras implements ActionExtras { @ParcelableThisPlease - @JsonField(name = "recipient_id") - String recipientId; + @JsonField(name = "recipient_ids") + String[] recipientIds; @ParcelableThisPlease @JsonField(name = "conversation_id") String conversationId; - public String getRecipientId() { - return recipientId; + public String[] getRecipientIds() { + return recipientIds; } - public void setRecipientId(String recipientId) { - this.recipientId = recipientId; + public void setRecipientIds(String[] recipientIds) { + this.recipientIds = recipientIds; } public String getConversationId() { @@ -68,19 +70,31 @@ public class SendDirectMessageActionExtras implements ActionExtras { } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - SendDirectMessageActionExtras that = (SendDirectMessageActionExtras) o; + final SendDirectMessageActionExtras that = (SendDirectMessageActionExtras) o; - return recipientId != null ? recipientId.equals(that.recipientId) : that.recipientId == null; + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(recipientIds, that.recipientIds)) return false; + return conversationId != null ? conversationId.equals(that.conversationId) : that.conversationId == null; } @Override public int hashCode() { - return recipientId != null ? recipientId.hashCode() : 0; + int result = Arrays.hashCode(recipientIds); + result = 31 * result + (conversationId != null ? conversationId.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "SendDirectMessageActionExtras{" + + "conversationId='" + conversationId + '\'' + + ", recipientIds=" + Arrays.toString(recipientIds) + + '}'; } public static final Creator CREATOR = new Creator() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/MessagesConversationFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/MessagesConversationFragment.kt index a4d0d1e01..a8a26a35a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/MessagesConversationFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/MessagesConversationFragment.kt @@ -1,5 +1,6 @@ package org.mariotaku.twidere.fragment +import android.accounts.AccountManager import android.content.Context import android.os.Bundle import android.support.v4.app.LoaderManager @@ -11,6 +12,7 @@ import android.view.View import android.view.ViewGroup import kotlinx.android.synthetic.main.fragment_messages_conversation.* import org.mariotaku.kpreferences.get +import org.mariotaku.ktextension.empty import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.OrderBy import org.mariotaku.twidere.R @@ -20,7 +22,9 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_CONVERSATION_ID import org.mariotaku.twidere.constant.newDocumentApiKey import org.mariotaku.twidere.loader.ObjectCursorLoader import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.provider.TwidereDataStore.Messages +import org.mariotaku.twidere.service.LengthyOperationsService import org.mariotaku.twidere.util.DataStoreUtils import org.mariotaku.twidere.util.IntentUtils import java.util.concurrent.atomic.AtomicReference @@ -31,6 +35,10 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac private val accountKey: UserKey get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) private val conversationId: String get() = arguments.getString(EXTRA_CONVERSATION_ID) + private val account: AccountDetails? by lazy { + AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) + } + override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) adapter = MessagesConversationAdapter(context) @@ -45,6 +53,12 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac } recyclerView.adapter = adapter recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true) + + sendMessage.setOnClickListener { + performSendMessage() + } + + loaderManager.initLoader(0, null, this) } @@ -61,10 +75,30 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac } override fun onLoadFinished(loader: Loader?>, data: List?) { - val conversation = (loader as? ConversationLoader)?.conversation + val conversationLoader = loader as? ConversationLoader + val conversation = conversationLoader?.conversation adapter.setData(conversation, data) } + private fun performSendMessage() { + val conversation = adapter.conversation ?: return + if (editText.empty) { + editText.error = getString(R.string.hint_error_message_no_content) + return + } + val text = editText.text.toString() + val message = ParcelableNewMessage().apply { + this.account = this@MessagesConversationFragment.account + this.conversation_id = conversation.id + this.recipient_ids = conversation.participants?.map { + it.key.id + }?.toTypedArray() + this.text = text + } + LengthyOperationsService.sendMessageAsync(context, message) + editText.text = null + } + internal class ConversationLoader( context: Context, val accountKey: UserKey, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt index 72f63f6f5..eff85c501 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt @@ -141,7 +141,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { } this.text = draft.text this.media = draft.media - this.recipient_id = extras.recipientId + this.recipient_ids = extras.recipientIds this.conversation_id = extras.conversationId } sendMessage(message) @@ -190,6 +190,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { val notification = builder.build() startForeground(NOTIFICATION_ID_SEND_DIRECT_MESSAGE, notification) val task = SendMessageTask(this) + task.params = message invokeBeforeExecute(task) val result = ManualTaskStarter.invokeExecute(task) invokeAfterExecute(task, result) @@ -202,7 +203,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { text = message.text media = message.media action_extras = SendDirectMessageActionExtras().apply { - recipientId = message.recipient_id + recipientIds = message.recipient_ids conversationId = message.conversation_id } } @@ -454,6 +455,13 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { intent.putExtra(EXTRA_ACTION, action) context.startService(intent) } + + fun sendMessageAsync(context: Context, message: ParcelableNewMessage) { + val intent = Intent(context, LengthyOperationsService::class.java) + intent.action = INTENT_ACTION_SEND_DIRECT_MESSAGE + intent.putExtra(EXTRA_MESSAGE, message) + context.startService(intent) + } } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SendMessageTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SendMessageTask.kt index d6d91cad5..fb3340866 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SendMessageTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SendMessageTask.kt @@ -44,19 +44,26 @@ class SendMessageTask( private fun sendTwitterOfficialDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData { val response = microBlog.sendDm(NewDm().apply { - setConversationId(message.conversation_id) + val conversationId = message.conversation_id + if (conversationId != null) { + setConversationId(conversationId) + } else { + setRecipientIds(message.recipient_ids) + } setText(message.text) }) return GetMessagesTask.createDatabaseUpdateData(context, account, response) } private fun sendFanfouDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData { - val response = microBlog.sendFanfouDirectMessage(message.recipient_id, message.text) + val recipientId = message.recipient_ids.singleOrNull() ?: throw MicroBlogException("No recipient") + val response = microBlog.sendFanfouDirectMessage(recipientId, message.text) return createDatabaseUpdateData(account, response) } private fun sendDefaultDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData { - val response = microBlog.sendDirectMessage(message.recipient_id, message.text) + val recipientId = message.recipient_ids.singleOrNull() ?: throw MicroBlogException("No recipient") + val response = microBlog.sendDirectMessage(recipientId, message.text) return createDatabaseUpdateData(account, response) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt index 653afacca..620387db2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt @@ -24,12 +24,11 @@ import org.mariotaku.microblog.library.twitter.model.SavedSearch import org.mariotaku.microblog.library.twitter.model.Status import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.twidere.model.* -import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras import org.mariotaku.twidere.model.util.ParcelableStatusUtils import org.mariotaku.twidere.model.util.ParcelableUserUtils import org.mariotaku.twidere.model.util.getActivityStatus -import org.mariotaku.twidere.provider.TwidereDataStore.* -import java.util.* +import org.mariotaku.twidere.provider.TwidereDataStore.Filters +import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches object ContentValuesCreator { @@ -63,23 +62,6 @@ object ContentValuesCreator { return values } - fun createMessageDraft(accountKey: UserKey, recipientId: String, text: String, imageUri: String?): ContentValues { - val values = ContentValues() - values.put(Drafts.ACTION_TYPE, Draft.Action.SEND_DIRECT_MESSAGE) - values.put(Drafts.TEXT, text) - values.put(Drafts.ACCOUNT_KEYS, accountKey.toString()) - values.put(Drafts.TIMESTAMP, System.currentTimeMillis()) - if (imageUri != null) { - val mediaArray = arrayOf(ParcelableMediaUpdate(imageUri, 0)) - values.put(Drafts.MEDIA, JsonSerializer.serialize(Arrays.asList(*mediaArray), - ParcelableMediaUpdate::class.java)) - } - val extra = SendDirectMessageActionExtras() - extra.recipientId = recipientId - values.put(Drafts.ACTION_EXTRAS, JsonSerializer.serialize(extra)) - return values - } - fun createSavedSearch(savedSearch: SavedSearch, accountKey: UserKey): ContentValues { val values = ContentValues() values.put(SavedSearches.ACCOUNT_KEY, accountKey.toString()) diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index fcabc282c..2a8006237 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -812,6 +812,7 @@ No location No rule No content + No content No tab No tab No, thanks