mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
feat: join groups logic
This commit is contained in:
parent
f9939aae92
commit
a4d79ea2d3
@ -4,7 +4,6 @@ import android.animation.Animator
|
|||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Patterns
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -76,25 +75,22 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun joinPublicChatIfPossible(url: String) {
|
fun joinPublicChatIfPossible(url: String) {
|
||||||
if (!Patterns.WEB_URL.matcher(url).matches() || !url.startsWith("https://")) {
|
// add http if just an IP style / host style URL is entered but leave it if scheme is included
|
||||||
return Toast.makeText(this, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
val properString = if (!url.startsWith("http")) "http://$url" else url
|
val properString = if (!url.startsWith("http")) "http://$url" else url
|
||||||
val httpUrl = HttpUrl.parse(url) ?: return Toast.makeText(this,R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
val httpUrl = HttpUrl.parse(properString) ?: return Toast.makeText(this,R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
val room = httpUrl.pathSegments().firstOrNull()
|
val room = httpUrl.pathSegments().firstOrNull()
|
||||||
val publicKey = httpUrl.queryParameter("public_key")
|
val publicKey = httpUrl.queryParameter("public_key")
|
||||||
val isV2OpenGroup = !room.isNullOrEmpty()
|
val isV2OpenGroup = !room.isNullOrEmpty()
|
||||||
showLoader()
|
showLoader()
|
||||||
val channel: Long = 1
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
if (isV2OpenGroup) {
|
if (isV2OpenGroup) {
|
||||||
val server = httpUrl.newBuilder().removeAllQueryParameters("public_key").removePathSegment(0).build().toString()
|
val server = HttpUrl.Builder().scheme(httpUrl.scheme()).host(httpUrl.host()).build()
|
||||||
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, server, room, publicKey)
|
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, server.toString().removeSuffix("/"), room!!, publicKey!!)
|
||||||
} else {
|
} else {
|
||||||
|
val channel: Long = 1
|
||||||
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, url, channel)
|
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, url, channel)
|
||||||
}
|
}
|
||||||
MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity)
|
MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity)
|
||||||
@ -195,10 +191,7 @@ class EnterChatURLFragment : Fragment() {
|
|||||||
private fun joinPublicChatIfPossible() {
|
private fun joinPublicChatIfPossible() {
|
||||||
val inputMethodManager = requireContext().getSystemService(BaseActionBarActivity.INPUT_METHOD_SERVICE) as InputMethodManager
|
val inputMethodManager = requireContext().getSystemService(BaseActionBarActivity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
inputMethodManager.hideSoftInputFromWindow(chatURLEditText.windowToken, 0)
|
inputMethodManager.hideSoftInputFromWindow(chatURLEditText.windowToken, 0)
|
||||||
var chatURL = chatURLEditText.text.trim().toString().toLowerCase().replace("http://", "https://")
|
val chatURL = chatURLEditText.text.trim().toString().toLowerCase()
|
||||||
if (!chatURL.toLowerCase().startsWith("https")) {
|
|
||||||
chatURL = "https://$chatURL"
|
|
||||||
}
|
|
||||||
(requireActivity() as JoinPublicChatActivity).joinPublicChatIfPossible(chatURL)
|
(requireActivity() as JoinPublicChatActivity).joinPublicChatIfPossible(chatURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,15 +80,6 @@ class PublicChatManager(private val context: Context) {
|
|||||||
return addChat(server, channel, channelInfo)
|
return addChat(server, channel, channelInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
|
||||||
fun addChat(server: String, room: String): OpenGroupV2 {
|
|
||||||
// Ensure the auth token is acquired.
|
|
||||||
OpenGroupAPIV2.getAuthToken(room, server).get()
|
|
||||||
|
|
||||||
val channelInfo = OpenGroupAPIV2.getInfo(room, server).get()
|
|
||||||
return addChat(server, room, channelInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public fun addChat(server: String, channel: Long, info: OpenGroupInfo): OpenGroup {
|
public fun addChat(server: String, channel: Long, info: OpenGroupInfo): OpenGroup {
|
||||||
val chat = PublicChat(channel, server, info.displayName, true)
|
val chat = PublicChat(channel, server, info.displayName, true)
|
||||||
@ -117,17 +108,21 @@ class PublicChatManager(private val context: Context) {
|
|||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun addChat(server: String, room: String, info: OpenGroupAPIV2.Info): OpenGroupV2 {
|
fun addChat(server: String, room: String, info: OpenGroupAPIV2.Info): OpenGroupV2 {
|
||||||
val chat = OpenGroupV2(server, room, info.id, info.name, info.imageID)
|
val chat = OpenGroupV2(server, room, info.id, info.name)
|
||||||
val threadID = GroupManager.getOpenGroupThreadID(chat.id, context)
|
var threadID = GroupManager.getOpenGroupThreadID(chat.id, context)
|
||||||
var profilePicture: Bitmap? = null
|
var profilePicture: Bitmap? = null
|
||||||
if (threadID < 0) {
|
if (threadID < 0) {
|
||||||
val imageID = info.imageID
|
val profilePictureAsByteArray = try {
|
||||||
if (!imageID.isNullOrEmpty()) {
|
OpenGroupAPIV2.downloadOpenGroupProfilePicture(info.id,server).get()
|
||||||
val profilePictureAsByteArray = OpenGroupAPIV2.downloadOpenGroupProfilePicture(info.id,server)
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
profilePicture = BitmapUtil.fromByteArray(profilePictureAsByteArray)
|
profilePicture = BitmapUtil.fromByteArray(profilePictureAsByteArray)
|
||||||
}
|
|
||||||
val result = GroupManager.createOpenGroup(chat.id, context, profilePicture, info.name)
|
val result = GroupManager.createOpenGroup(chat.id, context, profilePicture, info.name)
|
||||||
|
threadID = result.threadId
|
||||||
}
|
}
|
||||||
|
DatabaseFactory.getLokiThreadDatabase(context).setOpenGroupChat(chat, threadID)
|
||||||
|
Util.runOnMain { startPollersIfNeeded() }
|
||||||
return chat
|
return chat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,17 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setOpenGroupChat(openGroupV2: OpenGroupV2, threadID: Long) {
|
||||||
|
if (threadID < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val database = databaseHelper.writableDatabase
|
||||||
|
val contentValues = ContentValues(2)
|
||||||
|
contentValues.put(Companion.threadID, threadID)
|
||||||
|
contentValues.put(publicChat, JsonUtil.toJson(openGroupV2.toJson()))
|
||||||
|
database.insertOrUpdate(publicChatTable, contentValues, "${Companion.threadID} = ?", arrayOf(threadID.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
override fun getPublicChat(threadID: Long): PublicChat? {
|
override fun getPublicChat(threadID: Long): PublicChat? {
|
||||||
if (threadID < 0) {
|
if (threadID < 0) {
|
||||||
return null
|
return null
|
||||||
|
@ -3,8 +3,10 @@ package org.thoughtcrime.securesms.loki.utilities
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.session.libsession.messaging.MessagingConfiguration
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroup
|
import org.session.libsession.messaging.opengroups.OpenGroup
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroupAPI
|
import org.session.libsession.messaging.opengroups.OpenGroupAPI
|
||||||
|
import org.session.libsession.messaging.opengroups.OpenGroupAPIV2
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroupV2
|
import org.session.libsession.messaging.opengroups.OpenGroupV2
|
||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
@ -21,14 +23,24 @@ object OpenGroupUtilities {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun addGroup(context: Context, server: String, room: String, publicKey: String?): OpenGroupV2 {
|
fun addGroup(context: Context, server: String, room: String, publicKey: String): OpenGroupV2 {
|
||||||
val groupId = "$server.$room"
|
val groupId = "$server.$room"
|
||||||
val threadID = GroupManager.getOpenGroupThreadID(groupId, context)
|
val threadID = GroupManager.getOpenGroupThreadID(groupId, context)
|
||||||
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
|
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
|
||||||
if (openGroup != null) return openGroup
|
if (openGroup != null) return openGroup
|
||||||
|
|
||||||
|
MessagingConfiguration.shared.storage.setOpenGroupPublicKey(server,publicKey)
|
||||||
|
OpenGroupAPIV2.getAuthToken(room, server).get()
|
||||||
|
val groupInfo = OpenGroupAPIV2.getInfo(room,server).get()
|
||||||
val application = ApplicationContext.getInstance(context)
|
val application = ApplicationContext.getInstance(context)
|
||||||
val group = application.publicChatManager.addChat(server, room, publicKey)
|
|
||||||
|
val group = application.publicChatManager.addChat(server, room, groupInfo)
|
||||||
|
|
||||||
|
val storage = MessagingConfiguration.shared.storage
|
||||||
|
storage.removeLastDeletionServerId(room, server)
|
||||||
|
storage.removeLastMessageServerId(room, server)
|
||||||
|
|
||||||
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -6,6 +6,7 @@ import nl.komponents.kovenant.Kovenant
|
|||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.functional.bind
|
import nl.komponents.kovenant.functional.bind
|
||||||
import nl.komponents.kovenant.functional.map
|
import nl.komponents.kovenant.functional.map
|
||||||
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.MediaType
|
import okhttp3.MediaType
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
@ -92,9 +93,10 @@ object OpenGroupAPIV2 {
|
|||||||
fun execute(token: String?): Promise<Map<*, *>, Exception> {
|
fun execute(token: String?): Promise<Map<*, *>, Exception> {
|
||||||
val requestBuilder = okhttp3.Request.Builder()
|
val requestBuilder = okhttp3.Request.Builder()
|
||||||
.url(urlBuilder.build())
|
.url(urlBuilder.build())
|
||||||
|
.headers(Headers.of(request.headers))
|
||||||
if (request.isAuthRequired) {
|
if (request.isAuthRequired) {
|
||||||
if (token.isNullOrEmpty()) throw IllegalStateException("No auth token for request")
|
if (token.isNullOrEmpty()) throw IllegalStateException("No auth token for request")
|
||||||
requestBuilder.addHeader("Authorization", token)
|
requestBuilder.header("Authorization", token)
|
||||||
}
|
}
|
||||||
when (request.verb) {
|
when (request.verb) {
|
||||||
GET -> requestBuilder.get()
|
GET -> requestBuilder.get()
|
||||||
@ -353,7 +355,7 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getInfo(room: String, server: String): Promise<Info, Exception> {
|
fun getInfo(room: String, server: String): Promise<Info, Exception> {
|
||||||
val request = Request(verb = GET, room = room, server = server, endpoint = "rooms/$room", isAuthRequired = false)
|
val request = Request(verb = GET, room = null, server = server, endpoint = "rooms/$room", isAuthRequired = false)
|
||||||
return send(request).map(sharedContext) { json ->
|
return send(request).map(sharedContext) { json ->
|
||||||
val rawRoom = json["room"] as? Map<*, *> ?: throw Error.PARSING_FAILED
|
val rawRoom = json["room"] as? Map<*, *> ?: throw Error.PARSING_FAILED
|
||||||
val id = rawRoom["id"] as? String ?: throw Error.PARSING_FAILED
|
val id = rawRoom["id"] as? String ?: throw Error.PARSING_FAILED
|
||||||
|
@ -8,17 +8,15 @@ data class OpenGroupV2(
|
|||||||
val room: String,
|
val room: String,
|
||||||
val id: String,
|
val id: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val publicKey: String,
|
val publicKey: String
|
||||||
val imageId: String?
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
constructor(server: String, room: String, name: String, publicKey: String, imageId: String?) : this(
|
constructor(server: String, room: String, name: String, publicKey: String) : this(
|
||||||
server = server,
|
server = server,
|
||||||
room = room,
|
room = room,
|
||||||
id = "$server.$room",
|
id = "$server.$room",
|
||||||
name = name,
|
name = name,
|
||||||
publicKey = publicKey,
|
publicKey = publicKey,
|
||||||
imageId = imageId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -32,9 +30,8 @@ data class OpenGroupV2(
|
|||||||
val server = json.get("server").asText().toLowerCase(Locale.getDefault())
|
val server = json.get("server").asText().toLowerCase(Locale.getDefault())
|
||||||
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().let { str -> if (str.isEmpty()) null else str }
|
|
||||||
|
|
||||||
OpenGroupV2(server, room, displayName, publicKey, imageId)
|
OpenGroupV2(server, room, displayName, publicKey)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -42,4 +39,11 @@ data class OpenGroupV2(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toJson(): Map<String,String> = mapOf(
|
||||||
|
"room" to room,
|
||||||
|
"server" to server,
|
||||||
|
"displayName" to name,
|
||||||
|
"publicKey" to publicKey,
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
@ -7,7 +7,6 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage
|
|||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsignal.service.internal.push.PushTransportDetails
|
import org.session.libsignal.service.internal.push.PushTransportDetails
|
||||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
import org.session.libsignal.utilities.logging.Log
|
|
||||||
|
|
||||||
object MessageReceiver {
|
object MessageReceiver {
|
||||||
|
|
||||||
@ -122,7 +121,6 @@ object MessageReceiver {
|
|||||||
message.recipient = userPublicKey
|
message.recipient = userPublicKey
|
||||||
message.sentTimestamp = envelope.timestamp
|
message.sentTimestamp = envelope.timestamp
|
||||||
message.receivedTimestamp = if (envelope.hasServerTimestamp()) envelope.serverTimestamp else System.currentTimeMillis()
|
message.receivedTimestamp = if (envelope.hasServerTimestamp()) envelope.serverTimestamp else System.currentTimeMillis()
|
||||||
Log.d("Loki", "time: ${envelope.timestamp}, sent: ${envelope.serverTimestamp}")
|
|
||||||
message.groupPublicKey = groupPublicKey
|
message.groupPublicKey = groupPublicKey
|
||||||
message.openGroupServerMessageID = openGroupServerID
|
message.openGroupServerMessageID = openGroupServerID
|
||||||
// Validate
|
// Validate
|
||||||
|
@ -445,7 +445,7 @@ object OnionRequestAPI {
|
|||||||
val urlAsString = url.toString()
|
val urlAsString = url.toString()
|
||||||
val host = url.host()
|
val host = url.host()
|
||||||
val endpoint = when {
|
val endpoint = when {
|
||||||
server.count() < urlAsString.count() -> urlAsString.substringAfter("$server/")
|
server.count() < urlAsString.count() -> urlAsString.substringAfter(server).removePrefix("/")
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
val body = request.getBodyForOnionRequest() ?: "null"
|
val body = request.getBodyForOnionRequest() ?: "null"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user