mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-24 07:48:42 +00:00
Support for synchronizing read state to/from desktop
// FREEBIE
This commit is contained in:
@@ -165,4 +165,23 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SyncMessageId {
|
||||
|
||||
private final String address;
|
||||
private final long timetamp;
|
||||
|
||||
public SyncMessageId(String address, long timetamp) {
|
||||
this.address = address;
|
||||
this.timetamp = timetamp;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public long getTimetamp() {
|
||||
return timetamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,14 +190,14 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public void incrementDeliveryReceiptCount(String address, long timestamp) {
|
||||
public void incrementDeliveryReceiptCount(SyncMessageId messageId) {
|
||||
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
Cursor cursor = null;
|
||||
boolean found = false;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(timestamp)}, null, null, null, null);
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())}, null, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
if (Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)))) {
|
||||
@@ -205,7 +205,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
|
||||
for (String storedAddress : addresses) {
|
||||
try {
|
||||
String ourAddress = canonicalizeNumber(context, address);
|
||||
String ourAddress = canonicalizeNumber(context, messageId.getAddress());
|
||||
String theirAddress = canonicalizeNumberOrGroup(context, storedAddress);
|
||||
|
||||
if (ourAddress.equals(theirAddress) || GroupUtil.isEncodedGroup(theirAddress)) {
|
||||
@@ -230,7 +230,7 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
|
||||
if (!found) {
|
||||
try {
|
||||
earlyReceiptCache.increment(timestamp, canonicalizeNumber(context, address));
|
||||
earlyReceiptCache.increment(messageId.getTimetamp(), canonicalizeNumber(context, messageId.getAddress()));
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
@@ -432,12 +432,72 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
|
||||
public void setMessagesRead(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, 1);
|
||||
public List<SyncMessageId> setMessagesRead(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
String where = THREAD_ID + " = ? AND " + READ + " = 0";
|
||||
String[] selection = new String[]{String.valueOf(threadId)};
|
||||
List<SyncMessageId> result = new LinkedList<>();
|
||||
Cursor cursor = null;
|
||||
|
||||
database.update(TABLE_NAME, contentValues, THREAD_ID + " = ?", new String[] {threadId + ""});
|
||||
database.beginTransaction();
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ADDRESS, DATE_SENT, MESSAGE_BOX}, where, selection, null, null, null);
|
||||
|
||||
while(cursor != null && cursor.moveToNext()) {
|
||||
if (Types.isSecureType(cursor.getLong(2))) {
|
||||
result.add(new SyncMessageId(cursor.getString(0), cursor.getLong(1)));
|
||||
}
|
||||
}
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, 1);
|
||||
|
||||
database.update(TABLE_NAME, contentValues, where, selection);
|
||||
database.setTransactionSuccessful();
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setTimestampRead(SyncMessageId messageId) {
|
||||
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())}, null, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
List<String> addresses = addressDatabase.getAddressesListForId(cursor.getLong(cursor.getColumnIndexOrThrow(ID)));
|
||||
|
||||
for (String storedAddress : addresses) {
|
||||
try {
|
||||
String ourAddress = canonicalizeNumber(context, messageId.getAddress());
|
||||
String theirAddress = canonicalizeNumberOrGroup(context, storedAddress);
|
||||
|
||||
if (ourAddress.equals(theirAddress) || GroupUtil.isEncodedGroup(theirAddress)) {
|
||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
|
||||
|
||||
database.execSQL("UPDATE " + TABLE_NAME + " SET " + READ + " = 1 WHERE " + ID + " = ?",
|
||||
new String[] {String.valueOf(id)});
|
||||
|
||||
DatabaseFactory.getThreadDatabase(context).updateReadState(threadId);
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w("MmsDatabase", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAllMessagesRead() {
|
||||
|
||||
@@ -26,12 +26,15 @@ import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduHeaders;
|
||||
|
||||
public class MmsSmsDatabase extends Database {
|
||||
|
||||
private static final String TAG = MmsSmsDatabase.class.getSimpleName();
|
||||
@@ -107,6 +110,17 @@ public class MmsSmsDatabase extends Database {
|
||||
return queryTables(PROJECTION, selection, order, null);
|
||||
}
|
||||
|
||||
public int getUnreadCount(long threadId) {
|
||||
String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||
Cursor cursor = queryTables(PROJECTION, selection, null, null);
|
||||
|
||||
try {
|
||||
return cursor != null ? cursor.getCount() : 0;
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();;
|
||||
}
|
||||
}
|
||||
|
||||
public int getConversationCount(long threadId) {
|
||||
int count = DatabaseFactory.getSmsDatabase(context).getMessageCountForThread(threadId);
|
||||
count += DatabaseFactory.getMmsDatabase(context).getMessageCountForThread(threadId);
|
||||
@@ -114,9 +128,9 @@ public class MmsSmsDatabase extends Database {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void incrementDeliveryReceiptCount(String address, long timestamp) {
|
||||
DatabaseFactory.getSmsDatabase(context).incrementDeliveryReceiptCount(address, timestamp);
|
||||
DatabaseFactory.getMmsDatabase(context).incrementDeliveryReceiptCount(address, timestamp);
|
||||
public void incrementDeliveryReceiptCount(SyncMessageId syncMessageId) {
|
||||
DatabaseFactory.getSmsDatabase(context).incrementDeliveryReceiptCount(syncMessageId);
|
||||
DatabaseFactory.getMmsDatabase(context).incrementDeliveryReceiptCount(syncMessageId);
|
||||
}
|
||||
|
||||
private Cursor queryTables(String[] projection, String selection, String order, String limit) {
|
||||
|
||||
@@ -252,20 +252,20 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_SENT_FAILED_TYPE);
|
||||
}
|
||||
|
||||
public void incrementDeliveryReceiptCount(String address, long timestamp) {
|
||||
public void incrementDeliveryReceiptCount(SyncMessageId messageId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
Cursor cursor = null;
|
||||
boolean foundMessage = false;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE},
|
||||
DATE_SENT + " = ?", new String[] {String.valueOf(timestamp)},
|
||||
DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())},
|
||||
null, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
if (Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(TYPE)))) {
|
||||
try {
|
||||
String theirAddress = canonicalizeNumber(context, address);
|
||||
String theirAddress = canonicalizeNumber(context, messageId.getAddress());
|
||||
String ourAddress = canonicalizeNumber(context, cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)));
|
||||
|
||||
if (ourAddress.equals(theirAddress)) {
|
||||
@@ -288,7 +288,7 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
|
||||
if (!foundMessage) {
|
||||
try {
|
||||
earlyReceiptCache.increment(timestamp, canonicalizeNumber(context, address));
|
||||
earlyReceiptCache.increment(messageId.getTimetamp(), canonicalizeNumber(context, messageId.getAddress()));
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
@@ -300,14 +300,68 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessagesRead(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, 1);
|
||||
public List<SyncMessageId> setMessagesRead(long threadId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
String where = THREAD_ID + " = ? AND " + READ + " = 0";
|
||||
String[] selection = new String[]{String.valueOf(threadId)};
|
||||
List<SyncMessageId> results = new LinkedList<>();
|
||||
Cursor cursor = null;
|
||||
|
||||
database.update(TABLE_NAME, contentValues,
|
||||
THREAD_ID + " = ? AND " + READ + " = 0",
|
||||
new String[] {threadId+""});
|
||||
database.beginTransaction();
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ADDRESS, DATE_SENT, TYPE}, where, selection, null, null, null);
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
if (Types.isSecureType(cursor.getLong(2))) {
|
||||
results.add(new SyncMessageId(cursor.getString(0), cursor.getLong(1)));
|
||||
}
|
||||
}
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, 1);
|
||||
|
||||
database.update(TABLE_NAME, contentValues, where, selection);
|
||||
database.setTransactionSuccessful();
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public void setTimestampRead(SyncMessageId messageId) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE},
|
||||
DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())},
|
||||
null, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
String theirAddress = canonicalizeNumber(context, messageId.getAddress());
|
||||
String ourAddress = canonicalizeNumber(context, cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)));
|
||||
|
||||
if (ourAddress.equals(theirAddress)) {
|
||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, 1);
|
||||
|
||||
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + ""});
|
||||
|
||||
DatabaseFactory.getThreadDatabase(context).updateReadState(threadId);
|
||||
notifyConversationListeners(threadId);
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAllMessagesRead() {
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.model.DisplayRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
@@ -257,16 +258,22 @@ public class ThreadDatabase extends Database {
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
public void setRead(long threadId) {
|
||||
public List<SyncMessageId> setRead(long threadId) {
|
||||
ContentValues contentValues = new ContentValues(1);
|
||||
contentValues.put(READ, 1);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
|
||||
|
||||
DatabaseFactory.getSmsDatabase(context).setMessagesRead(threadId);
|
||||
DatabaseFactory.getMmsDatabase(context).setMessagesRead(threadId);
|
||||
final List<SyncMessageId> smsRecords = DatabaseFactory.getSmsDatabase(context).setMessagesRead(threadId);
|
||||
final List<SyncMessageId> mmsRecords = DatabaseFactory.getMmsDatabase(context).setMessagesRead(threadId);
|
||||
|
||||
notifyConversationListListeners();
|
||||
|
||||
return new LinkedList<SyncMessageId>() {{
|
||||
addAll(smsRecords);
|
||||
addAll(mmsRecords);
|
||||
}};
|
||||
}
|
||||
|
||||
public void setUnread(long threadId) {
|
||||
@@ -465,6 +472,18 @@ public class ThreadDatabase extends Database {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateReadState(long threadId) {
|
||||
int unreadCount = DatabaseFactory.getMmsSmsDatabase(context).getUnreadCount(threadId);
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(READ, unreadCount == 0);
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,ID_WHERE,
|
||||
new String[] {String.valueOf(threadId)});
|
||||
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
public boolean update(long threadId, boolean unarchive) {
|
||||
MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context);
|
||||
long count = mmsSmsDatabase.getConversationCount(threadId);
|
||||
|
||||
Reference in New Issue
Block a user