pull/533/head
Niels Andriesse 3 years ago
parent 1efd516eaf
commit 61c210837e

@ -11,7 +11,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.* import androidx.fragment.app.*
@ -42,9 +41,6 @@ import org.thoughtcrime.securesms.loki.viewmodel.DefaultGroupsViewModel
import org.thoughtcrime.securesms.loki.viewmodel.State import org.thoughtcrime.securesms.loki.viewmodel.State
class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate { class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
private val viewModel by viewModels<DefaultGroupsViewModel>()
private val adapter = JoinPublicChatActivityAdapter(this) private val adapter = JoinPublicChatActivityAdapter(this)
// region Lifecycle // region Lifecycle
@ -83,23 +79,18 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode
} }
fun joinPublicChatIfPossible(url: String) { fun joinPublicChatIfPossible(url: String) {
// add http if just an IP style / host style URL is entered but leave it if scheme is included // Add "http" if not entered explicitly
val properString = if (!url.startsWith("http")) "http://$url" else url val stringWithExplicitScheme = if (!url.startsWith("http")) "http://$url" else url
val httpUrl = HttpUrl.parse(properString) ?: return Toast.makeText(this,R.string.invalid_url, Toast.LENGTH_SHORT).show() val url = HttpUrl.parse(stringWithExplicitScheme) ?: return Toast.makeText(this,R.string.invalid_url, Toast.LENGTH_SHORT).show()
val room = url.pathSegments().firstOrNull()
val room = httpUrl.pathSegments().firstOrNull() val publicKey = url.queryParameter("public_key")
val publicKey = httpUrl.queryParameter("public_key")
val isV2OpenGroup = !room.isNullOrEmpty() val isV2OpenGroup = !room.isNullOrEmpty()
showLoader() showLoader()
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
try { try {
val (threadID, groupID) = if (isV2OpenGroup) { val (threadID, groupID) = if (isV2OpenGroup) {
val server = HttpUrl.Builder().scheme(httpUrl.scheme()).host(httpUrl.host()).apply { val server = HttpUrl.Builder().scheme(url.scheme()).host(url.host()).apply {
if (httpUrl.port() != 80 || httpUrl.port() != 443) { if (url.port() != 80 || url.port() != 443) { this.port(url.port()) } // Non-standard port; add to server
// non-standard port, add to server
this.port(httpUrl.port())
}
}.build() }.build()
val group = OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, server.toString().removeSuffix("/"), room!!, publicKey!!) val group = OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, server.toString().removeSuffix("/"), room!!, publicKey!!)
val threadID = GroupManager.getOpenGroupThreadID(group.id, this@JoinPublicChatActivity) val threadID = GroupManager.getOpenGroupThreadID(group.id, this@JoinPublicChatActivity)
@ -107,21 +98,19 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode
threadID to groupID threadID to groupID
} else { } else {
val channel: Long = 1 val channel: Long = 1
val group = OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, properString, channel) val group = OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, stringWithExplicitScheme, channel)
val threadID = GroupManager.getOpenGroupThreadID(group.id, this@JoinPublicChatActivity) val threadID = GroupManager.getOpenGroupThreadID(group.id, this@JoinPublicChatActivity)
val groupID = GroupUtil.getEncodedOpenGroupID(group.id.toByteArray()) val groupID = GroupUtil.getEncodedOpenGroupID(group.id.toByteArray())
threadID to groupID threadID to groupID
} }
MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity) MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
// go to the new conversation and finish this one val recipient = Recipient.from(this@JoinPublicChatActivity, Address.fromSerialized(groupID), false)
openConversationActivity(this@JoinPublicChatActivity, threadID, Recipient.from(this@JoinPublicChatActivity, Address.fromSerialized(groupID), false)) openConversationActivity(this@JoinPublicChatActivity, threadID, recipient)
finish() finish()
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("JoinPublicChatActivity", "Fialed to join open group.", e) Log.e("Loki", "Couldn't join open group.", e)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
hideLoader() hideLoader()
Toast.makeText(this@JoinPublicChatActivity, R.string.activity_join_public_chat_error, Toast.LENGTH_SHORT).show() Toast.makeText(this@JoinPublicChatActivity, R.string.activity_join_public_chat_error, Toast.LENGTH_SHORT).show()
@ -175,13 +164,33 @@ private class JoinPublicChatActivityAdapter(val activity: JoinPublicChatActivity
// region Enter Chat URL Fragment // region Enter Chat URL Fragment
class EnterChatURLFragment : Fragment() { class EnterChatURLFragment : Fragment() {
private val viewModel by activityViewModels<DefaultGroupsViewModel>() private val viewModel by activityViewModels<DefaultGroupsViewModel>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_enter_chat_url, container, false) return inflater.inflate(R.layout.fragment_enter_chat_url, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
chatURLEditText.imeOptions = chatURLEditText.imeOptions or 16777216 // Always use incognito keyboard
joinPublicChatButton.setOnClickListener { joinPublicChatIfPossible() }
viewModel.defaultRooms.observe(viewLifecycleOwner) { state ->
defaultRoomsContainer.isVisible = state is State.Success
defaultRoomsLoader.isVisible = state is State.Loading
when (state) {
State.Loading -> {
// TODO: Show a loader
}
is State.Error -> {
// TODO: Hide the loader
}
is State.Success -> {
populateDefaultGroups(state.value)
}
}
}
}
private fun populateDefaultGroups(groups: List<DefaultGroup>) { private fun populateDefaultGroups(groups: List<DefaultGroup>) {
defaultRoomsGridLayout.removeAllViews() defaultRoomsGridLayout.removeAllViews()
groups.forEach { defaultGroup -> groups.forEach { defaultGroup ->
@ -200,32 +209,10 @@ class EnterChatURLFragment : Fragment() {
defaultRoomsGridLayout.addView(chip) defaultRoomsGridLayout.addView(chip)
} }
if (groups.size and 1 != 0) { if (groups.size and 1 != 0) {
// add a filler weight 1 view
layoutInflater.inflate(R.layout.grid_layout_filler, defaultRoomsGridLayout) layoutInflater.inflate(R.layout.grid_layout_filler, defaultRoomsGridLayout)
} }
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
chatURLEditText.imeOptions = chatURLEditText.imeOptions or 16777216 // Always use incognito keyboard
joinPublicChatButton.setOnClickListener { joinPublicChatIfPossible() }
viewModel.defaultRooms.observe(viewLifecycleOwner) { state ->
defaultRoomsParent.isVisible = state is State.Success
defaultRoomsLoader.isVisible = state is State.Loading
when (state) {
State.Loading -> {
// show a loader here probs
}
is State.Error -> {
// hide the loader and the
}
is State.Success -> {
populateDefaultGroups(state.value)
}
}
}
}
// region Convenience // region Convenience
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

@ -20,5 +20,4 @@ class DefaultGroupsViewModel : ViewModel() {
}.onStart { }.onStart {
emit(State.Loading) emit(State.Loading)
}.asLiveData() }.asLiveData()
} }

@ -34,10 +34,11 @@
<LinearLayout <LinearLayout
android:visibility="gone" android:visibility="gone"
android:paddingHorizontal="24dp" android:paddingHorizontal="24dp"
android:id="@+id/defaultRoomsParent" android:id="@+id/defaultRoomsContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:layout_marginVertical="16dp" android:layout_marginVertical="16dp"
android:textSize="18sp" android:textSize="18sp"
@ -45,11 +46,13 @@
android:text="@string/activity_join_public_chat_join_rooms" android:text="@string/activity_join_public_chat_join_rooms"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<GridLayout <GridLayout
android:id="@+id/defaultRoomsGridLayout" android:id="@+id/defaultRoomsGridLayout"
android:columnCount="2" android:columnCount="2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>
<View <View

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.chip.Chip
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:theme="@style/Theme.MaterialComponents.DayNight" android:theme="@style/Theme.MaterialComponents.DayNight"

@ -34,10 +34,11 @@
<LinearLayout <LinearLayout
android:visibility="gone" android:visibility="gone"
android:paddingHorizontal="24dp" android:paddingHorizontal="24dp"
android:id="@+id/defaultRoomsParent" android:id="@+id/defaultRoomsContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:layout_marginVertical="16dp" android:layout_marginVertical="16dp"
android:textSize="18sp" android:textSize="18sp"
@ -45,11 +46,13 @@
android:text="@string/activity_join_public_chat_join_rooms" android:text="@string/activity_join_public_chat_join_rooms"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<GridLayout <GridLayout
android:id="@+id/defaultRoomsGridLayout" android:id="@+id/defaultRoomsGridLayout"
android:columnCount="2" android:columnCount="2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>
<View <View

@ -348,7 +348,7 @@ object OpenGroupAPIV2 {
// region General // region General
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun getCompactPoll(rooms: List<String>, server: String): Promise<Map<String, CompactPollResult>, Exception> { fun compactPoll(rooms: List<String>, server: String): Promise<Map<String, CompactPollResult>, Exception> {
val authTokenRequests = rooms.associateWith { room -> getAuthToken(room, server) } val authTokenRequests = rooms.associateWith { room -> getAuthToken(room, server) }
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
val requests = rooms.mapNotNull { room -> val requests = rooms.mapNotNull { room ->

@ -70,7 +70,7 @@ class OpenGroupV2Poller(private val openGroups: List<OpenGroupV2>, private val e
isPollOngoing = true isPollOngoing = true
val server = openGroups.first().server // assume all the same server val server = openGroups.first().server // assume all the same server
val rooms = openGroups.map { it.room } val rooms = openGroups.map { it.room }
return OpenGroupAPIV2.getCompactPoll(rooms = rooms, server).successBackground { results -> return OpenGroupAPIV2.compactPoll(rooms = rooms, server).successBackground { results ->
results.forEach { (room, results) -> results.forEach { (room, results) ->
val serverRoomId = "$server.$room" val serverRoomId = "$server.$room"
handleDeletedMessages(serverRoomId,results.deletions) handleDeletedMessages(serverRoomId,results.deletions)

Loading…
Cancel
Save