mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-07 15:28:51 +01:00
supports send dm
This commit is contained in:
parent
ed7876a7d1
commit
1957cd87e0
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
package org.mariotaku.microblog.library.twitter.model;
|
package org.mariotaku.microblog.library.twitter.model;
|
||||||
|
|
||||||
|
import org.mariotaku.microblog.library.twitter.util.InternalArrayUtil;
|
||||||
import org.mariotaku.restfu.http.SimpleValueMap;
|
import org.mariotaku.restfu.http.SimpleValueMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +37,10 @@ public class NewDm extends SimpleValueMap {
|
|||||||
put("conversation_id", conversationId);
|
put("conversation_id", conversationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRecipientIds(String[] recipientIds) {
|
||||||
|
put("conversation_ids", InternalArrayUtil.join(recipientIds, ","));
|
||||||
|
}
|
||||||
|
|
||||||
public void setMediaId(long mediaId) {
|
public void setMediaId(long mediaId) {
|
||||||
put("media_id", mediaId);
|
put("media_id", mediaId);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ public class ParcelableNewMessage implements Parcelable {
|
|||||||
@JsonField(name = "conversation_id")
|
@JsonField(name = "conversation_id")
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
public String conversation_id;
|
public String conversation_id;
|
||||||
@JsonField(name = "recipient_id")
|
@JsonField(name = "recipient_ids")
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
public String recipient_id;
|
public String[] recipient_ids;
|
||||||
@JsonField(name = "text")
|
@JsonField(name = "text")
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
public String text;
|
public String text;
|
||||||
|
@ -28,6 +28,8 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
|
|||||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 16/2/21.
|
* Created by mariotaku on 16/2/21.
|
||||||
*/
|
*/
|
||||||
@ -35,18 +37,18 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
|||||||
@JsonObject
|
@JsonObject
|
||||||
public class SendDirectMessageActionExtras implements ActionExtras {
|
public class SendDirectMessageActionExtras implements ActionExtras {
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
@JsonField(name = "recipient_id")
|
@JsonField(name = "recipient_ids")
|
||||||
String recipientId;
|
String[] recipientIds;
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
@JsonField(name = "conversation_id")
|
@JsonField(name = "conversation_id")
|
||||||
String conversationId;
|
String conversationId;
|
||||||
|
|
||||||
public String getRecipientId() {
|
public String[] getRecipientIds() {
|
||||||
return recipientId;
|
return recipientIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecipientId(String recipientId) {
|
public void setRecipientIds(String[] recipientIds) {
|
||||||
this.recipientId = recipientId;
|
this.recipientIds = recipientIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getConversationId() {
|
public String getConversationId() {
|
||||||
@ -68,19 +70,31 @@ public class SendDirectMessageActionExtras implements ActionExtras {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
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
|
@Override
|
||||||
public int hashCode() {
|
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>() {
|
public static final Creator<SendDirectMessageActionExtras> CREATOR = new Creator<SendDirectMessageActionExtras>() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.mariotaku.twidere.fragment
|
package org.mariotaku.twidere.fragment
|
||||||
|
|
||||||
|
import android.accounts.AccountManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.LoaderManager
|
import android.support.v4.app.LoaderManager
|
||||||
@ -11,6 +12,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
|
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
|
||||||
import org.mariotaku.kpreferences.get
|
import org.mariotaku.kpreferences.get
|
||||||
|
import org.mariotaku.ktextension.empty
|
||||||
import org.mariotaku.sqliteqb.library.Expression
|
import org.mariotaku.sqliteqb.library.Expression
|
||||||
import org.mariotaku.sqliteqb.library.OrderBy
|
import org.mariotaku.sqliteqb.library.OrderBy
|
||||||
import org.mariotaku.twidere.R
|
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.constant.newDocumentApiKey
|
||||||
import org.mariotaku.twidere.loader.ObjectCursorLoader
|
import org.mariotaku.twidere.loader.ObjectCursorLoader
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.*
|
||||||
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||||
|
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||||
import org.mariotaku.twidere.util.DataStoreUtils
|
import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.IntentUtils
|
import org.mariotaku.twidere.util.IntentUtils
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
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 accountKey: UserKey get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY)
|
||||||
private val conversationId: String get() = arguments.getString(EXTRA_CONVERSATION_ID)
|
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?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
adapter = MessagesConversationAdapter(context)
|
adapter = MessagesConversationAdapter(context)
|
||||||
@ -45,6 +53,12 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac
|
|||||||
}
|
}
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
recyclerView.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
||||||
|
|
||||||
|
sendMessage.setOnClickListener {
|
||||||
|
performSendMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
loaderManager.initLoader(0, null, this)
|
loaderManager.initLoader(0, null, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,10 +75,30 @@ class MessagesConversationFragment : BaseFragment(), LoaderManager.LoaderCallbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadFinished(loader: Loader<List<ParcelableMessage>?>, data: List<ParcelableMessage>?) {
|
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)
|
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(
|
internal class ConversationLoader(
|
||||||
context: Context,
|
context: Context,
|
||||||
val accountKey: UserKey,
|
val accountKey: UserKey,
|
||||||
|
@ -141,7 +141,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||||||
}
|
}
|
||||||
this.text = draft.text
|
this.text = draft.text
|
||||||
this.media = draft.media
|
this.media = draft.media
|
||||||
this.recipient_id = extras.recipientId
|
this.recipient_ids = extras.recipientIds
|
||||||
this.conversation_id = extras.conversationId
|
this.conversation_id = extras.conversationId
|
||||||
}
|
}
|
||||||
sendMessage(message)
|
sendMessage(message)
|
||||||
@ -190,6 +190,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||||||
val notification = builder.build()
|
val notification = builder.build()
|
||||||
startForeground(NOTIFICATION_ID_SEND_DIRECT_MESSAGE, notification)
|
startForeground(NOTIFICATION_ID_SEND_DIRECT_MESSAGE, notification)
|
||||||
val task = SendMessageTask(this)
|
val task = SendMessageTask(this)
|
||||||
|
task.params = message
|
||||||
invokeBeforeExecute(task)
|
invokeBeforeExecute(task)
|
||||||
val result = ManualTaskStarter.invokeExecute(task)
|
val result = ManualTaskStarter.invokeExecute(task)
|
||||||
invokeAfterExecute(task, result)
|
invokeAfterExecute(task, result)
|
||||||
@ -202,7 +203,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||||||
text = message.text
|
text = message.text
|
||||||
media = message.media
|
media = message.media
|
||||||
action_extras = SendDirectMessageActionExtras().apply {
|
action_extras = SendDirectMessageActionExtras().apply {
|
||||||
recipientId = message.recipient_id
|
recipientIds = message.recipient_ids
|
||||||
conversationId = message.conversation_id
|
conversationId = message.conversation_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,6 +455,13 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||||||
intent.putExtra(EXTRA_ACTION, action)
|
intent.putExtra(EXTRA_ACTION, action)
|
||||||
context.startService(intent)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,19 +44,26 @@ class SendMessageTask(
|
|||||||
|
|
||||||
private fun sendTwitterOfficialDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
private fun sendTwitterOfficialDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
||||||
val response = microBlog.sendDm(NewDm().apply {
|
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)
|
setText(message.text)
|
||||||
})
|
})
|
||||||
return GetMessagesTask.createDatabaseUpdateData(context, account, response)
|
return GetMessagesTask.createDatabaseUpdateData(context, account, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendFanfouDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
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)
|
return createDatabaseUpdateData(account, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendDefaultDM(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
|
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)
|
return createDatabaseUpdateData(account, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.Status
|
||||||
import org.mariotaku.microblog.library.twitter.model.User
|
import org.mariotaku.microblog.library.twitter.model.User
|
||||||
import org.mariotaku.twidere.model.*
|
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.ParcelableStatusUtils
|
||||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
||||||
import org.mariotaku.twidere.model.util.getActivityStatus
|
import org.mariotaku.twidere.model.util.getActivityStatus
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
|
||||||
import java.util.*
|
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches
|
||||||
|
|
||||||
object ContentValuesCreator {
|
object ContentValuesCreator {
|
||||||
|
|
||||||
@ -63,23 +62,6 @@ object ContentValuesCreator {
|
|||||||
return values
|
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 {
|
fun createSavedSearch(savedSearch: SavedSearch, accountKey: UserKey): ContentValues {
|
||||||
val values = ContentValues()
|
val values = ContentValues()
|
||||||
values.put(SavedSearches.ACCOUNT_KEY, accountKey.toString())
|
values.put(SavedSearches.ACCOUNT_KEY, accountKey.toString())
|
||||||
|
@ -812,6 +812,7 @@
|
|||||||
<string name="no_location">No location</string>
|
<string name="no_location">No location</string>
|
||||||
<string name="no_rule">No rule</string>
|
<string name="no_rule">No rule</string>
|
||||||
<string name="no_status_content_text">No content</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">No tab</string>
|
||||||
<string name="no_tab_hint">No tab</string>
|
<string name="no_tab_hint">No tab</string>
|
||||||
<string name="no_thanks">No, thanks</string>
|
<string name="no_thanks">No, thanks</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user