From 9c7a62f447bb527dee2d2868cc735c8ce8271854 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Thu, 16 Feb 2017 01:03:48 +0800 Subject: [PATCH] implementing new dm conversation --- .../model/ParcelableMessageConversation.java | 9 ++ .../twidere/model/ParcelableNewMessage.java | 19 +++++ .../twidere/provider/TwidereDataStore.java | 1 + twidere/build.gradle | 2 + .../java/org/mariotaku/twidere/Constants.java | 2 +- .../twidere/model/DefaultFeatures.java | 7 ++ .../twidere/activity/UserSelectorActivity.kt | 2 +- .../message/MessageNewConversationFragment.kt | 84 ++++++++++++++++--- .../message/MessagesConversationFragment.kt | 16 ++++ .../message/MessagesEntriesFragment.kt | 3 +- .../twidere/loader/CacheUserSearchLoader.kt | 61 ++++++++------ .../twidere/loader/MicroBlogAPIUsersLoader.kt | 6 +- .../model/event/SendMessageTaskEvent.kt | 32 +++++++ .../mariotaku/twidere/task/GetMessagesTask.kt | 4 +- .../twidere/task/message/SendMessageTask.kt | 37 ++++++-- .../org/mariotaku/twidere/util/IntentUtils.kt | 6 +- .../menu/menu_messages_conversation_new.xml | 28 +++++++ twidere/src/main/res/values/strings.xml | 2 + 18 files changed, 271 insertions(+), 50 deletions(-) create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/model/event/SendMessageTaskEvent.kt create mode 100644 twidere/src/main/res/menu/menu_messages_conversation_new.xml diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java index d3248ef38..93478a8be 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java @@ -140,6 +140,14 @@ public class ParcelableMessageConversation implements Parcelable { @CursorField(value = Conversations.REQUEST_CURSOR) public String request_cursor; + /** + * True if this is a temporary conversation, i.e. Created by user but haven't send any message + * yet. + */ + @JsonField(name = "is_temp") + @CursorField(value = Conversations.IS_TEMP) + public boolean is_temp; + @JsonField(name = "message_extras") @ParcelableNoThanks ParcelableMessage.InternalExtras internalMessageExtras; @@ -191,6 +199,7 @@ public class ParcelableMessageConversation implements Parcelable { ", recipient_key=" + recipient_key + ", is_outgoing=" + is_outgoing + ", request_cursor='" + request_cursor + '\'' + + ", is_temp=" + is_temp + ", internalMessageExtras=" + internalMessageExtras + ", internalConversationExtras=" + internalConversationExtras + '}'; 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 b7152e41d..bea25de91 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 @@ -29,6 +29,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 2017/2/14. */ @@ -58,6 +60,23 @@ public class ParcelableNewMessage implements Parcelable { @ParcelableThisPlease @Draft.Action public String draft_action; + @JsonField(name = "is_temp_conversation") + @ParcelableThisPlease + public boolean is_temp_conversation; + + @Override + public String toString() { + return "ParcelableNewMessage{" + + "account=" + account + + ", conversation_id='" + conversation_id + '\'' + + ", recipient_ids=" + Arrays.toString(recipient_ids) + + ", text='" + text + '\'' + + ", media=" + Arrays.toString(media) + + ", draft_unique_id='" + draft_unique_id + '\'' + + ", draft_action='" + draft_action + '\'' + + ", is_temp_conversation=" + is_temp_conversation + + '}'; + } @Override public int describeContents() { diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java index 8c061b5dd..da69e579c 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/provider/TwidereDataStore.java @@ -398,6 +398,7 @@ public interface TwidereDataStore { String RECIPIENT_KEY = "recipient_key"; String REQUEST_CURSOR = "request_cursor"; String IS_OUTGOING = "is_outgoing"; + String IS_TEMP = "is_temp"; String CONVERSATION_EXTRAS = "conversation_extras"; String CONVERSATION_EXTRAS_TYPE = "conversation_extras_type"; diff --git a/twidere/build.gradle b/twidere/build.gradle index 0b6e94d11..7968bd38e 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -56,6 +56,8 @@ android { } buildTypes { debug { + minifyEnabled false + shrinkResources false resValue("bool", "debug", "true") } release { diff --git a/twidere/src/main/java/org/mariotaku/twidere/Constants.java b/twidere/src/main/java/org/mariotaku/twidere/Constants.java index 322621d31..8169e86af 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/Constants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/Constants.java @@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING; public interface Constants extends TwidereConstants { String DATABASES_NAME = "twidere.sqlite"; - int DATABASES_VERSION = 175; + int DATABASES_VERSION = 176; int EXTRA_FEATURES_NOTICE_VERSION = 0; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/DefaultFeatures.java b/twidere/src/main/java/org/mariotaku/twidere/model/DefaultFeatures.java index 0df0ad89e..228b79b69 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/DefaultFeatures.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/DefaultFeatures.java @@ -42,6 +42,9 @@ public class DefaultFeatures { @JsonField(name = "twitter_direct_message_media_limit") long twitterDirectMessageMediaLimit = 1; + @JsonField(name = "twitter_direct_message_max_participants") + long twitterDirectMessageMaxParticipants = 20; + public boolean isMediaLinkCountsInStatus() { return mediaLinkCountsInStatus; } @@ -58,6 +61,10 @@ public class DefaultFeatures { return twitterDirectMessageMediaLimit; } + public long getTwitterDirectMessageMaxParticipants() { + return twitterDirectMessageMaxParticipants; + } + @WorkerThread public boolean loadRemoteSettings(RestHttpClient client) throws IOException { HttpRequest request = new HttpRequest.Builder().method(GET.METHOD).url(REMOTE_SETTINGS_URL).build(); diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserSelectorActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserSelectorActivity.kt index d111666e5..cb412292e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserSelectorActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserSelectorActivity.kt @@ -97,7 +97,7 @@ class UserSelectorActivity : BaseActivity(), OnItemClickListener, LoaderManager. if (!fromCache) { showProgress() } - return CacheUserSearchLoader(this, accountKey, query, fromCache, true) + return CacheUserSearchLoader(this, accountKey, query, !fromCache, true, true) } override fun onLoaderReset(loader: Loader>) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt index 03db3ed97..2d6db9708 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt @@ -19,6 +19,7 @@ package org.mariotaku.twidere.fragment.message +import android.accounts.AccountManager import android.graphics.Canvas import android.graphics.Paint import android.graphics.RectF @@ -30,22 +31,28 @@ import android.text.Editable import android.text.Spannable import android.text.TextUtils import android.text.style.ReplacementSpan -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import kotlinx.android.synthetic.main.fragment_messages_conversation_new.* import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.set +import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.twidere.R import org.mariotaku.twidere.adapter.SelectableUsersAdapter import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.nameFirstKey +import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.fragment.BaseFragment import org.mariotaku.twidere.loader.CacheUserSearchLoader +import org.mariotaku.twidere.model.ParcelableMessageConversation +import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType +import org.mariotaku.twidere.model.ParcelableMessageConversationValuesCreator import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.model.util.AccountUtils +import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.text.MarkForDeleteSpan +import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.util.view.SimpleTextWatcher /** @@ -53,13 +60,24 @@ import org.mariotaku.twidere.util.view.SimpleTextWatcher */ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks?> { - private val accountKey: UserKey get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) + private val accountKey by lazy { arguments.getParcelable(EXTRA_ACCOUNT_KEY) } + private val account by lazy { + AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) + } + + private val selectedRecipients: List + get() { + val text = editParticipants.editableText ?: return emptyList() + return text.getSpans(0, text.length, ParticipantSpan::class.java).map(ParticipantSpan::user) + } + private var loaderInitialized: Boolean = false private lateinit var usersAdapter: SelectableUsersAdapter override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) usersAdapter = SelectableUsersAdapter(context) recyclerView.adapter = usersAdapter recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) @@ -92,6 +110,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks?>) { @@ -168,6 +187,55 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks { + createConversation() + return true + } + } + return super.onOptionsItemSelected(item) + } + + private fun createConversation() { + val account = this.account ?: return + val selected = this.selectedRecipients + if (selected.isEmpty()) return + val maxParticipants = if (account.isOfficial(context)) { + defaultFeatures.twitterDirectMessageMaxParticipants + } else { + 1 + } + if (selected.size > maxParticipants) { + editParticipants.error = getString(R.string.error_message_message_too_many_participants) + return + } + val conversation = ParcelableMessageConversation() + conversation.account_color = account.color + conversation.account_key = account.key + conversation.id = "twidere:temp:${System.currentTimeMillis()}" + conversation.local_timestamp = System.currentTimeMillis() + conversation.conversation_type = if (selected.size > 1) { + ConversationType.ONE_TO_ONE + } else { + ConversationType.GROUP + } + conversation.participants = (selected + account.user).toTypedArray() + conversation.is_temp = true + val values = ParcelableMessageConversationValuesCreator.create(conversation) + context.contentResolver.insert(Conversations.CONTENT_URI, values) + activity.startActivity(IntentUtils.messageConversation(accountKey, conversation.id)) + activity.finish() + } + private fun updateCheckState() { val selected = selectedRecipients usersAdapter.clearCheckState() @@ -175,6 +243,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks - get() { - val text = editParticipants.editableText ?: return emptyList() - return text.getSpans(0, text.length, ParticipantSpan::class.java).map(ParticipantSpan::user) - } class PendingQuerySpan diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesConversationFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesConversationFragment.kt index 62bde0473..8ac494699 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesConversationFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesConversationFragment.kt @@ -37,11 +37,13 @@ import kotlinx.android.synthetic.main.fragment_messages_conversation.* import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.empty +import org.mariotaku.ktextension.set import org.mariotaku.pickncrop.library.MediaPickerActivity import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.OrderBy import org.mariotaku.twidere.R import org.mariotaku.twidere.TwidereConstants.REQUEST_PICK_MEDIA +import org.mariotaku.twidere.activity.LinkHandlerActivity import org.mariotaku.twidere.activity.ThemedMediaPickerActivity import org.mariotaku.twidere.adapter.MediaPreviewAdapter import org.mariotaku.twidere.adapter.MessagesConversationAdapter @@ -56,6 +58,7 @@ import org.mariotaku.twidere.loader.ObjectCursorLoader import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType import org.mariotaku.twidere.model.event.GetMessagesTaskEvent +import org.mariotaku.twidere.model.event.SendMessageTaskEvent import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.provider.TwidereDataStore.Messages import org.mariotaku.twidere.service.LengthyOperationsService @@ -252,6 +255,19 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment { - if (TextUtils.isEmpty(query)) return emptyList() - if (fromCache) { - val cachedList = ArrayList() - val queryEscaped = query.replace("_", "^_") - val nicknameKeys = Utils.getMatchedNicknameKeys(query, userColorNameManager) - val selection = Expression.or(Expression.likeRaw(Columns.Column(TwidereDataStore.CachedUsers.SCREEN_NAME), "?||'%'", "^"), - Expression.likeRaw(Columns.Column(TwidereDataStore.CachedUsers.NAME), "?||'%'", "^"), - Expression.inArgs(Columns.Column(TwidereDataStore.CachedUsers.USER_KEY), nicknameKeys.size)) - val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys) - val order = arrayOf(TwidereDataStore.CachedUsers.LAST_SEEN, TwidereDataStore.CachedUsers.SCREEN_NAME, TwidereDataStore.CachedUsers.NAME) - val ascending = booleanArrayOf(false, true, true) - val orderBy = OrderBy(order, ascending) - val c = context.contentResolver.query(TwidereDataStore.CachedUsers.CONTENT_URI, - TwidereDataStore.CachedUsers.BASIC_COLUMNS, selection?.sql, - selectionArgs, orderBy.sql)!! - val i = ParcelableUserCursorIndices(c) - c.moveToFirst() - while (!c.isAfterLast) { - cachedList.add(i.newObject(c)) - c.moveToNext() + override fun getUsers(twitter: MicroBlog, details: AccountDetails): List { + if (query.isEmpty() || !fromNetwork) return emptyList() + return super.getUsers(twitter, details) + } + + override fun processUsersData(list: MutableList) { + if (query.isEmpty() || !fromCache) return + val queryEscaped = query.replace("_", "^_") + val nicknameKeys = Utils.getMatchedNicknameKeys(query, userColorNameManager) + val selection = Expression.or(Expression.likeRaw(Columns.Column(CachedUsers.SCREEN_NAME), "?||'%'", "^"), + Expression.likeRaw(Columns.Column(CachedUsers.NAME), "?||'%'", "^"), + Expression.inArgs(Columns.Column(CachedUsers.USER_KEY), nicknameKeys.size)) + val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys) + val c = context.contentResolver.query(CachedUsers.CONTENT_URI, CachedUsers.BASIC_COLUMNS, + selection.sql, selectionArgs, null)!! + val i = ParcelableUserCursorIndices(c) + c.moveToFirst() + while (!c.isAfterLast) { + if (list.none { it.key.toString() == c.getString(i.key) }) { + list.add(i.newObject(c)) } - c.close() - return cachedList + c.moveToNext() } - return super.loadInBackground() + c.close() + val collator = Collator.getInstance() + list.sortWith(Comparator { l, r -> + val compare = collator.compare(l.name, r.name) + if (compare != 0) return@Comparator compare + return@Comparator l.screen_name.compareTo(r.screen_name) + }) } } \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIUsersLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIUsersLoader.kt index eadf70f3b..64ea743ff 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIUsersLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIUsersLoader.kt @@ -69,7 +69,7 @@ abstract class MicroBlogAPIUsersLoader( data.add(item) pos++ } - Collections.sort(data) + processUsersData(data) return ListResponse.getListInstance(data) } @@ -79,4 +79,8 @@ abstract class MicroBlogAPIUsersLoader( @Throws(MicroBlogException::class) protected abstract fun getUsers(twitter: MicroBlog, details: AccountDetails): List + + protected open fun processUsersData(list: MutableList) { + Collections.sort(data) + } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/event/SendMessageTaskEvent.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/event/SendMessageTaskEvent.kt new file mode 100644 index 000000000..e4af791d8 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/event/SendMessageTaskEvent.kt @@ -0,0 +1,32 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.model.event + +import org.mariotaku.twidere.model.UserKey + +/** + * Created by mariotaku on 2017/2/16. + */ +data class SendMessageTaskEvent( + val accountKey: UserKey, + val conversationId: String?, + val newConversationId: String?, + val success: Boolean +) \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetMessagesTask.kt index 5c49d3668..4df5c94a8 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetMessagesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetMessagesTask.kt @@ -329,9 +329,7 @@ class GetMessagesTask( val conversations = hashMapOf() - respConversations.keys.let { - conversations.addLocalConversations(context, account.key, it) - } + conversations.addLocalConversations(context, account.key, respConversations.keys) val messages = ArrayList() val messageDeletionsMap = HashMap>() val conversationDeletions = ArrayList() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/message/SendMessageTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/message/SendMessageTask.kt index f12623a9c..755d904e2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/message/SendMessageTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/message/SendMessageTask.kt @@ -27,13 +27,16 @@ import org.mariotaku.microblog.library.twitter.TwitterUpload import org.mariotaku.microblog.library.twitter.model.DirectMessage import org.mariotaku.microblog.library.twitter.model.NewDm import org.mariotaku.microblog.library.twitter.model.fixMedia +import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableMessageConversation import org.mariotaku.twidere.model.ParcelableNewMessage +import org.mariotaku.twidere.model.event.SendMessageTaskEvent import org.mariotaku.twidere.model.util.ParcelableMessageUtils +import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask import org.mariotaku.twidere.task.GetMessagesTask import org.mariotaku.twidere.task.GetMessagesTask.Companion.addConversation @@ -45,15 +48,33 @@ import org.mariotaku.twidere.task.twitter.UpdateStatusTask */ class SendMessageTask( context: Context -) : ExceptionHandlingAbstractTask(context) { - override fun onExecute(params: ParcelableNewMessage) { +) : ExceptionHandlingAbstractTask(context) { + + override fun onExecute(params: ParcelableNewMessage): SendMessageResult { val account = params.account val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java) val updateData = requestSendMessage(microBlog, account, params) + if (params.is_temp_conversation && params.conversation_id != null) { + val deleteTempWhere = Expression.and(Expression.equalsArgs(Conversations.ACCOUNT_KEY), + Expression.equalsArgs(Conversations.CONVERSATION_ID)).sql + val deleteTempWhereArgs = arrayOf(account.key.toString(), params.conversation_id) + context.contentResolver.delete(Conversations.CONTENT_URI, deleteTempWhere, + deleteTempWhereArgs) + } GetMessagesTask.storeMessages(context, updateData, account) + return SendMessageResult(updateData.conversations.map { it.id }) } - fun requestSendMessage(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData { + override fun onException(callback: Unit?, exception: MicroBlogException) { + bus.post(SendMessageTaskEvent(params.account.key, params.conversation_id, null, false)) + } + + override fun onSucceed(callback: Unit?, result: SendMessageResult) { + bus.post(SendMessageTaskEvent(params.account.key, params.conversation_id, + result.conversationIds.singleOrNull(), true)) + } + + private fun requestSendMessage(microBlog: MicroBlog, account: AccountDetails, message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData { when (account.type) { AccountType.TWITTER -> { if (account.isOfficial(context)) { @@ -71,9 +92,11 @@ class SendMessageTask( var deleteOnSuccess: List? = null var deleteAlways: List? = null val response = try { - val newDm = NewDm() val conversationId = message.conversation_id - if (conversationId != null) { + val tempConversation = message.is_temp_conversation + + val newDm = NewDm() + if (!tempConversation && conversationId != null) { newDm.setConversationId(conversationId) } else { newDm.setRecipientIds(message.recipient_ids) @@ -118,4 +141,8 @@ class SendMessageTask( conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient)) return GetMessagesTask.DatabaseUpdateData(conversations.values, listOf(message)) } + + class SendMessageResult(var conversationIds: List) { + + } } \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt index 7b9282a01..870b6f110 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt @@ -228,6 +228,10 @@ object IntentUtils { } fun openMessageConversation(context: Context, accountKey: UserKey, conversationId: String) { + context.startActivity(messageConversation(accountKey, conversationId)) + } + + fun messageConversation(accountKey: UserKey, conversationId: String): Intent { val builder = Uri.Builder() builder.scheme(SCHEME_TWIDERE) builder.authority(AUTHORITY_MESSAGES) @@ -236,7 +240,7 @@ object IntentUtils { builder.appendQueryParameter(QUERY_PARAM_CONVERSATION_ID, conversationId) val intent = Intent(Intent.ACTION_VIEW, builder.build()) intent.`package` = BuildConfig.APPLICATION_ID - context.startActivity(intent) + return intent } fun messageConversationInfo(accountKey: UserKey, conversationId: String): Intent { diff --git a/twidere/src/main/res/menu/menu_messages_conversation_new.xml b/twidere/src/main/res/menu/menu_messages_conversation_new.xml new file mode 100644 index 000000000..53020a2f4 --- /dev/null +++ b/twidere/src/main/res/menu/menu_messages_conversation_new.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index b88f2f35a..74dbb5ade 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -25,6 +25,7 @@ Center Clear Compose + Create conversation creating list Delete @@ -428,6 +429,7 @@ Media upload failed. Media uploader not found, maybe it was uninstalled. Message too long + Too many participants No content Twitter\'s rate limit exceeded, please retry %s