supports leave conversation event

This commit is contained in:
Mariotaku Lee 2017-02-13 21:33:45 +08:00
parent b66b619354
commit b900eedfe5
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
16 changed files with 245 additions and 116 deletions

View File

@ -23,7 +23,6 @@ package org.mariotaku.microblog.library.twitter.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.StringDef;
import com.bluelinelabs.logansquare.annotation.JsonField;
@ -132,6 +131,10 @@ public class DMResponse implements Parcelable {
Message conversationNameUpdate;
@JsonField(name = "conversation_read")
Message conversationRead;
@JsonField(name = "message_delete")
Message messageDelete;
@JsonField(name = "remove_conversation")
Message removeConversation;
public Message getJoinConversation() {
return joinConversation;
@ -161,6 +164,14 @@ public class DMResponse implements Parcelable {
return conversationRead;
}
public Message getMessageDelete() {
return messageDelete;
}
public Message getRemoveConversation() {
return removeConversation;
}
@Override
public String toString() {
return "Entry{" +
@ -171,9 +182,37 @@ public class DMResponse implements Parcelable {
", participantsJoin=" + participantsJoin +
", conversationNameUpdate=" + conversationNameUpdate +
", conversationRead=" + conversationRead +
", messageDelete=" + messageDelete +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
DMResponse$EntryParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Entry> CREATOR = new Creator<Entry>() {
@Override
public Entry createFromParcel(Parcel source) {
Entry target = new Entry();
DMResponse$EntryParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public Entry[] newArray(int size) {
return new Entry[size];
}
};
/**
* Created by mariotaku on 2017/2/13.
*/
@ParcelablePlease
@JsonObject
public static class Message implements Parcelable {
@ -208,6 +247,9 @@ public class DMResponse implements Parcelable {
@JsonField(name = "participants")
Conversation.Participant[] participants;
@JsonField(name = "messages")
MessageIds[] messages;
public boolean isAffectsSort() {
return affectsSort;
}
@ -248,6 +290,10 @@ public class DMResponse implements Parcelable {
return byUserId;
}
public MessageIds[] getMessages() {
return messages;
}
@Override
public String toString() {
return "Message{" +
@ -261,6 +307,7 @@ public class DMResponse implements Parcelable {
", byUserId='" + byUserId + '\'' +
", messageData=" + messageData +
", participants=" + Arrays.toString(participants) +
", messages=" + Arrays.toString(messages) +
'}';
}
@ -275,19 +322,64 @@ public class DMResponse implements Parcelable {
}
public static final Creator<Message> CREATOR = new Creator<Message>() {
@Override
public Message createFromParcel(Parcel source) {
Message target = new Message();
DMResponse$Entry$MessageParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public Message[] newArray(int size) {
return new Message[size];
}
};
@ParcelablePlease
@JsonObject
public static class MessageIds implements Parcelable {
@JsonField(name = "message_create_event_id")
String messageCreateEventId;
@JsonField(name = "message_id")
String messageId;
public String getMessageCreateEventId() {
return messageCreateEventId;
}
public String getMessageId() {
return messageId;
}
@Override
public String toString() {
return "MessageIds{" +
"messageCreateEventId='" + messageCreateEventId + '\'' +
", messageId='" + messageId + '\'' +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
DMResponse$Entry$Message$MessageIdsParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<MessageIds> CREATOR = new Creator<MessageIds>() {
public MessageIds createFromParcel(Parcel source) {
MessageIds target = new MessageIds();
DMResponse$Entry$Message$MessageIdsParcelablePlease.readFromParcel(target, source);
return target;
}
public MessageIds[] newArray(int size) {
return new MessageIds[size];
}
};
}
@ParcelablePlease
@JsonObject
public static class Data implements EntitySupport, Parcelable {
@ -360,6 +452,28 @@ public class DMResponse implements Parcelable {
return id;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
DMResponse$Entry$Message$DataParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Data> CREATOR = new Creator<Data>() {
public Data createFromParcel(Parcel source) {
Data target = new Data();
DMResponse$Entry$Message$DataParcelablePlease.readFromParcel(target, source);
return target;
}
public Data[] newArray(int size) {
return new Data[size];
}
};
@ParcelablePlease
@JsonObject
public static class Attachment implements Parcelable {
@ -406,54 +520,8 @@ public class DMResponse implements Parcelable {
}
};
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
DMResponse$Entry$Message$DataParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Data> CREATOR = new Creator<Data>() {
public Data createFromParcel(Parcel source) {
Data target = new Data();
DMResponse$Entry$Message$DataParcelablePlease.readFromParcel(target, source);
return target;
}
public Data[] newArray(int size) {
return new Data[size];
}
};
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
DMResponse$EntryParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<Entry> CREATOR = new Creator<Entry>() {
@Override
public Entry createFromParcel(Parcel source) {
Entry target = new Entry();
DMResponse$EntryParcelablePlease.readFromParcel(target, source);
return target;
}
@Override
public Entry[] newArray(int size) {
return new Entry[size];
}
};
}
@ParcelablePlease

View File

@ -134,6 +134,7 @@ dependencies {
compile "com.android.support:preference-v14:$android_support_lib_version"
compile "com.android.support:customtabs:$android_support_lib_version"
compile "com.android.support:design:$android_support_lib_version"
compile "com.android.support:percent:$android_support_lib_version"
compile 'com.twitter:twitter-text:1.13.0'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'

View File

@ -40,15 +40,17 @@ public class ContentResolverUtils {
}
public static <T> int bulkDelete(@NonNull final ContentResolver resolver, @NonNull final Uri uri,
@NonNull final String matchColumn, final boolean notIn,
@Nullable final Collection<T> colValues, final String extraWhere) {
@NonNull final String matchColumn, final boolean notIn,
@Nullable final Collection<T> colValues, final String extraWhere,
final String[] extraWhereArgs) {
if (colValues == null) return 0;
return bulkDelete(resolver, uri, matchColumn, notIn, colValues.toArray(), extraWhere);
return bulkDelete(resolver, uri, matchColumn, notIn, colValues.toArray(), extraWhere,
extraWhereArgs);
}
public static int bulkDelete(@NonNull final ContentResolver resolver, @NonNull final Uri uri,
@NonNull final String matchColumn, final boolean notIn,
@Nullable final Object colValues, final String extraWhere) {
@NonNull final String matchColumn, final boolean notIn,
@Nullable final Object colValues, final String extraWhere, final String[] extraWhereArgs) {
if (colValues == null) return 0;
final int colValuesLength = Array.getLength(colValues), blocksCount = colValuesLength / MAX_BULK_COUNT + 1;
int rowsDeleted = 0;
@ -56,6 +58,13 @@ public class ContentResolverUtils {
final int start = i * MAX_BULK_COUNT, end = Math.min(start + MAX_BULK_COUNT,
colValuesLength);
final String[] block = TwidereArrayUtils.toStringArray(colValues, start, end);
final String[] whereArgs;
if (extraWhereArgs != null) {
whereArgs = new String[block.length + extraWhereArgs.length];
TwidereArrayUtils.mergeArray(whereArgs, block, extraWhereArgs);
} else {
whereArgs = block;
}
final StringBuilder where;
if (notIn) {
where = new StringBuilder(Expression.notInArgs(matchColumn, block.length).getSQL());
@ -65,18 +74,18 @@ public class ContentResolverUtils {
if (!TextUtils.isEmpty(extraWhere)) {
where.append(" AND ").append(extraWhere);
}
rowsDeleted += resolver.delete(uri, where.toString(), block);
rowsDeleted += resolver.delete(uri, where.toString(), whereArgs);
}
return rowsDeleted;
}
public static int bulkInsert(@NonNull final ContentResolver resolver, @NonNull final Uri uri,
@NonNull final Collection<ContentValues> values) {
@NonNull final Collection<ContentValues> values) {
return bulkInsert(resolver, uri, values.toArray(new ContentValues[values.size()]));
}
public static int bulkInsert(@NonNull final ContentResolver resolver, @NonNull final Uri uri,
@NonNull final ContentValues[] values) {
@NonNull final ContentValues[] values) {
if (values.length == 0) return 0;
final int colValuesLength = values.length, blocksCount = colValuesLength / MAX_BULK_COUNT + 1;
int rowsInserted = 0;

View File

@ -84,8 +84,8 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
ids[i] = item._id
}
adapter.addRemovedPositions(reverseSortedPositions)
ContentResolverUtils.bulkDelete(contentResolver, SearchHistory.CONTENT_URI,
SearchHistory._ID, false, ids, null)
ContentResolverUtils.bulkDelete(contentResolver, SearchHistory.CONTENT_URI, SearchHistory._ID,
false, ids, null, null)
supportLoaderManager.restartLoader(0, null, this)
}

View File

@ -106,9 +106,12 @@ class AddStatusFilterDialogFragment : BaseDialogFragment() {
}
}
val resolver = context.contentResolver
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI, Filters.Users.USER_KEY, false, userKeys, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Keywords.CONTENT_URI, Filters.Keywords.VALUE, false, keywords, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Sources.CONTENT_URI, Filters.Sources.VALUE, false, sources, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI,
Filters.Users.USER_KEY, false, userKeys, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Keywords.CONTENT_URI,
Filters.Keywords.VALUE, false, keywords, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Sources.CONTENT_URI,
Filters.Sources.VALUE, false, sources, null, null)
ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, userValues)
ContentResolverUtils.bulkInsert(resolver, Filters.Keywords.CONTENT_URI, keywordValues)
ContentResolverUtils.bulkInsert(resolver, Filters.Sources.CONTENT_URI, sourceValues)

View File

@ -239,15 +239,15 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac
}
}
ContentResolverUtils.bulkDelete(resolver, Filters.Subscriptions.CONTENT_URI, Filters._ID,
false, ids, null)
false, ids, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI, Filters.Users.SOURCE,
false, ids, null)
false, ids, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Keywords.CONTENT_URI, Filters.Keywords.SOURCE,
false, ids, null)
false, ids, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Sources.CONTENT_URI, Filters.Sources.SOURCE,
false, ids, null)
false, ids, null, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Links.CONTENT_URI, Filters.Links.SOURCE,
false, ids, null)
false, ids, null, null)
}
private fun showAddUrlSubscription() {

View File

@ -3,6 +3,8 @@ package org.mariotaku.twidere.model.util
import android.support.annotation.FloatRange
import org.mariotaku.ktextension.convert
import org.mariotaku.microblog.library.twitter.model.DMResponse
import org.mariotaku.microblog.library.twitter.model.DMResponse.Entry.Message
import org.mariotaku.microblog.library.twitter.model.DMResponse.Entry.Message.Data
import org.mariotaku.microblog.library.twitter.model.DirectMessage
import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.twidere.model.ParcelableMedia
@ -73,7 +75,7 @@ object ParcelableMessageUtils {
return "$senderId-$recipientId"
}
private fun ParcelableMessage.applyMessage(accountKey: UserKey, message: DMResponse.Entry.Message) {
private fun ParcelableMessage.applyMessage(accountKey: UserKey, message: Message) {
this.commonEntry(accountKey, message)
val data = message.messageData
@ -86,13 +88,13 @@ object ParcelableMessageUtils {
this.media = media
}
private fun ParcelableMessage.applyConversationCreate(accountKey: UserKey, message: DMResponse.Entry.Message) {
private fun ParcelableMessage.applyConversationCreate(accountKey: UserKey, message: Message) {
this.commonEntry(accountKey, message)
this.message_type = MessageType.CONVERSATION_CREATE
this.is_outgoing = false
}
private fun ParcelableMessage.applyUsersEvent(accountKey: UserKey, message: DMResponse.Entry.Message,
private fun ParcelableMessage.applyUsersEvent(accountKey: UserKey, message: Message,
users: Map<String, User>, @MessageType type: String) {
this.commonEntry(accountKey, message)
this.message_type = type
@ -105,7 +107,7 @@ object ParcelableMessageUtils {
this.is_outgoing = false
}
private fun ParcelableMessage.applyNameUpdatedEvent(accountKey: UserKey, message: DMResponse.Entry.Message,
private fun ParcelableMessage.applyNameUpdatedEvent(accountKey: UserKey, message: Message,
users: Map<String, User>) {
this.commonEntry(accountKey, message)
this.message_type = MessageType.CONVERSATION_NAME_UPDATE
@ -116,7 +118,7 @@ object ParcelableMessageUtils {
this.is_outgoing = false
}
private fun ParcelableMessage.commonEntry(accountKey: UserKey, message: DMResponse.Entry.Message) {
private fun ParcelableMessage.commonEntry(accountKey: UserKey, message: Message) {
val data = message.messageData
this.sender_key = run {
val senderId = data?.senderId ?: message.senderId ?: return@run null
@ -168,7 +170,7 @@ object ParcelableMessageUtils {
return Pair(MessageType.TEXT, null)
}
private fun typeAndExtras(data: DMResponse.Entry.Message.Data): Triple<String, MessageExtras?, Array<ParcelableMedia>?> {
private fun typeAndExtras(data: Data): Triple<String, MessageExtras?, Array<ParcelableMedia>?> {
val attachment = data.attachment ?: return Triple(MessageType.TEXT, null, null)
when {
attachment.photo != null -> {

View File

@ -2,6 +2,7 @@ package org.mariotaku.twidere.task
import android.accounts.AccountManager
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import org.mariotaku.ktextension.toInt
import org.mariotaku.ktextension.useCursor
@ -172,21 +173,35 @@ class GetMessagesTask(
}).userInbox
}
val respConversations = response.conversations
val respEntries = response.entries
val respUsers = response.users
if (respConversations == null || respEntries == null || respUsers == null) {
return GetMessagesData(emptyList(), emptyList())
}
val respConversations = response.conversations.orEmpty()
val respEntries = response.entries.orEmpty()
val respUsers = response.users.orEmpty()
val conversations = hashMapOf<String, ParcelableMessageConversation>()
respConversations.keys.let {
conversations.addLocalConversations(accountKey, it)
}
val messages = respEntries.mapNotNull {
ParcelableMessageUtils.fromEntry(accountKey, it, respUsers)
val messages = ArrayList<ParcelableMessage>()
val messageDeletionsMap = HashMap<String, ArrayList<String>>()
val conversationDeletions = ArrayList<String>()
respEntries.mapNotNullTo(messages) { entry ->
when {
entry.messageDelete != null -> {
val list = messageDeletionsMap.getOrPut(entry.messageDelete.conversationId) { ArrayList<String>() }
entry.messageDelete.messages?.forEach {
list.add(it.messageId)
}
return@mapNotNullTo null
}
entry.removeConversation != null -> {
conversationDeletions.add(entry.removeConversation.conversationId)
return@mapNotNullTo null
}
else -> {
return@mapNotNullTo ParcelableMessageUtils.fromEntry(accountKey, entry, respUsers)
}
}
}
val messagesMap = messages.groupBy(ParcelableMessage::conversation_id)
for ((k, v) in respConversations) {
@ -210,7 +225,8 @@ class GetMessagesTask(
this.status = v.status
}
}
return GetMessagesData(conversations.values, messages)
return GetMessagesData(conversations.values, messages, conversationDeletions,
messageDeletionsMap, response.cursor)
}
private fun getFanfouConversations(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): GetMessagesData {
@ -266,21 +282,6 @@ class GetMessagesTask(
}
}
private fun storeMessages(data: GetMessagesData, details: AccountDetails) {
val resolver = context.contentResolver
val conversationsValues = data.conversations.map {
val values = ParcelableMessageConversationValuesCreator.create(it)
if (it._id > 0) {
values.put(Conversations._ID, it._id)
}
return@map values
}
val messagesValues = data.messages.map(ParcelableMessageValuesCreator::create)
ContentResolverUtils.bulkInsert(resolver, Conversations.CONTENT_URI, conversationsValues)
ContentResolverUtils.bulkInsert(resolver, Messages.CONTENT_URI, messagesValues)
}
private fun ParcelableMessageConversation.addParticipant(
accountKey: UserKey,
user: User
@ -323,10 +324,50 @@ class GetMessagesTask(
return conversation
}
private fun storeMessages(data: GetMessagesData, details: AccountDetails) {
val resolver = context.contentResolver
val conversationsValues = data.conversations.map {
val values = ParcelableMessageConversationValuesCreator.create(it)
if (it._id > 0) {
values.put(Conversations._ID, it._id)
}
return@map values
}
val messagesValues = data.messages.map(ParcelableMessageValuesCreator::create)
for ((conversationId, messageIds) in data.deleteMessages) {
val where = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
Expression.equalsArgs(Messages.CONVERSATION_ID)).sql
val whereArgs = arrayOf(details.key.toString(), conversationId)
ContentResolverUtils.bulkDelete(resolver, Messages.CONTENT_URI, Messages.MESSAGE_ID,
false, messageIds, where, whereArgs)
}
val accountWhere = Expression.equalsArgs(Messages.ACCOUNT_KEY).sql
val accountWhereArgs = arrayOf(details.key.toString())
ContentResolverUtils.bulkDelete(resolver, Conversations.CONTENT_URI, Conversations.CONVERSATION_ID,
false, data.deleteConversations, accountWhere, accountWhereArgs)
ContentResolverUtils.bulkDelete(resolver, Messages.CONTENT_URI, Messages.CONVERSATION_ID,
false, data.deleteConversations, accountWhere, accountWhereArgs)
ContentResolverUtils.bulkInsert(resolver, Conversations.CONTENT_URI, conversationsValues)
ContentResolverUtils.bulkInsert(resolver, Messages.CONTENT_URI, messagesValues)
if (data.conversationRequestCursor != null) {
resolver.update(Conversations.CONTENT_URI, ContentValues().apply {
put(Conversations.REQUEST_CURSOR, data.conversationRequestCursor)
}, accountWhere, accountWhereArgs)
}
}
data class GetMessagesData(
val conversations: Collection<ParcelableMessageConversation>,
val messages: Collection<ParcelableMessage>
val messages: Collection<ParcelableMessage>,
val deleteConversations: List<String> = emptyList(),
val deleteMessages: Map<String, List<String>> = emptyMap(),
val conversationRequestCursor: String? = null
)
class RefreshNewTaskParam(

View File

@ -73,7 +73,7 @@ class GetTrendsTask(
}
ContentResolverUtils.bulkInsert(cr, uri, allTrends.map(ParcelableTrendValuesCreator::create))
ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false,
hashtags, null)
hashtags, null, null)
ContentResolverUtils.bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map {
val values = ContentValues()
values.put(CachedHashtags.NAME, it)

View File

@ -50,13 +50,13 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask<Unit?
// Delete 'orphaned' filter items with `sourceId` > 0
val extraWhere = Expression.greaterThan(Filters.SOURCE, 0).sql
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI, Filters.Users.SOURCE,
true, sourceIds, extraWhere)
true, sourceIds, extraWhere, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Keywords.CONTENT_URI, Filters.Keywords.SOURCE,
true, sourceIds, extraWhere)
true, sourceIds, extraWhere, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Sources.CONTENT_URI, Filters.Sources.SOURCE,
true, sourceIds, extraWhere)
true, sourceIds, extraWhere, null)
ContentResolverUtils.bulkDelete(resolver, Filters.Links.CONTENT_URI, Filters.Links.SOURCE,
true, sourceIds, extraWhere)
true, sourceIds, extraWhere, null)
try {
Thread.sleep(1000)
} catch (e: InterruptedException) {

View File

@ -878,9 +878,12 @@ object DataStoreUtils {
val linkWithoutScheme = userLink.toString().substringAfter("://")
linkValues.add(linkWithoutScheme)
}
ContentResolverUtils.bulkDelete(cr, Filters.Users.CONTENT_URI, Filters.Users.USER_KEY, false, userKeyValues, null)
ContentResolverUtils.bulkDelete(cr, Filters.Keywords.CONTENT_URI, Filters.Keywords.VALUE, false, keywordValues, null)
ContentResolverUtils.bulkDelete(cr, Filters.Links.CONTENT_URI, Filters.Links.VALUE, false, linkValues, null)
ContentResolverUtils.bulkDelete(cr, Filters.Users.CONTENT_URI, Filters.Users.USER_KEY,
false, userKeyValues, null, null)
ContentResolverUtils.bulkDelete(cr, Filters.Keywords.CONTENT_URI, Filters.Keywords.VALUE,
false, keywordValues, null, null)
ContentResolverUtils.bulkDelete(cr, Filters.Links.CONTENT_URI, Filters.Links.VALUE, false,
linkValues, null, null)
}
@WorkerThread

View File

@ -130,7 +130,7 @@ class MultiSelectEventHandler(
}
}
ContentResolverUtils.bulkDelete(resolver, Filters.Users.CONTENT_URI,
Filters.Users.USER_KEY, false, userIds, null)
Filters.Users.USER_KEY, false, userIds, null, null)
ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, valuesList)
Toast.makeText(activity, R.string.message_toast_users_filters_added, Toast.LENGTH_SHORT).show()
mode.finish()

View File

@ -143,7 +143,7 @@ abstract class FileBasedDraftsSyncAction<RemoteFileInfo>(val context: Context) :
val fileList = removeLocalIdsList.joinToString(",") { "$it.eml" }
DebugLog.d(LOGTAG_SYNC, "Removing local drafts $fileList")
ContentResolverUtils.bulkDelete(context.contentResolver, Drafts.CONTENT_URI,
Drafts.UNIQUE_ID, false, removeLocalIdsList, null)
Drafts.UNIQUE_ID, false, removeLocalIdsList, null, null)
}
// Remove remote items

View File

@ -53,13 +53,13 @@ abstract class FileBasedFiltersDataSyncAction<DownloadSession : Closeable, Uploa
override fun removeFromLocal(data: FiltersData) {
ContentResolverUtils.bulkDelete(context.contentResolver, Filters.Users.CONTENT_URI,
Filters.Users.USER_KEY, false, data.users?.map { it.userKey }, null)
Filters.Users.USER_KEY, false, data.users?.map { it.userKey }, null, null)
ContentResolverUtils.bulkDelete(context.contentResolver, Filters.Keywords.CONTENT_URI,
Filters.Keywords.VALUE, false, data.keywords?.map { it.value }, null)
Filters.Keywords.VALUE, false, data.keywords?.map { it.value }, null, null)
ContentResolverUtils.bulkDelete(context.contentResolver, Filters.Sources.CONTENT_URI,
Filters.Sources.VALUE, false, data.sources?.map { it.value }, null)
Filters.Sources.VALUE, false, data.sources?.map { it.value }, null, null)
ContentResolverUtils.bulkDelete(context.contentResolver, Filters.Links.CONTENT_URI,
Filters.Links.VALUE, false, data.links?.map { it.value }, null)
Filters.Links.VALUE, false, data.links?.map { it.value }, null, null)
}
override fun newData(): FiltersData {

View File

@ -112,7 +112,7 @@ class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) :
const val layoutResource = R.layout.list_item_message_conversation_text
fun MessageBubbleView.setOutgoing(outgoing: Boolean) {
setCaretPosition(if (outgoing) MessageBubbleView.BOTTOM_END else MessageBubbleView.TOP_START)
setCaretPosition(if (outgoing) MessageBubbleView.TOP_END else MessageBubbleView.BOTTOM_START)
}
}
}

View File

@ -45,7 +45,7 @@
android:id="@+id/profileImage"
android:layout_width="@dimen/profile_image_size_direct_message"
android:layout_height="@dimen/profile_image_size_direct_message"
android:layout_alignParentTop="true"
android:layout_alignBottom="@+id/messageBubble"
tools:src="@drawable/ic_profile_image_twidere"/>
<org.mariotaku.messagebubbleview.library.MessageBubbleView
@ -55,9 +55,10 @@
android:layout_toEndOf="@+id/profileImage"
android:layout_toRightOf="@+id/profileImage"
android:clickable="true"
android:minHeight="@dimen/profile_image_size_direct_message"
app:bubbleColor="?messageBubbleColor"
app:caretHeight="@dimen/element_spacing_normal"
app:caretPosition="topStart"
app:caretPosition="bottomStart"
app:caretWidth="@dimen/element_spacing_normal"
app:cornerRadius="2dp">
@ -72,6 +73,7 @@
android:id="@+id/mediaPreview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="200dp"
android:visibility="gone">
<include layout="@layout/layout_card_media_preview"/>