mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 20:15:21 +00:00
Merge pull request #1466 from AL-Session/SES1688_LastDeletedMessageFix
SES1688 - Last deleted message REFIX
This commit is contained in:
commit
e1652f8c6b
@ -35,11 +35,28 @@ class ContactListAdapter(
|
|||||||
binding.profilePictureView.update(contact.recipient)
|
binding.profilePictureView.update(contact.recipient)
|
||||||
binding.nameTextView.text = contact.displayName
|
binding.nameTextView.text = contact.displayName
|
||||||
binding.root.setOnClickListener { listener(contact.recipient) }
|
binding.root.setOnClickListener { listener(contact.recipient) }
|
||||||
|
|
||||||
|
// TODO: When we implement deleting contacts (hide might be safest) then probably set a long-click listener here w/ something like:
|
||||||
|
/*
|
||||||
|
binding.root.setOnLongClickListener {
|
||||||
|
Log.w("[ACL]", "Long clicked on contact ${contact.recipient.name}")
|
||||||
|
binding.contentView.context.showSessionDialog {
|
||||||
|
title("Delete Contact")
|
||||||
|
text("Are you sure you want to delete this contact?")
|
||||||
|
button(R.string.delete) {
|
||||||
|
val contacts = configFactory.contacts ?: return
|
||||||
|
contacts.upsertContact(contact.recipient.address.serialize()) { priority = PRIORITY_HIDDEN }
|
||||||
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
||||||
|
endActionMode()
|
||||||
|
}
|
||||||
|
cancelButton(::endActionMode)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unbind() {
|
fun unbind() { binding.profilePictureView.recycle() }
|
||||||
binding.profilePictureView.recycle()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HeaderViewHolder(
|
class HeaderViewHolder(
|
||||||
@ -52,15 +69,11 @@ class ContactListAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int { return items.size }
|
||||||
return items.size
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
|
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
|
||||||
super.onViewRecycled(holder)
|
super.onViewRecycled(holder)
|
||||||
if (holder is ContactViewHolder) {
|
if (holder is ContactViewHolder) { holder.unbind() }
|
||||||
holder.unbind()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
@ -72,13 +85,9 @@ class ContactListAdapter(
|
|||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return if (viewType == ViewType.Contact) {
|
return if (viewType == ViewType.Contact) {
|
||||||
ContactViewHolder(
|
ContactViewHolder(ViewContactBinding.inflate(LayoutInflater.from(context), parent, false))
|
||||||
ViewContactBinding.inflate(LayoutInflater.from(context), parent, false)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
HeaderViewHolder(
|
HeaderViewHolder(ContactSectionHeaderBinding.inflate(LayoutInflater.from(context), parent, false))
|
||||||
ContactSectionHeaderBinding.inflate(LayoutInflater.from(context), parent, false)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,15 +22,11 @@ import android.content.Context;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||||
import net.zetetic.database.sqlcipher.SQLiteStatement;
|
import net.zetetic.database.sqlcipher.SQLiteStatement;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.session.libsession.messaging.calls.CallMessageType;
|
import org.session.libsession.messaging.calls.CallMessageType;
|
||||||
import org.session.libsession.messaging.messages.signal.IncomingGroupMessage;
|
import org.session.libsession.messaging.messages.signal.IncomingGroupMessage;
|
||||||
@ -51,7 +47,6 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
|||||||
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@ -634,7 +629,7 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
long threadId = getThreadIdForMessage(messageId);
|
long threadId = getThreadIdForMessage(messageId);
|
||||||
db.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""});
|
db.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""});
|
||||||
notifyConversationListeners(threadId);
|
notifyConversationListeners(threadId);
|
||||||
boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false, true);
|
boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false, false);
|
||||||
return threadDeleted;
|
return threadDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,12 +696,7 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package */void deleteThread(long threadId) {
|
void deleteMessagesInThreadBeforeDate(long threadId, long date) {
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
|
||||||
db.delete(TABLE_NAME, THREAD_ID + " = ?", new String[] {threadId+""});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*package*/void deleteMessagesInThreadBeforeDate(long threadId, long date) {
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
String where = THREAD_ID + " = ? AND (CASE " + TYPE;
|
String where = THREAD_ID + " = ? AND (CASE " + TYPE;
|
||||||
|
|
||||||
@ -719,7 +709,12 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
db.delete(TABLE_NAME, where, new String[] {threadId + ""});
|
db.delete(TABLE_NAME, where, new String[] {threadId + ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ void deleteThreads(Set<Long> threadIds) {
|
void deleteThread(long threadId) {
|
||||||
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
|
db.delete(TABLE_NAME, THREAD_ID + " = ?", new String[] {threadId+""});
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteThreads(Set<Long> threadIds) {
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
String where = "";
|
String where = "";
|
||||||
|
|
||||||
@ -727,23 +722,23 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
where += THREAD_ID + " = '" + threadId + "' OR ";
|
where += THREAD_ID + " = '" + threadId + "' OR ";
|
||||||
}
|
}
|
||||||
|
|
||||||
where = where.substring(0, where.length() - 4);
|
where = where.substring(0, where.length() - 4); // Remove the final: "' OR "
|
||||||
|
|
||||||
db.delete(TABLE_NAME, where, null);
|
db.delete(TABLE_NAME, where, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package */ void deleteAllThreads() {
|
void deleteAllThreads() {
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.delete(TABLE_NAME, null, null);
|
db.delete(TABLE_NAME, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ SQLiteDatabase beginTransaction() {
|
SQLiteDatabase beginTransaction() {
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ void endTransaction(SQLiteDatabase database) {
|
void endTransaction(SQLiteDatabase database) {
|
||||||
database.setTransactionSuccessful();
|
database.setTransactionSuccessful();
|
||||||
database.endTransaction();
|
database.endTransaction();
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ private const val TAG = "Storage"
|
|||||||
open class Storage(
|
open class Storage(
|
||||||
context: Context,
|
context: Context,
|
||||||
helper: SQLCipherOpenHelper,
|
helper: SQLCipherOpenHelper,
|
||||||
private val configFactory: ConfigFactory
|
val configFactory: ConfigFactory
|
||||||
) : Database(context, helper), StorageProtocol, ThreadDatabase.ConversationThreadUpdateListener {
|
) : Database(context, helper), StorageProtocol, ThreadDatabase.ConversationThreadUpdateListener {
|
||||||
|
|
||||||
override fun threadCreated(address: Address, threadId: Long) {
|
override fun threadCreated(address: Address, threadId: Long) {
|
||||||
@ -1371,31 +1371,31 @@ open class Storage(
|
|||||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||||
val groupDB = DatabaseComponent.get(context).groupDatabase()
|
val groupDB = DatabaseComponent.get(context).groupDatabase()
|
||||||
threadDB.deleteConversation(threadID)
|
threadDB.deleteConversation(threadID)
|
||||||
val recipient = getRecipientForThread(threadID) ?: return
|
|
||||||
when {
|
val recipient = getRecipientForThread(threadID)
|
||||||
recipient.isContactRecipient -> {
|
if (recipient == null) {
|
||||||
if (recipient.isLocalNumber) return
|
Log.w(TAG, "Got null recipient when deleting conversation - aborting.");
|
||||||
val contacts = configFactory.contacts ?: return
|
return
|
||||||
contacts.upsertContact(recipient.address.serialize()) { priority = PRIORITY_HIDDEN }
|
|
||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
|
||||||
}
|
}
|
||||||
recipient.isClosedGroupRecipient -> {
|
|
||||||
// TODO: handle closed group
|
// There is nothing further we need to do if this is a 1-on-1 conversation, and it's not
|
||||||
|
// possible to delete communities in this manner so bail.
|
||||||
|
if (recipient.isContactRecipient || recipient.isCommunityRecipient) return
|
||||||
|
|
||||||
|
// If we get here then this is a closed group conversation (i.e., recipient.isClosedGroupRecipient)
|
||||||
val volatile = configFactory.convoVolatile ?: return
|
val volatile = configFactory.convoVolatile ?: return
|
||||||
val groups = configFactory.userGroups ?: return
|
val groups = configFactory.userGroups ?: return
|
||||||
val groupID = recipient.address.toGroupString()
|
val groupID = recipient.address.toGroupString()
|
||||||
val closedGroup = getGroup(groupID)
|
val closedGroup = getGroup(groupID)
|
||||||
val groupPublicKey = GroupUtil.doubleDecodeGroupId(recipient.address.serialize())
|
val groupPublicKey = GroupUtil.doubleDecodeGroupId(recipient.address.serialize())
|
||||||
if (closedGroup != null) {
|
if (closedGroup != null) {
|
||||||
groupDB.delete(groupID) // TODO: Should we delete the group? (seems odd to leave it)
|
groupDB.delete(groupID)
|
||||||
volatile.eraseLegacyClosedGroup(groupPublicKey)
|
volatile.eraseLegacyClosedGroup(groupPublicKey)
|
||||||
groups.eraseLegacyGroup(groupPublicKey)
|
groups.eraseLegacyGroup(groupPublicKey)
|
||||||
} else {
|
} else {
|
||||||
Log.w("Loki-DBG", "Failed to find a closed group for ${groupPublicKey.take(4)}")
|
Log.w("Loki-DBG", "Failed to find a closed group for ${groupPublicKey.take(4)}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAttachmentDataUri(attachmentId: AttachmentId): Uri {
|
override fun getAttachmentDataUri(attachmentId: AttachmentId): Uri {
|
||||||
return PartAuthority.getAttachmentDataUri(attachmentId)
|
return PartAuthority.getAttachmentDataUri(attachmentId)
|
||||||
|
@ -26,14 +26,10 @@ import android.content.Context;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.MergeCursor;
|
import android.database.MergeCursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.session.libsession.snode.SnodeAPI;
|
import org.session.libsession.snode.SnodeAPI;
|
||||||
import org.session.libsession.utilities.Address;
|
import org.session.libsession.utilities.Address;
|
||||||
@ -61,7 +57,6 @@ import org.thoughtcrime.securesms.mms.Slide;
|
|||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
||||||
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
|
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -83,7 +78,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public static final String TABLE_NAME = "thread";
|
public static final String TABLE_NAME = "thread";
|
||||||
public static final String ID = "_id";
|
public static final String ID = "_id";
|
||||||
public static final String DATE = "date";
|
public static final String THREAD_CREATION_DATE = "date";
|
||||||
public static final String MESSAGE_COUNT = "message_count";
|
public static final String MESSAGE_COUNT = "message_count";
|
||||||
public static final String ADDRESS = "recipient_ids";
|
public static final String ADDRESS = "recipient_ids";
|
||||||
public static final String SNIPPET = "snippet";
|
public static final String SNIPPET = "snippet";
|
||||||
@ -91,7 +86,7 @@ public class ThreadDatabase extends Database {
|
|||||||
public static final String READ = "read";
|
public static final String READ = "read";
|
||||||
public static final String UNREAD_COUNT = "unread_count";
|
public static final String UNREAD_COUNT = "unread_count";
|
||||||
public static final String UNREAD_MENTION_COUNT = "unread_mention_count";
|
public static final String UNREAD_MENTION_COUNT = "unread_mention_count";
|
||||||
public static final String TYPE = "type";
|
public static final String DISTRIBUTION_TYPE = "type"; // See: DistributionTypes.kt
|
||||||
private static final String ERROR = "error";
|
private static final String ERROR = "error";
|
||||||
public static final String SNIPPET_TYPE = "snippet_type";
|
public static final String SNIPPET_TYPE = "snippet_type";
|
||||||
public static final String SNIPPET_URI = "snippet_uri";
|
public static final String SNIPPET_URI = "snippet_uri";
|
||||||
@ -105,23 +100,23 @@ public class ThreadDatabase extends Database {
|
|||||||
public static final String IS_PINNED = "is_pinned";
|
public static final String IS_PINNED = "is_pinned";
|
||||||
|
|
||||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
|
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
|
||||||
ID + " INTEGER PRIMARY KEY, " + DATE + " INTEGER DEFAULT 0, " +
|
ID + " INTEGER PRIMARY KEY, " + THREAD_CREATION_DATE + " INTEGER DEFAULT 0, " +
|
||||||
MESSAGE_COUNT + " INTEGER DEFAULT 0, " + ADDRESS + " TEXT, " + SNIPPET + " TEXT, " +
|
MESSAGE_COUNT + " INTEGER DEFAULT 0, " + ADDRESS + " TEXT, " + SNIPPET + " TEXT, " +
|
||||||
SNIPPET_CHARSET + " INTEGER DEFAULT 0, " + READ + " INTEGER DEFAULT 1, " +
|
SNIPPET_CHARSET + " INTEGER DEFAULT 0, " + READ + " INTEGER DEFAULT 1, " +
|
||||||
TYPE + " INTEGER DEFAULT 0, " + ERROR + " INTEGER DEFAULT 0, " +
|
DISTRIBUTION_TYPE + " INTEGER DEFAULT 0, " + ERROR + " INTEGER DEFAULT 0, " +
|
||||||
SNIPPET_TYPE + " INTEGER DEFAULT 0, " + SNIPPET_URI + " TEXT DEFAULT NULL, " +
|
SNIPPET_TYPE + " INTEGER DEFAULT 0, " + SNIPPET_URI + " TEXT DEFAULT NULL, " +
|
||||||
ARCHIVED + " INTEGER DEFAULT 0, " + STATUS + " INTEGER DEFAULT 0, " +
|
ARCHIVED + " INTEGER DEFAULT 0, " + STATUS + " INTEGER DEFAULT 0, " +
|
||||||
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + EXPIRES_IN + " INTEGER DEFAULT 0, " +
|
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + EXPIRES_IN + " INTEGER DEFAULT 0, " +
|
||||||
LAST_SEEN + " INTEGER DEFAULT 0, " + HAS_SENT + " INTEGER DEFAULT 0, " +
|
LAST_SEEN + " INTEGER DEFAULT 0, " + HAS_SENT + " INTEGER DEFAULT 0, " +
|
||||||
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNREAD_COUNT + " INTEGER DEFAULT 0);";
|
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNREAD_COUNT + " INTEGER DEFAULT 0);";
|
||||||
|
|
||||||
public static final String[] CREATE_INDEXS = {
|
public static final String[] CREATE_INDEXES = {
|
||||||
"CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + ADDRESS + ");",
|
"CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + ADDRESS + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS archived_count_index ON " + TABLE_NAME + " (" + ARCHIVED + ", " + MESSAGE_COUNT + ");",
|
"CREATE INDEX IF NOT EXISTS archived_count_index ON " + TABLE_NAME + " (" + ARCHIVED + ", " + MESSAGE_COUNT + ");",
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] THREAD_PROJECTION = {
|
private static final String[] THREAD_PROJECTION = {
|
||||||
ID, DATE, MESSAGE_COUNT, ADDRESS, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, UNREAD_MENTION_COUNT, TYPE, ERROR, SNIPPET_TYPE,
|
ID, THREAD_CREATION_DATE, MESSAGE_COUNT, ADDRESS, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, UNREAD_MENTION_COUNT, DISTRIBUTION_TYPE, ERROR, SNIPPET_TYPE,
|
||||||
SNIPPET_URI, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN, READ_RECEIPT_COUNT, IS_PINNED
|
SNIPPET_URI, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN, READ_RECEIPT_COUNT, IS_PINNED
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,11 +153,10 @@ public class ThreadDatabase extends Database {
|
|||||||
ContentValues contentValues = new ContentValues(4);
|
ContentValues contentValues = new ContentValues(4);
|
||||||
long date = SnodeAPI.getNowWithOffset();
|
long date = SnodeAPI.getNowWithOffset();
|
||||||
|
|
||||||
contentValues.put(DATE, date - date % 1000);
|
contentValues.put(THREAD_CREATION_DATE, date - date % 1000);
|
||||||
contentValues.put(ADDRESS, address.serialize());
|
contentValues.put(ADDRESS, address.serialize());
|
||||||
|
|
||||||
if (group)
|
if (group) contentValues.put(DISTRIBUTION_TYPE, distributionType);
|
||||||
contentValues.put(TYPE, distributionType);
|
|
||||||
|
|
||||||
contentValues.put(MESSAGE_COUNT, 0);
|
contentValues.put(MESSAGE_COUNT, 0);
|
||||||
|
|
||||||
@ -175,7 +169,7 @@ public class ThreadDatabase extends Database {
|
|||||||
long expiresIn, int readReceiptCount)
|
long expiresIn, int readReceiptCount)
|
||||||
{
|
{
|
||||||
ContentValues contentValues = new ContentValues(7);
|
ContentValues contentValues = new ContentValues(7);
|
||||||
contentValues.put(DATE, date - date % 1000);
|
contentValues.put(THREAD_CREATION_DATE, date - date % 1000);
|
||||||
contentValues.put(MESSAGE_COUNT, count);
|
contentValues.put(MESSAGE_COUNT, count);
|
||||||
if (!body.isEmpty()) {
|
if (!body.isEmpty()) {
|
||||||
contentValues.put(SNIPPET, body);
|
contentValues.put(SNIPPET, body);
|
||||||
@ -187,9 +181,7 @@ public class ThreadDatabase extends Database {
|
|||||||
contentValues.put(READ_RECEIPT_COUNT, readReceiptCount);
|
contentValues.put(READ_RECEIPT_COUNT, readReceiptCount);
|
||||||
contentValues.put(EXPIRES_IN, expiresIn);
|
contentValues.put(EXPIRES_IN, expiresIn);
|
||||||
|
|
||||||
if (unarchive) {
|
if (unarchive) { contentValues.put(ARCHIVED, 0); }
|
||||||
contentValues.put(ARCHIVED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""});
|
db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""});
|
||||||
@ -199,7 +191,7 @@ public class ThreadDatabase extends Database {
|
|||||||
public void updateSnippet(long threadId, String snippet, @Nullable Uri attachment, long date, long type, boolean unarchive) {
|
public void updateSnippet(long threadId, String snippet, @Nullable Uri attachment, long date, long type, boolean unarchive) {
|
||||||
ContentValues contentValues = new ContentValues(4);
|
ContentValues contentValues = new ContentValues(4);
|
||||||
|
|
||||||
contentValues.put(DATE, date - date % 1000);
|
contentValues.put(THREAD_CREATION_DATE, date - date % 1000);
|
||||||
if (!snippet.isEmpty()) {
|
if (!snippet.isEmpty()) {
|
||||||
contentValues.put(SNIPPET, snippet);
|
contentValues.put(SNIPPET, snippet);
|
||||||
}
|
}
|
||||||
@ -230,9 +222,7 @@ public class ThreadDatabase extends Database {
|
|||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
String where = "";
|
String where = "";
|
||||||
|
|
||||||
for (long threadId : threadIds) {
|
for (long threadId : threadIds) { where += ID + " = '" + threadId + "' OR "; }
|
||||||
where += ID + " = '" + threadId + "' OR ";
|
|
||||||
}
|
|
||||||
|
|
||||||
where = where.substring(0, where.length() - 4);
|
where = where.substring(0, where.length() - 4);
|
||||||
|
|
||||||
@ -358,7 +348,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public void setDistributionType(long threadId, int distributionType) {
|
public void setDistributionType(long threadId, int distributionType) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(TYPE, distributionType);
|
contentValues.put(DISTRIBUTION_TYPE, distributionType);
|
||||||
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
|
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
|
||||||
@ -367,7 +357,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public void setDate(long threadId, long date) {
|
public void setDate(long threadId, long date) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(DATE, date);
|
contentValues.put(THREAD_CREATION_DATE, date);
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
int updated = db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
int updated = db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
||||||
if (updated > 0) notifyConversationListListeners();
|
if (updated > 0) notifyConversationListListeners();
|
||||||
@ -375,11 +365,11 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public int getDistributionType(long threadId) {
|
public int getDistributionType(long threadId) {
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = db.query(TABLE_NAME, new String[]{TYPE}, ID_WHERE, new String[]{String.valueOf(threadId)}, null, null, null);
|
Cursor cursor = db.query(TABLE_NAME, new String[]{DISTRIBUTION_TYPE}, ID_WHERE, new String[]{String.valueOf(threadId)}, null, null, null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
return cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
|
return cursor.getInt(cursor.getColumnIndexOrThrow(DISTRIBUTION_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return DistributionTypes.DEFAULT;
|
return DistributionTypes.DEFAULT;
|
||||||
@ -469,7 +459,7 @@ public class ThreadDatabase extends Database {
|
|||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String where = "SELECT " + DATE + " FROM " + TABLE_NAME +
|
String where = "SELECT " + THREAD_CREATION_DATE + " FROM " + TABLE_NAME +
|
||||||
" LEFT OUTER JOIN " + RecipientDatabase.TABLE_NAME +
|
" LEFT OUTER JOIN " + RecipientDatabase.TABLE_NAME +
|
||||||
" ON " + TABLE_NAME + "." + ADDRESS + " = " + RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.ADDRESS +
|
" ON " + TABLE_NAME + "." + ADDRESS + " = " + RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.ADDRESS +
|
||||||
" LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME +
|
" LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME +
|
||||||
@ -477,7 +467,7 @@ public class ThreadDatabase extends Database {
|
|||||||
" WHERE " + MESSAGE_COUNT + " != 0 AND " + ARCHIVED + " = 0 AND " + HAS_SENT + " = 0 AND " +
|
" WHERE " + MESSAGE_COUNT + " != 0 AND " + ARCHIVED + " = 0 AND " + HAS_SENT + " = 0 AND " +
|
||||||
RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.BLOCK + " = 0 AND " +
|
RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.BLOCK + " = 0 AND " +
|
||||||
RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.APPROVED + " = 0 AND " +
|
RecipientDatabase.TABLE_NAME + "." + RecipientDatabase.APPROVED + " = 0 AND " +
|
||||||
GroupDatabase.TABLE_NAME + "." + GROUP_ID + " IS NULL ORDER BY " + DATE + " DESC LIMIT 1";
|
GroupDatabase.TABLE_NAME + "." + GROUP_ID + " IS NULL ORDER BY " + THREAD_CREATION_DATE + " DESC LIMIT 1";
|
||||||
cursor = db.rawQuery(where, null);
|
cursor = db.rawQuery(where, null);
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst())
|
if (cursor != null && cursor.moveToFirst())
|
||||||
@ -595,7 +585,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public Long getLastUpdated(long threadId) {
|
public Long getLastUpdated(long threadId) {
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = db.query(TABLE_NAME, new String[]{DATE}, ID_WHERE, new String[]{String.valueOf(threadId)}, null, null, null);
|
Cursor cursor = db.query(TABLE_NAME, new String[]{THREAD_CREATION_DATE}, ID_WHERE, new String[]{String.valueOf(threadId)}, null, null, null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
@ -736,7 +726,7 @@ public class ThreadDatabase extends Database {
|
|||||||
MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
|
MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
|
||||||
long count = mmsSmsDatabase.getConversationCount(threadId);
|
long count = mmsSmsDatabase.getConversationCount(threadId);
|
||||||
|
|
||||||
boolean shouldDeleteEmptyThread = shouldDeleteOnEmpty && deleteThreadOnEmpty(threadId);
|
boolean shouldDeleteEmptyThread = shouldDeleteOnEmpty && possibleToDeleteThreadOnEmpty(threadId);
|
||||||
|
|
||||||
if (count == 0 && shouldDeleteEmptyThread) {
|
if (count == 0 && shouldDeleteEmptyThread) {
|
||||||
deleteThread(threadId);
|
deleteThread(threadId);
|
||||||
@ -810,7 +800,7 @@ public class ThreadDatabase extends Database {
|
|||||||
return setLastSeen(threadId, lastSeenTime);
|
return setLastSeen(threadId, lastSeenTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteThreadOnEmpty(long threadId) {
|
private boolean possibleToDeleteThreadOnEmpty(long threadId) {
|
||||||
Recipient threadRecipient = getRecipientForThreadId(threadId);
|
Recipient threadRecipient = getRecipientForThreadId(threadId);
|
||||||
return threadRecipient != null && !threadRecipient.isCommunityRecipient();
|
return threadRecipient != null && !threadRecipient.isCommunityRecipient();
|
||||||
}
|
}
|
||||||
@ -855,7 +845,7 @@ public class ThreadDatabase extends Database {
|
|||||||
" LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME +
|
" LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME +
|
||||||
" ON " + TABLE_NAME + "." + ADDRESS + " = " + GroupDatabase.TABLE_NAME + "." + GROUP_ID +
|
" ON " + TABLE_NAME + "." + ADDRESS + " = " + GroupDatabase.TABLE_NAME + "." + GROUP_ID +
|
||||||
" WHERE " + where +
|
" WHERE " + where +
|
||||||
" ORDER BY " + TABLE_NAME + "." + IS_PINNED + " DESC, " + TABLE_NAME + "." + DATE + " DESC";
|
" ORDER BY " + TABLE_NAME + "." + IS_PINNED + " DESC, " + TABLE_NAME + "." + THREAD_CREATION_DATE + " DESC";
|
||||||
|
|
||||||
if (limit > 0) {
|
if (limit > 0) {
|
||||||
query += " LIMIT " + limit;
|
query += " LIMIT " + limit;
|
||||||
@ -900,7 +890,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public ThreadRecord getCurrent() {
|
public ThreadRecord getCurrent() {
|
||||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
|
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
|
||||||
int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.TYPE));
|
int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.DISTRIBUTION_TYPE));
|
||||||
Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.ADDRESS)));
|
Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.ADDRESS)));
|
||||||
|
|
||||||
Optional<RecipientSettings> settings;
|
Optional<RecipientSettings> settings;
|
||||||
@ -916,7 +906,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
Recipient recipient = Recipient.from(context, address, settings, groupRecord, true);
|
Recipient recipient = Recipient.from(context, address, settings, groupRecord, true);
|
||||||
String body = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET));
|
String body = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET));
|
||||||
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
|
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.THREAD_CREATION_DATE));
|
||||||
long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));
|
long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));
|
||||||
int unreadCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT));
|
int unreadCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT));
|
||||||
int unreadMentionCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_MENTION_COUNT));
|
int unreadMentionCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_MENTION_COUNT));
|
||||||
|
@ -357,7 +357,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
executeStatements(db, SmsDatabase.CREATE_INDEXS);
|
executeStatements(db, SmsDatabase.CREATE_INDEXS);
|
||||||
executeStatements(db, MmsDatabase.CREATE_INDEXS);
|
executeStatements(db, MmsDatabase.CREATE_INDEXS);
|
||||||
executeStatements(db, AttachmentDatabase.CREATE_INDEXS);
|
executeStatements(db, AttachmentDatabase.CREATE_INDEXS);
|
||||||
executeStatements(db, ThreadDatabase.CREATE_INDEXS);
|
executeStatements(db, ThreadDatabase.CREATE_INDEXES);
|
||||||
executeStatements(db, DraftDatabase.CREATE_INDEXS);
|
executeStatements(db, DraftDatabase.CREATE_INDEXS);
|
||||||
executeStatements(db, GroupDatabase.CREATE_INDEXS);
|
executeStatements(db, GroupDatabase.CREATE_INDEXS);
|
||||||
executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES);
|
executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES);
|
||||||
|
@ -4,19 +4,14 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
|
|||||||
|
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
import app.cash.copper.Query
|
import app.cash.copper.Query
|
||||||
import app.cash.copper.flow.observeQuery
|
import app.cash.copper.flow.observeQuery
|
||||||
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.resumeWithException
|
import kotlin.coroutines.resumeWithException
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
import org.session.libsession.database.MessageDataProvider
|
import org.session.libsession.database.MessageDataProvider
|
||||||
import org.session.libsession.messaging.messages.Destination
|
import org.session.libsession.messaging.messages.Destination
|
||||||
import org.session.libsession.messaging.messages.control.MessageRequestResponse
|
import org.session.libsession.messaging.messages.control.MessageRequestResponse
|
||||||
@ -32,9 +27,7 @@ import org.session.libsession.utilities.GroupUtil
|
|||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
|
|
||||||
import org.session.libsignal.utilities.toHexString
|
import org.session.libsignal.utilities.toHexString
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseContentProviders
|
import org.thoughtcrime.securesms.database.DatabaseContentProviders
|
||||||
import org.thoughtcrime.securesms.database.DraftDatabase
|
import org.thoughtcrime.securesms.database.DraftDatabase
|
||||||
import org.thoughtcrime.securesms.database.ExpirationConfigurationDatabase
|
import org.thoughtcrime.securesms.database.ExpirationConfigurationDatabase
|
||||||
@ -51,7 +44,6 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
|||||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||||
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
interface ConversationRepository {
|
interface ConversationRepository {
|
||||||
@ -239,7 +231,7 @@ class DefaultConversationRepository @Inject constructor(
|
|||||||
.success {
|
.success {
|
||||||
continuation.resume(ResultOf.Success(Unit))
|
continuation.resume(ResultOf.Success(Unit))
|
||||||
}.fail { error ->
|
}.fail { error ->
|
||||||
Log.w("[onversationRepository", "Call to SnodeAPI.deleteMessage failed - attempting to resume..")
|
Log.w("ConversationRepository", "Call to SnodeAPI.deleteMessage failed - attempting to resume..")
|
||||||
continuation.resumeWithException(error)
|
continuation.resumeWithException(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,9 +322,7 @@ class DefaultConversationRepository @Inject constructor(
|
|||||||
while (reader.next != null) {
|
while (reader.next != null) {
|
||||||
deleteMessageRequest(reader.current)
|
deleteMessageRequest(reader.current)
|
||||||
val recipient = reader.current.recipient
|
val recipient = reader.current.recipient
|
||||||
if (block) {
|
if (block) { setBlocked(recipient, true) }
|
||||||
setBlocked(recipient, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResultOf.Success(Unit)
|
return ResultOf.Success(Unit)
|
||||||
@ -359,9 +349,7 @@ class DefaultConversationRepository @Inject constructor(
|
|||||||
val cursor = mmsSmsDb.getConversation(threadId, true)
|
val cursor = mmsSmsDb.getConversation(threadId, true)
|
||||||
mmsSmsDb.readerFor(cursor).use { reader ->
|
mmsSmsDb.readerFor(cursor).use { reader ->
|
||||||
while (reader.next != null) {
|
while (reader.next != null) {
|
||||||
if (!reader.current.isOutgoing) {
|
if (!reader.current.isOutgoing) { return true }
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
Loading…
Reference in New Issue
Block a user