mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 19:07:40 +00:00
feat: Update open group avatars periodically (#807)
* feat: Update open group avatars periodically * Updated timestamp * Existing job check * Refresh avatar on the conversation * Remove println statement * Update profile picture on recipient modified event
This commit is contained in:
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||
import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob
|
||||
import org.session.libsession.messaging.jobs.Job
|
||||
import org.session.libsession.messaging.jobs.MessageSendJob
|
||||
import org.session.libsession.messaging.messages.control.ConfigurationMessage
|
||||
@@ -43,6 +44,7 @@ interface StorageProtocol {
|
||||
fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob?
|
||||
fun getMessageSendJob(messageSendJobID: String): MessageSendJob?
|
||||
fun getMessageReceiveJob(messageReceiveJobID: String): Job?
|
||||
fun getGroupAvatarDownloadJob(server: String, room: String): Job?
|
||||
fun resumeMessageSendJobIfNeeded(messageSendJobID: String)
|
||||
fun isJobCanceled(job: Job): Boolean
|
||||
|
||||
@@ -117,6 +119,7 @@ interface StorageProtocol {
|
||||
fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair>
|
||||
fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair?
|
||||
fun updateFormationTimestamp(groupID: String, formationTimestamp: Long)
|
||||
fun updateTimestampUpdated(groupID: String, updatedTimestamp: Long)
|
||||
fun setExpirationTimer(groupID: String, duration: Int)
|
||||
|
||||
// Groups
|
||||
|
@@ -0,0 +1,54 @@
|
||||
package org.session.libsession.messaging.jobs
|
||||
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||
import org.session.libsession.messaging.utilities.Data
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
|
||||
class GroupAvatarDownloadJob(val room: String, val server: String) : Job {
|
||||
|
||||
override var delegate: JobDelegate? = null
|
||||
override var id: String? = null
|
||||
override var failureCount: Int = 0
|
||||
override val maxFailureCount: Int = 10
|
||||
|
||||
override fun execute() {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
try {
|
||||
val info = OpenGroupAPIV2.getInfo(room, server).get()
|
||||
val bytes = OpenGroupAPIV2.downloadOpenGroupProfilePicture(info.id, server).get()
|
||||
val groupId = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray())
|
||||
storage.updateProfilePicture(groupId, bytes)
|
||||
storage.updateTimestampUpdated(groupId, System.currentTimeMillis())
|
||||
delegate?.handleJobSucceeded(this)
|
||||
} catch (e: Exception) {
|
||||
delegate?.handleJobFailed(this, e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(): Data {
|
||||
return Data.Builder()
|
||||
.putString(ROOM, room)
|
||||
.putString(SERVER, server)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun getFactoryKey(): String = KEY
|
||||
|
||||
companion object {
|
||||
const val KEY = "GroupAvatarDownloadJob"
|
||||
|
||||
private const val ROOM = "room"
|
||||
private const val SERVER = "server"
|
||||
}
|
||||
|
||||
class Factory : Job.Factory<GroupAvatarDownloadJob> {
|
||||
|
||||
override fun create(data: Data): GroupAvatarDownloadJob {
|
||||
return GroupAvatarDownloadJob(
|
||||
data.getString(ROOM),
|
||||
data.getString(SERVER)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -45,9 +45,16 @@ class JobQueue : JobDelegate {
|
||||
while (isActive) {
|
||||
for (job in queue) {
|
||||
when (job) {
|
||||
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> txQueue.send(job)
|
||||
is MessageReceiveJob, is TrimThreadJob, is BatchMessageReceiveJob, is AttachmentDownloadJob-> rxQueue.send(job)
|
||||
else -> throw IllegalStateException("Unexpected job type.")
|
||||
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> {
|
||||
txQueue.send(job)
|
||||
}
|
||||
is MessageReceiveJob, is TrimThreadJob, is BatchMessageReceiveJob,
|
||||
is AttachmentDownloadJob, is GroupAvatarDownloadJob -> {
|
||||
rxQueue.send(job)
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Unexpected job type.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +130,8 @@ class JobQueue : JobDelegate {
|
||||
MessageReceiveJob.KEY,
|
||||
MessageSendJob.KEY,
|
||||
NotifyPNServerJob.KEY,
|
||||
BatchMessageReceiveJob.KEY
|
||||
BatchMessageReceiveJob.KEY,
|
||||
GroupAvatarDownloadJob.KEY
|
||||
)
|
||||
allJobTypes.forEach { type ->
|
||||
resumePendingJobs(type)
|
||||
|
@@ -12,7 +12,8 @@ class SessionJobManagerFactories {
|
||||
MessageSendJob.KEY to MessageSendJob.Factory(),
|
||||
NotifyPNServerJob.KEY to NotifyPNServerJob.Factory(),
|
||||
TrimThreadJob.KEY to TrimThreadJob.Factory(),
|
||||
BatchMessageReceiveJob.KEY to BatchMessageReceiveJob.Factory()
|
||||
BatchMessageReceiveJob.KEY to BatchMessageReceiveJob.Factory(),
|
||||
GroupAvatarDownloadJob.KEY to GroupAvatarDownloadJob.Factory()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
||||
fun poll(isBackgroundPoll: Boolean = false): Promise<Unit, Exception> {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val rooms = storage.getAllV2OpenGroups().values.filter { it.server == server }.map { it.room }
|
||||
rooms.forEach { downloadGroupAvatarIfNeeded(it) }
|
||||
return OpenGroupAPIV2.compactPoll(rooms, server).successBackground { responses ->
|
||||
responses.forEach { (room, response) ->
|
||||
val openGroupID = "$server.$room"
|
||||
@@ -50,7 +51,7 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
||||
}
|
||||
}
|
||||
}.always {
|
||||
executorService?.schedule(this@OpenGroupPollerV2::poll, OpenGroupPollerV2.pollInterval, TimeUnit.MILLISECONDS)
|
||||
executorService?.schedule(this@OpenGroupPollerV2::poll, pollInterval, TimeUnit.MILLISECONDS)
|
||||
}.map { }
|
||||
}
|
||||
|
||||
@@ -103,4 +104,15 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
||||
storage.setLastDeletionServerID(room, server, latestMax)
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadGroupAvatarIfNeeded(room: String) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
if (storage.getGroupAvatarDownloadJob(server, room) != null) return
|
||||
val groupId = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray())
|
||||
storage.getGroup(groupId)?.let {
|
||||
if (System.currentTimeMillis() > it.updatedTimestamp + TimeUnit.DAYS.toMillis(7)) {
|
||||
JobQueue.shared.add(GroupAvatarDownloadJob(room, server))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,15 +1,14 @@
|
||||
package org.session.libsession.utilities
|
||||
|
||||
import android.text.TextUtils
|
||||
import org.session.libsession.utilities.Address
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.LinkedList
|
||||
|
||||
class GroupRecord(
|
||||
val encodedId: String, val title: String, members: String?, val avatar: ByteArray?,
|
||||
val avatarId: Long?, val avatarKey: ByteArray?, val avatarContentType: String?,
|
||||
val relay: String?, val isActive: Boolean, val avatarDigest: ByteArray?, val isMms: Boolean,
|
||||
val url: String?, admins: String?, val formationTimestamp: Long
|
||||
val url: String?, admins: String?, val formationTimestamp: Long, val updatedTimestamp: Long
|
||||
) {
|
||||
var members: List<Address> = LinkedList<Address>()
|
||||
var admins: List<Address> = LinkedList<Address>()
|
||||
|
Reference in New Issue
Block a user