feat: add in remove attachments but not link previews

This commit is contained in:
0x330a 2022-11-23 14:02:51 +11:00
parent e12568673f
commit 75a10f71c3
7 changed files with 89 additions and 32 deletions

View file

@ -52,6 +52,7 @@ import androidx.viewpager.widget.ViewPager;
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
import com.google.android.material.tabs.TabLayout;
import org.session.libsession.database.StorageProtocol;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.messaging.messages.control.DataExtractionNotification;
import org.session.libsession.messaging.sending_receiving.MessageSender;
@ -68,7 +69,6 @@ import org.thoughtcrime.securesms.database.MediaDatabase;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.AttachmentUtil;
@ -164,7 +164,11 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity i
if (v.getId() == R.id.clearMedia) {
FragmentManager fm = getSupportFragmentManager();
ClearAllMediaDialog dialog = new ClearAllMediaDialog(() -> {
MediaDatabase mediaDb = DatabaseComponent.get(this).mediaDatabase();
StorageProtocol storage = MessagingModuleConfiguration.getShared().getStorage();
Long threadId = storage.getThreadId(recipient);
if (threadId != null) {
storage.clearMedia(threadId, null);
}
return Unit.INSTANCE;
});
dialog.show(fm, "ClearAllMedia");

View file

@ -943,10 +943,6 @@ public class AttachmentDatabase extends Database {
@SuppressLint("NewApi")
private ThumbnailData generateVideoThumbnail(AttachmentId attachmentId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Video thumbnails not supported...");
return null;
}
DataInfo dataInfo = getAttachmentDataFileInfo(attachmentId, DATA);

View file

@ -44,7 +44,8 @@ public class MediaDatabase extends Database {
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.ADDRESS + " "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.ADDRESS + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.LINK_PREVIEWS + " "
+ "FROM " + AttachmentDatabase.TABLE_NAME + " LEFT JOIN " + MmsDatabase.TABLE_NAME
+ " ON " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " "
+ "WHERE " + AttachmentDatabase.MMS_ID + " IN (SELECT " + MmsSmsColumns.ID
@ -52,7 +53,8 @@ public class MediaDatabase extends Database {
+ " WHERE " + MmsDatabase.THREAD_ID + " = ?) AND (%s) AND "
+ AttachmentDatabase.DATA + " IS NOT NULL AND "
+ AttachmentDatabase.QUOTE + " = 0 AND "
+ AttachmentDatabase.STICKER_PACK_ID + " IS NULL "
+ AttachmentDatabase.STICKER_PACK_ID + " IS NULL AND "
+ MmsDatabase.LINK_PREVIEWS + " IS NULL "
+ "ORDER BY " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " DESC";
private static final String GALLERY_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, AttachmentDatabase.CONTENT_TYPE + " LIKE 'image/%' OR " + AttachmentDatabase.CONTENT_TYPE + " LIKE 'video/%'");

View file

@ -933,23 +933,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
}
}
private fun deleteQuotedFromMessages(toDeleteRecords: List<MessageRecord>) {
if (toDeleteRecords.isEmpty()) return
val queryBuilder = StringBuilder()
for (i in toDeleteRecords.indices) {
queryBuilder.append("$QUOTE_ID = ").append(toDeleteRecords[i].getId())
if (i + 1 < toDeleteRecords.size) {
queryBuilder.append(" OR ")
}
}
val query = queryBuilder.toString()
val db = databaseHelper.writableDatabase
val values = ContentValues(2)
values.put(QUOTE_MISSING, 1)
values.put(QUOTE_AUTHOR, "")
db!!.update(TABLE_NAME, values, query, null)
}
/**
* Delete all the messages in single queries where possible
* @param messageIds a String array representation of regularly Long types representing message IDs
@ -1016,6 +999,62 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
deleteThreads(setOf(threadId))
}
fun deleteMediaFor(threadId: Long, fromUser: String? = null) {
val db = databaseHelper.writableDatabase
val whereString =
if (fromUser == null) "$THREAD_ID = ? AND $LINK_PREVIEWS IS NULL"
else "$THREAD_ID = ? AND $ADDRESS = ? AND $LINK_PREVIEWS IS NULL"
val whereArgs = if (fromUser == null) arrayOf(threadId.toString()) else arrayOf(threadId.toString(), fromUser)
var cursor: Cursor? = null
try {
cursor = db.query(TABLE_NAME, arrayOf(ID), whereString, whereArgs, null, null, null, null)
val toDeleteStringMessageIds = mutableListOf<String>()
while (cursor.moveToNext()) {
toDeleteStringMessageIds += cursor.getLong(0).toString() // get the ID as a string
}
// TODO: this can probably be optimized out,
// currently attachmentDB uses MmsID not threadID which makes it difficult to delete
// and clean up on threadID alone
toDeleteStringMessageIds.toList().chunked(50).forEach { sublist ->
deleteMessages(sublist.toTypedArray())
}
} finally {
cursor?.close()
}
val threadDb = get(context).threadDatabase()
threadDb.update(threadId, false)
notifyConversationListeners(threadId)
notifyStickerListeners()
notifyStickerPackListeners()
}
fun deleteMessagesFrom(threadId: Long, fromUser: String) { // copied from deleteThreads implementation
val db = databaseHelper.writableDatabase
var cursor: Cursor? = null
val whereString = "$THREAD_ID = ? AND $ADDRESS = ?"
try {
cursor =
db!!.query(TABLE_NAME, arrayOf<String?>(ID), whereString, arrayOf(threadId.toString(), fromUser), null, null, null)
val toDeleteStringMessageIds = mutableListOf<String>()
while (cursor.moveToNext()) {
toDeleteStringMessageIds += cursor.getLong(0).toString() // get the ID as a string
}
// TODO: this can probably be optimized out,
// currently attachmentDB uses MmsID not threadID which makes it difficult to delete
// and clean up on threadID alone
toDeleteStringMessageIds.toList().chunked(50).forEach { sublist ->
deleteMessages(sublist.toTypedArray())
}
} finally {
cursor?.close()
}
val threadDb = get(context).threadDatabase()
threadDb.update(threadId, false)
notifyConversationListeners(threadId)
notifyStickerListeners()
notifyStickerPackListeners()
}
private fun getSerializedSharedContacts(
insertedAttachmentIds: Map<Attachment?, AttachmentId?>,
contacts: List<Contact?>
@ -1159,7 +1198,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
return false
}
/*package*/
private fun deleteThreads(threadIds: Set<Long>) {
val db = databaseHelper.writableDatabase
val where = StringBuilder()

View file

@ -638,11 +638,16 @@ public class SmsDatabase extends MessagingDatabase {
}
}
/*package */void deleteThread(long threadId) {
void deleteThread(long threadId) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.delete(TABLE_NAME, THREAD_ID + " = ?", new String[] {threadId+""});
}
void deleteMessagesFrom(long threadId, String fromUser) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.delete(TABLE_NAME, THREAD_ID+" = ? AND "+ADDRESS+" = ?", new String[]{threadId+"", fromUser});
}
/*package*/void deleteMessagesInThreadBeforeDate(long threadId, long date) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
String where = THREAD_ID + " = ? AND (CASE " + TYPE;

View file

@ -731,13 +731,24 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
return threadDb.getPinned(threadID)
}
override fun clearMessages(threadID: Long): Boolean {
override fun clearMessages(threadID: Long, fromUser: Address?): Boolean {
val smsDb = DatabaseComponent.get(context).smsDatabase()
val mmsDb = DatabaseComponent.get(context).mmsDatabase()
val threadDb = DatabaseComponent.get(context).threadDatabase()
smsDb.deleteThread(threadID)
mmsDb.deleteThread(threadID) // threadDB update called from within
threadDb.update(threadID, false)
if (fromUser == null) {
smsDb.deleteThread(threadID)
mmsDb.deleteThread(threadID) // threadDB update called from within
} else {
smsDb.deleteMessagesFrom(threadID, fromUser.serialize())
mmsDb.deleteMessagesFrom(threadID, fromUser.serialize())
threadDb.update(threadID, false)
}
return true
}
override fun clearMedia(threadID: Long, fromUser: Address?): Boolean {
val mmsDb = DatabaseComponent.get(context).mmsDatabase()
mmsDb.deleteMediaFor(threadID, fromUser?.serialize())
return true
}

View file

@ -155,7 +155,8 @@ interface StorageProtocol {
fun getMessageCount(threadID: Long): Long
fun setThreadPinned(threadID: Long, isPinned: Boolean)
fun isThreadPinned(threadID: Long): Boolean
fun clearMessages(threadID: Long): Boolean
fun clearMessages(threadID: Long, fromUser: Address? = null): Boolean
fun clearMedia(threadID: Long, fromUser: Address? = null): Boolean
// Contacts
fun getContactWithSessionID(sessionID: String): Contact?