supports send dm

This commit is contained in:
Mariotaku Lee 2017-02-14 15:27:28 +08:00
parent ed7876a7d1
commit 1957cd87e0
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 89 additions and 38 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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<SendDirectMessageActionExtras> CREATOR = new Creator<SendDirectMessageActionExtras>() {

View File

@ -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<List<ParcelableMessage>?>, data: List<ParcelableMessage>?) {
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,

View File

@ -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)
}
}
}

View File

@ -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)
}

View File

@ -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())

View File

@ -812,6 +812,7 @@
<string name="no_location">No location</string>
<string name="no_rule">No rule</string>
<string name="no_status_content_text">No content</string>
<string name="hint_error_message_no_content">No content</string>
<string name="no_tab">No tab</string>
<string name="no_tab_hint">No tab</string>
<string name="no_thanks">No, thanks</string>