Fixed a few issues with the GroupAvatarDownloadJob

Added a method to remove the Group avatar
Fixed an issue where the recipient diffing on the HomeActivity wasn't working properly
Fixed an issue where the GroupAvatarDownloadJob could be scheduled even when there was already one scheduled
This commit is contained in:
Morgan Pretty 2023-02-10 10:05:28 +11:00
parent cd3b8f3571
commit 9fd68d27f8
9 changed files with 47 additions and 5 deletions

View File

@ -318,6 +318,25 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
notifyConversationListListeners(); notifyConversationListListeners();
} }
@Override
public void removeProfilePicture(String groupID) {
databaseHelper.getWritableDatabase()
.execSQL("UPDATE " + TABLE_NAME +
" SET " + AVATAR + " = NULL, " +
AVATAR_ID + " = NULL, " +
AVATAR_KEY + " = NULL, " +
AVATAR_CONTENT_TYPE + " = NULL, " +
AVATAR_RELAY + " = NULL, " +
AVATAR_DIGEST + " = NULL, " +
AVATAR_URL + " = NULL" +
" WHERE " +
GROUP_ID + " = ?",
new String[] {groupID});
Recipient.applyCached(Address.fromSerialized(groupID), recipient -> recipient.setGroupAvatarId(null));
notifyConversationListListeners();
}
public boolean hasDownloadedProfilePicture(String groupId) { public boolean hasDownloadedProfilePicture(String groupId) {
try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[]{AVATAR}, GROUP_ID + " = ?", try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[]{AVATAR}, GROUP_ID + " = ?",
new String[] {groupId}, new String[] {groupId},

View File

@ -324,6 +324,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
DatabaseComponent.get(context).groupDatabase().updateProfilePicture(groupID, newValue) DatabaseComponent.get(context).groupDatabase().updateProfilePicture(groupID, newValue)
} }
override fun removeProfilePicture(groupID: String) {
DatabaseComponent.get(context).groupDatabase().removeProfilePicture(groupID)
}
override fun hasDownloadedProfilePicture(groupID: String): Boolean { override fun hasDownloadedProfilePicture(groupID: String): Boolean {
return DatabaseComponent.get(context).groupDatabase().hasDownloadedProfilePicture(groupID) return DatabaseComponent.get(context).groupDatabase().hasDownloadedProfilePicture(groupID)
} }

View File

@ -51,6 +51,7 @@ public class ThreadRecord extends DisplayRecord {
private final long expiresIn; private final long expiresIn;
private final long lastSeen; private final long lastSeen;
private final boolean pinned; private final boolean pinned;
private final int initialRecipientHash;
public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri, public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri,
@NonNull Recipient recipient, long date, long count, int unreadCount, @NonNull Recipient recipient, long date, long count, int unreadCount,
@ -68,6 +69,7 @@ public class ThreadRecord extends DisplayRecord {
this.expiresIn = expiresIn; this.expiresIn = expiresIn;
this.lastSeen = lastSeen; this.lastSeen = lastSeen;
this.pinned = pinned; this.pinned = pinned;
this.initialRecipientHash = recipient.hashCode();
} }
public @Nullable Uri getSnippetUri() { public @Nullable Uri getSnippetUri() {
@ -176,4 +178,8 @@ public class ThreadRecord extends DisplayRecord {
public boolean isPinned() { public boolean isPinned() {
return pinned; return pinned;
} }
public int getInitialRecipientHash() {
return initialRecipientHash;
}
} }

View File

@ -28,8 +28,11 @@ class HomeDiffUtil(
if (isSameItem) { isSameItem = (oldItem.unreadCount == newItem.unreadCount) } if (isSameItem) { isSameItem = (oldItem.unreadCount == newItem.unreadCount) }
if (isSameItem) { isSameItem = (oldItem.isPinned == newItem.isPinned) } if (isSameItem) { isSameItem = (oldItem.isPinned == newItem.isPinned) }
// Note: For some reason the 'hashCode' value can change after initialisation so we can't cache it // The recipient is passed as a reference and changes to recipients update the reference so we
if (isSameItem) { isSameItem = (oldItem.recipient.hashCode() == newItem.recipient.hashCode()) } // need to cache the hashCode for the recipient and use that for diffing - unfortunately
// recipient data is also loaded asyncronously which means every thread will refresh at least
// once when the initial recipient data is loaded
if (isSameItem) { isSameItem = (oldItem.initialRecipientHash == newItem.initialRecipientHash) }
// Note: Two instances of 'SpannableString' may not equate even though their content matches // Note: Two instances of 'SpannableString' may not equate even though their content matches
if (isSameItem) { isSameItem = (oldItem.getDisplayBody(context).toString() == newItem.getDisplayBody(context).toString()) } if (isSameItem) { isSameItem = (oldItem.getDisplayBody(context).toString() == newItem.getDisplayBody(context).toString()) }

View File

@ -80,6 +80,7 @@ interface StorageProtocol {
// Open Group Metadata // Open Group Metadata
fun updateTitle(groupID: String, newValue: String) fun updateTitle(groupID: String, newValue: String)
fun updateProfilePicture(groupID: String, newValue: ByteArray) fun updateProfilePicture(groupID: String, newValue: ByteArray)
fun removeProfilePicture(groupID: String)
fun hasDownloadedProfilePicture(groupID: String): Boolean fun hasDownloadedProfilePicture(groupID: String): Boolean
fun setUserCount(room: String, server: String, newValue: Int) fun setUserCount(room: String, server: String, newValue: Int)

View File

@ -68,8 +68,8 @@ class GroupAvatarDownloadJob(val server: String, val room: String, val imageId:
override fun create(data: Data): GroupAvatarDownloadJob { override fun create(data: Data): GroupAvatarDownloadJob {
return GroupAvatarDownloadJob( return GroupAvatarDownloadJob(
data.getString(ROOM),
data.getString(SERVER), data.getString(SERVER),
data.getString(ROOM),
if (data.hasString(IMAGE_ID)) { data.getString(IMAGE_ID) } else { null } if (data.hasString(IMAGE_ID)) { data.getString(IMAGE_ID) } else { null }
) )
} }

View File

@ -36,7 +36,7 @@ data class OpenGroup(
val server = json.get("server").asText().lowercase(Locale.US) val server = json.get("server").asText().lowercase(Locale.US)
val displayName = json.get("displayName").asText() val displayName = json.get("displayName").asText()
val publicKey = json.get("publicKey").asText() val publicKey = json.get("publicKey").asText()
val imageId = json.get("imageId")?.asText() val imageId = if (json.hasNonNull("imageId")) { json.get("imageId")?.asText() } else { null }
val canWrite = json.get("canWrite")?.asText()?.toBoolean() ?: true val canWrite = json.get("canWrite")?.asText()?.toBoolean() ?: true
val infoUpdates = json.get("infoUpdates")?.asText()?.toIntOrNull() ?: 0 val infoUpdates = json.get("infoUpdates")?.asText()?.toIntOrNull() ?: 0
OpenGroup(server = server, room = room, name = displayName, publicKey = publicKey, imageId = imageId, canWrite = canWrite, infoUpdates = infoUpdates) OpenGroup(server = server, room = room, name = displayName, publicKey = publicKey, imageId = imageId, canWrite = canWrite, infoUpdates = infoUpdates)

View File

@ -159,6 +159,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S
}) })
} }
// Update the group avatar
if ( if (
( (
pollInfo.details != null && pollInfo.details != null &&
@ -174,7 +175,14 @@ class OpenGroupPoller(private val server: String, private val executorService: S
storage.getGroupAvatarDownloadJob(openGroup.server, openGroup.room, existingOpenGroup.imageId) == null storage.getGroupAvatarDownloadJob(openGroup.server, openGroup.room, existingOpenGroup.imageId) == null
) )
) { ) {
JobQueue.shared.add(GroupAvatarDownloadJob(roomToken, server, existingOpenGroup.imageId)) JobQueue.shared.add(GroupAvatarDownloadJob(server, roomToken, existingOpenGroup.imageId))
}
else if (
pollInfo.details != null &&
pollInfo.details.imageId == null &&
existingOpenGroup.imageId != null
) {
storage.removeProfilePicture(dbGroupId)
} }
} }

View File

@ -4,4 +4,5 @@ interface LokiOpenGroupDatabaseProtocol {
fun updateTitle(groupID: String, newValue: String) fun updateTitle(groupID: String, newValue: String)
fun updateProfilePicture(groupID: String, newValue: ByteArray) fun updateProfilePicture(groupID: String, newValue: ByteArray)
fun removeProfilePicture(groupID: String)
} }