mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 05:43:39 +00:00
Update attachment download handling
This commit is contained in:
parent
1a82238a44
commit
c10e96dd91
@ -73,7 +73,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
}
|
||||
|
||||
override fun setUserProfilePictureURL(newValue: String) {
|
||||
val ourRecipient = Address.fromSerialized(getUserPublicKey()!!).let {
|
||||
val ourRecipient = fromSerialized(getUserPublicKey()!!).let {
|
||||
Recipient.from(context, it, false)
|
||||
}
|
||||
TextSecurePreferences.setProfilePictureURL(context, newValue)
|
||||
@ -103,7 +103,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>): Long? {
|
||||
var messageID: Long? = null
|
||||
val senderAddress = Address.fromSerialized(message.sender!!)
|
||||
val senderAddress = fromSerialized(message.sender!!)
|
||||
val isUserSender = (message.sender!! == getUserPublicKey())
|
||||
val group: Optional<SignalServiceGroup> = when {
|
||||
openGroupID != null -> Optional.of(SignalServiceGroup(openGroupID.toByteArray(), SignalServiceGroup.GroupType.PUBLIC_CHAT))
|
||||
@ -117,9 +117,9 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
it.toSignalAttachment()
|
||||
}
|
||||
val targetAddress = if (isUserSender && !message.syncTarget.isNullOrEmpty()) {
|
||||
Address.fromSerialized(message.syncTarget!!)
|
||||
fromSerialized(message.syncTarget!!)
|
||||
} else if (group.isPresent) {
|
||||
Address.fromSerialized(GroupUtil.getEncodedId(group.get()))
|
||||
fromSerialized(GroupUtil.getEncodedId(group.get()))
|
||||
} else {
|
||||
senderAddress
|
||||
}
|
||||
@ -291,6 +291,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
return getAllOpenGroups().values.firstOrNull { it.server == server && it.room == room }
|
||||
}
|
||||
|
||||
override fun updateOpenGroupCapabilities(server: String, capabilities: List<String>) {
|
||||
getAllOpenGroups().values.filter { it.server == server }
|
||||
.map { it.copy(capabilities = it.capabilities) }
|
||||
.forEach(this::updateOpenGroup)
|
||||
}
|
||||
|
||||
override fun getOpenGroupServer(server: String): List<String> {
|
||||
return getAllOpenGroups().values.firstOrNull { it.server == server }?.capabilities ?: emptyList()
|
||||
}
|
||||
|
||||
override fun isDuplicateMessage(timestamp: Long): Boolean {
|
||||
return getReceivedMessageTimestamps().contains(timestamp)
|
||||
}
|
||||
@ -317,7 +327,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? {
|
||||
val database = DatabaseComponent.get(context).mmsSmsDatabase()
|
||||
val address = Address.fromSerialized(author)
|
||||
val address = fromSerialized(author)
|
||||
return database.getMessageFor(timestamp, address)?.getId()
|
||||
}
|
||||
|
||||
@ -435,7 +445,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, sentTimestamp: Long) {
|
||||
val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList())
|
||||
val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true)
|
||||
val m = IncomingTextMessage(fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true)
|
||||
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON()
|
||||
val infoMessage = IncomingGroupMessage(m, groupID, updateData, true)
|
||||
val smsDB = DatabaseComponent.get(context).smsDatabase()
|
||||
@ -444,7 +454,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) {
|
||||
val userPublicKey = getUserPublicKey()
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(groupID), false)
|
||||
val recipient = Recipient.from(context, fromSerialized(groupID), false)
|
||||
|
||||
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: ""
|
||||
val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, true, null, listOf(), listOf())
|
||||
@ -457,7 +467,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun isClosedGroup(publicKey: String): Boolean {
|
||||
val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(publicKey)
|
||||
val address = Address.fromSerialized(publicKey)
|
||||
val address = fromSerialized(publicKey)
|
||||
return address.isClosedGroup || isClosedGroup
|
||||
}
|
||||
|
||||
@ -514,6 +524,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
return DatabaseComponent.get(context).lokiThreadDatabase().getAllOpenGroups()
|
||||
}
|
||||
|
||||
override fun updateOpenGroup(openGroup: OpenGroup) {
|
||||
OpenGroupManager.updateOpenGroup(openGroup, context)
|
||||
}
|
||||
|
||||
override fun getAllGroups(): List<GroupRecord> {
|
||||
return DatabaseComponent.get(context).groupDatabase().allGroups
|
||||
}
|
||||
@ -534,20 +548,20 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
|
||||
override fun getOrCreateThreadIdFor(publicKey: String, groupPublicKey: String?, openGroupID: String?): Long {
|
||||
val database = DatabaseComponent.get(context).threadDatabase()
|
||||
if (!openGroupID.isNullOrEmpty()) {
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())), false)
|
||||
return database.getThreadIdIfExistsFor(recipient)
|
||||
return if (!openGroupID.isNullOrEmpty()) {
|
||||
val recipient = Recipient.from(context, fromSerialized(GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())), false)
|
||||
database.getThreadIdIfExistsFor(recipient)
|
||||
} else if (!groupPublicKey.isNullOrEmpty()) {
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(groupPublicKey)), false)
|
||||
return database.getOrCreateThreadIdFor(recipient)
|
||||
val recipient = Recipient.from(context, fromSerialized(GroupUtil.doubleEncodeGroupID(groupPublicKey)), false)
|
||||
database.getOrCreateThreadIdFor(recipient)
|
||||
} else {
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false)
|
||||
return database.getOrCreateThreadIdFor(recipient)
|
||||
val recipient = Recipient.from(context, fromSerialized(publicKey), false)
|
||||
database.getOrCreateThreadIdFor(recipient)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getThreadId(publicKeyOrOpenGroupID: String): Long? {
|
||||
val address = Address.fromSerialized(publicKeyOrOpenGroupID)
|
||||
val address = fromSerialized(publicKeyOrOpenGroupID)
|
||||
return getThreadId(address)
|
||||
}
|
||||
|
||||
@ -595,7 +609,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
val recipientDatabase = DatabaseComponent.get(context).recipientDatabase()
|
||||
val threadDatabase = DatabaseComponent.get(context).threadDatabase()
|
||||
for (contact in contacts) {
|
||||
val address = Address.fromSerialized(contact.publicKey)
|
||||
val address = fromSerialized(contact.publicKey)
|
||||
val recipient = Recipient.from(context, address, true)
|
||||
if (!contact.profilePicture.isNullOrEmpty()) {
|
||||
recipientDatabase.setProfileAvatar(recipient, contact.profilePicture)
|
||||
@ -725,11 +739,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
}
|
||||
|
||||
override fun setLastInboxMessageId(server: String, messageId: Long) {
|
||||
// TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
|
||||
override fun removeLastInboxMessageId(server: String) {
|
||||
// TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
|
||||
override fun getLastOutboxMessageId(server: String): Long? {
|
||||
@ -737,11 +751,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
}
|
||||
|
||||
override fun setLastOutboxMessageId(server: String, messageId: Long) {
|
||||
// TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
|
||||
override fun removeLastOutboxMessageId(server: String) {
|
||||
// TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -124,4 +124,11 @@ object OpenGroupManager {
|
||||
val publicKey = url.queryParameter("public_key") ?: return
|
||||
add(server.toString().removeSuffix("/"), room, publicKey, context)
|
||||
}
|
||||
|
||||
fun updateOpenGroup(openGroup: OpenGroup, context: Context) {
|
||||
val threadDB = DatabaseComponent.get(context).lokiThreadDatabase()
|
||||
val openGroupID = "${openGroup.server}.${openGroup.room}"
|
||||
val threadID = GroupManager.getOpenGroupThreadID(openGroupID, context)
|
||||
threadDB.setOpenGroupChat(openGroup, threadID)
|
||||
}
|
||||
}
|
@ -55,10 +55,13 @@ interface StorageProtocol {
|
||||
|
||||
// Open Groups
|
||||
fun getAllOpenGroups(): Map<Long, OpenGroup>
|
||||
fun updateOpenGroup(openGroup: OpenGroup)
|
||||
fun getOpenGroup(threadId: Long): OpenGroup?
|
||||
fun addOpenGroup(urlAsString: String)
|
||||
fun setOpenGroupServerMessageID(messageID: Long, serverID: Long, threadID: Long, isSms: Boolean)
|
||||
fun getOpenGroup(room: String, server: String): OpenGroup?
|
||||
fun updateOpenGroupCapabilities(server: String, capabilities: List<String>)
|
||||
fun getOpenGroupServer(server: String): List<String>
|
||||
|
||||
// Open Group Public Keys
|
||||
fun getOpenGroupPublicKey(server: String): String?
|
||||
|
@ -87,14 +87,22 @@ object FileServerApi {
|
||||
fun upload(file: ByteArray): Promise<Long, Exception> {
|
||||
val base64EncodedFile = Base64.encodeBytes(file)
|
||||
val parameters = mapOf( "file" to base64EncodedFile )
|
||||
val request = Request(verb = HTTP.Verb.POST, endpoint = "files", parameters = parameters)
|
||||
val request = Request(
|
||||
verb = HTTP.Verb.POST,
|
||||
endpoint = "file",
|
||||
parameters = parameters,
|
||||
headers = mapOf(
|
||||
"Content-Disposition" to "attachment",
|
||||
"Content-Type" to "application/octet-stream"
|
||||
)
|
||||
)
|
||||
return send(request).map { json ->
|
||||
json["result"] as? Long ?: throw OpenGroupApi.Error.ParsingFailed
|
||||
}
|
||||
}
|
||||
|
||||
fun download(file: Long): Promise<ByteArray, Exception> {
|
||||
val request = Request(verb = HTTP.Verb.GET, endpoint = "files/$file")
|
||||
val request = Request(verb = HTTP.Verb.GET, endpoint = "file/$file")
|
||||
return send(request).map { json ->
|
||||
val base64EncodedFile = json["result"] as? String ?: throw Error.ParsingFailed
|
||||
Base64.decode(base64EncodedFile) ?: throw Error.ParsingFailed
|
||||
|
@ -100,7 +100,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess
|
||||
val id = upload(data).get()
|
||||
val digest = drb.transmittedDigest
|
||||
// Return
|
||||
return Pair(key, UploadResult(id, "${server}/files/$id", digest))
|
||||
return Pair(key, UploadResult(id, "${server}/file/$id", digest))
|
||||
}
|
||||
|
||||
private fun handleSuccess(attachment: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: UploadResult) {
|
||||
|
@ -16,8 +16,7 @@ sealed class Endpoint(val value: String) {
|
||||
|
||||
// Messages
|
||||
|
||||
data class RoomMessage(val roomToken: String) :
|
||||
Endpoint("room/$roomToken/message")
|
||||
data class RoomMessage(val roomToken: String) : Endpoint("room/$roomToken/message")
|
||||
|
||||
data class RoomMessageIndividual(val roomToken: String, val messageId: Long) :
|
||||
Endpoint("room/$roomToken/message/$messageId")
|
||||
@ -42,8 +41,7 @@ sealed class Endpoint(val value: String) {
|
||||
data class RoomUnpinMessage(val roomToken: String, val messageId: Long) :
|
||||
Endpoint("room/$roomToken/unpin/$messageId")
|
||||
|
||||
data class RoomUnpinAll(val roomToken: String) :
|
||||
Endpoint("room/$roomToken/unpin/all")
|
||||
data class RoomUnpinAll(val roomToken: String) : Endpoint("room/$roomToken/unpin/all")
|
||||
|
||||
// Files
|
||||
|
||||
|
@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory
|
||||
import com.goterl.lazysodium.LazySodiumAndroid
|
||||
import com.goterl.lazysodium.SodiumAndroid
|
||||
import com.goterl.lazysodium.interfaces.GenericHash
|
||||
import com.goterl.lazysodium.interfaces.Sign
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import nl.komponents.kovenant.Promise
|
||||
@ -166,8 +167,8 @@ object OpenGroupApi {
|
||||
val whisper: Boolean = false,
|
||||
val whisper_mods: String = "",
|
||||
val whisper_to: String = "",
|
||||
val data: String = "",
|
||||
val signature: String = ""
|
||||
val data: String? = null,
|
||||
val signature: String? = null
|
||||
)
|
||||
|
||||
data class MessageDeletion(
|
||||
@ -194,8 +195,7 @@ object OpenGroupApi {
|
||||
* Always `true` under normal circumstances. You might want to disable
|
||||
* this when running over Lokinet.
|
||||
*/
|
||||
val useOnionRouting: Boolean = true,
|
||||
val isBlinded: Boolean = true
|
||||
val useOnionRouting: Boolean = true
|
||||
)
|
||||
|
||||
private fun createBody(parameters: Any?): RequestBody? {
|
||||
@ -223,6 +223,7 @@ object OpenGroupApi {
|
||||
}
|
||||
}
|
||||
fun execute(): Promise<OnionResponse, Exception> {
|
||||
val serverCapabilities = MessagingModuleConfiguration.shared.storage.getOpenGroupServer(request.server)
|
||||
val publicKey =
|
||||
MessagingModuleConfiguration.shared.storage.getOpenGroupPublicKey(request.server)
|
||||
?: return Promise.ofFail(Error.NoPublicKey)
|
||||
@ -233,32 +234,33 @@ object OpenGroupApi {
|
||||
val nonce = sodium.nonce(16)
|
||||
val timestamp = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
|
||||
var pubKey = ""
|
||||
var signature = ByteArray(0)
|
||||
if (request.isBlinded) {
|
||||
var signature = ByteArray(Sign.BYTES)
|
||||
var bodyHash = ByteArray(0)
|
||||
if (request.parameters != null) {
|
||||
val parameterBytes = JsonUtil.toJson(request.parameters).toByteArray()
|
||||
val parameterHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
parameterHash,
|
||||
parameterHash.size,
|
||||
parameterBytes,
|
||||
parameterBytes.size.toLong()
|
||||
)) {
|
||||
bodyHash = parameterHash
|
||||
}
|
||||
}
|
||||
val messageBytes = Hex.fromStringCondensed(publicKey)
|
||||
.plus(nonce)
|
||||
.plus("$timestamp".toByteArray(Charsets.US_ASCII))
|
||||
.plus(request.verb.rawValue.toByteArray())
|
||||
.plus(urlRequest.encodedPath().toByteArray())
|
||||
.plus(bodyHash)
|
||||
if (serverCapabilities.contains("blind")) {
|
||||
SodiumUtilities.blindedKeyPair(publicKey, ed25519KeyPair)?.let { keyPair ->
|
||||
pubKey = SodiumUtilities.SessionId(
|
||||
SodiumUtilities.IdPrefix.BLINDED,
|
||||
keyPair.publicKey.asBytes
|
||||
).hexString
|
||||
var bodyHash = ByteArray(0)
|
||||
if (request.parameters != null) {
|
||||
val parameterBytes = JsonUtil.toJson(request.parameters).toByteArray()
|
||||
val parameterHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
parameterHash,
|
||||
parameterHash.size,
|
||||
parameterBytes,
|
||||
parameterBytes.size.toLong()
|
||||
)) {
|
||||
bodyHash = parameterHash
|
||||
}
|
||||
}
|
||||
val messageBytes = Hex.fromStringCondensed(publicKey)
|
||||
.plus(nonce)
|
||||
.plus("$timestamp".toByteArray(Charsets.US_ASCII))
|
||||
.plus(request.verb.rawValue.toByteArray())
|
||||
.plus(urlRequest.encodedPath().toByteArray())
|
||||
.plus(bodyHash)
|
||||
|
||||
signature = SodiumUtilities.sogsSignature(
|
||||
messageBytes,
|
||||
ed25519KeyPair.secretKey.asBytes,
|
||||
@ -271,7 +273,7 @@ object OpenGroupApi {
|
||||
SodiumUtilities.IdPrefix.UN_BLINDED,
|
||||
ed25519KeyPair.publicKey.asBytes
|
||||
).hexString
|
||||
signature = ByteArray(0)
|
||||
sodium.cryptoSignDetached(signature, messageBytes, messageBytes.size.toLong(), ed25519KeyPair.secretKey.asBytes)
|
||||
}
|
||||
headers["X-SOGS-Nonce"] = encodeBytes(nonce)
|
||||
headers["X-SOGS-Timestamp"] = "$timestamp"
|
||||
@ -330,7 +332,12 @@ object OpenGroupApi {
|
||||
}
|
||||
|
||||
fun download(fileId: Long, room: String, server: String): Promise<ByteArray, Exception> {
|
||||
val request = Request(verb = GET, room = room, server = server, endpoint = Endpoint.FileIndividual(fileId))
|
||||
val request = Request(
|
||||
verb = GET,
|
||||
room = room,
|
||||
server = server,
|
||||
endpoint = Endpoint.RoomFileIndividual(room, fileId)
|
||||
)
|
||||
return send(request).map { it.body ?: throw Error.ParsingFailed }
|
||||
}
|
||||
// endregion
|
||||
@ -415,7 +422,7 @@ object OpenGroupApi {
|
||||
@JvmStatic
|
||||
fun deleteMessage(serverID: Long, room: String, server: String): Promise<Unit, Exception> {
|
||||
val request =
|
||||
Request(verb = DELETE, room = room, server = server, endpoint = "messages/$serverID")
|
||||
Request(verb = DELETE, room = room, server = server, endpoint = Endpoint.RoomMessageIndividual(room, serverID))
|
||||
return send(request).map {
|
||||
Log.d("Loki", "Message deletion successful.")
|
||||
}
|
||||
@ -568,49 +575,51 @@ object OpenGroupApi {
|
||||
}
|
||||
)
|
||||
}
|
||||
requests.add(
|
||||
if (lastInboxMessageId == null) {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/inbox"
|
||||
),
|
||||
endpoint = Endpoint.Inbox,
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
} else {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/inbox/since/$lastInboxMessageId"
|
||||
),
|
||||
endpoint = Endpoint.InboxSince(lastInboxMessageId),
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
}
|
||||
)
|
||||
requests.add(
|
||||
if (lastOutboxMessageId == null) {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/outbox"
|
||||
),
|
||||
endpoint = Endpoint.Outbox,
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
} else {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/outbox/since/$lastOutboxMessageId"
|
||||
),
|
||||
endpoint = Endpoint.OutboxSince(lastOutboxMessageId),
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
val serverCapabilities = storage.getOpenGroupServer(server)
|
||||
if (serverCapabilities.contains("blind")) {
|
||||
requests.add(
|
||||
if (lastInboxMessageId == null) {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/inbox"
|
||||
),
|
||||
endpoint = Endpoint.Inbox,
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
} else {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/inbox/since/$lastInboxMessageId"
|
||||
),
|
||||
endpoint = Endpoint.InboxSince(lastInboxMessageId),
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
}
|
||||
)
|
||||
requests.add(
|
||||
if (lastOutboxMessageId == null) {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/outbox"
|
||||
),
|
||||
endpoint = Endpoint.Outbox,
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
} else {
|
||||
BatchRequestInfo(
|
||||
request = BatchRequest(
|
||||
method = "GET",
|
||||
path = "/outbox/since/$lastOutboxMessageId"
|
||||
),
|
||||
endpoint = Endpoint.OutboxSince(lastOutboxMessageId),
|
||||
responseType = object : TypeReference<List<DirectMessage>>() {}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
return parallelBatch(server, requests)
|
||||
}
|
||||
|
||||
@ -666,7 +675,7 @@ object OpenGroupApi {
|
||||
fun getDefaultRoomsIfNeeded(): Promise<List<DefaultGroup>, Exception> {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
storage.setOpenGroupPublicKey(defaultServer, defaultServerPublicKey)
|
||||
return getAllRooms(defaultServer).map { groups ->
|
||||
return getAllRooms().map { groups ->
|
||||
val earlyGroups = groups.map { group ->
|
||||
DefaultGroup(group.token, group.name, null)
|
||||
}
|
||||
@ -705,11 +714,11 @@ object OpenGroupApi {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllRooms(server: String): Promise<List<RoomInfo>, Exception> {
|
||||
private fun getAllRooms(): Promise<List<RoomInfo>, Exception> {
|
||||
val request = Request(
|
||||
verb = GET,
|
||||
room = null,
|
||||
server = server,
|
||||
server = defaultServer,
|
||||
endpoint = Endpoint.Rooms
|
||||
)
|
||||
return send(request).map { response ->
|
||||
|
@ -58,12 +58,17 @@ class OpenGroupPoller(private val server: String, private val executorService: S
|
||||
is Endpoint.RoomPollInfo -> {
|
||||
handleRoomPollInfo(server, response.endpoint.roomToken, response.body as OpenGroupApi.RoomPollInfo)
|
||||
}
|
||||
is Endpoint.RoomMessagesRecent -> {
|
||||
is Endpoint.RoomMessagesRecent -> {
|
||||
handleMessages(server, response.endpoint.roomToken, response.body as List<OpenGroupApi.Message>)
|
||||
}
|
||||
is Endpoint.Inbox, Endpoint.Outbox -> {
|
||||
val fromOutbox = response.endpoint.value.startsWith("outbox", ignoreCase = true)
|
||||
handleDirectMessages(server, fromOutbox, response.body as List<OpenGroupApi.DirectMessage>)
|
||||
is Endpoint.RoomMessagesSince -> {
|
||||
handleMessages(server, response.endpoint.roomToken, response.body as List<OpenGroupApi.Message>)
|
||||
}
|
||||
is Endpoint.Inbox, is Endpoint.InboxSince -> {
|
||||
handleDirectMessages(server, false, response.body as List<OpenGroupApi.DirectMessage>)
|
||||
}
|
||||
is Endpoint.Outbox, is Endpoint.OutboxSince -> {
|
||||
handleDirectMessages(server, true, response.body as List<OpenGroupApi.DirectMessage>)
|
||||
}
|
||||
}
|
||||
if (secondToLastJob == null && !isCaughtUp) {
|
||||
@ -77,7 +82,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S
|
||||
|
||||
private fun handleCapabilities(server: String, capabilities: OpenGroupApi.Capabilities) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
storage.setOpenGroupSever(server, capabilities.capabilities)
|
||||
storage.updateOpenGroupCapabilities(server, capabilities.capabilities)
|
||||
}
|
||||
|
||||
private fun handleRoomPollInfo(
|
||||
@ -102,7 +107,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S
|
||||
capabilities = listOf()
|
||||
)
|
||||
// - Open Group changes
|
||||
storage.setOpenGroup(openGroup)
|
||||
storage.updateOpenGroup(openGroup)
|
||||
|
||||
// - User Count
|
||||
storage.setUserCount(roomToken, server, pollInfo.active_users)
|
||||
@ -123,16 +128,19 @@ class OpenGroupPoller(private val server: String, private val executorService: S
|
||||
messages: List<OpenGroupApi.Message>
|
||||
) {
|
||||
val openGroupId = "$server.$roomToken"
|
||||
val msgs = messages.map {
|
||||
val (deletions, additions) = messages.sortedBy { it.seqno }.partition { it.data.isNullOrBlank() }
|
||||
handleNewMessages(roomToken, openGroupId, additions.map {
|
||||
OpenGroupMessageV2(
|
||||
serverID = it.id,
|
||||
sender = it.session_id,
|
||||
sentTimestamp = it.posted,
|
||||
base64EncodedData = it.data,
|
||||
base64EncodedData = it.data!!,
|
||||
base64EncodedSignature = it.signature
|
||||
)
|
||||
}
|
||||
handleNewMessages(roomToken, openGroupId, msgs)
|
||||
})
|
||||
handleDeletedMessages(roomToken, openGroupId, deletions.map {
|
||||
OpenGroupApi.MessageDeletion(it.id, it.seqno)
|
||||
})
|
||||
}
|
||||
|
||||
private fun handleDirectMessages(
|
||||
|
@ -36,7 +36,7 @@ object ProfilePictureUtilities {
|
||||
deferred.reject(e)
|
||||
}
|
||||
TextSecurePreferences.setLastProfilePictureUpload(context, Date().time)
|
||||
val url = "${FileServerApi.server}/files/$id"
|
||||
val url = "${FileServerApi.server}/file/$id"
|
||||
TextSecurePreferences.setProfilePictureURL(context, url)
|
||||
deferred.resolve(Unit)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user