feat: adding default group handling to frontend viewmodel

This commit is contained in:
jubb
2021-04-20 17:22:36 +10:00
parent aea23a6fc1
commit 1e164f8648
15 changed files with 246 additions and 185 deletions

View File

@@ -9,8 +9,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentPagerAdapter
import androidx.fragment.app.*
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.activity_join_public_chat.*
import kotlinx.android.synthetic.main.fragment_enter_chat_url.*
@@ -18,13 +17,16 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import network.loki.messenger.R
import org.session.libsignal.utilities.logging.Log
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.session.libsignal.utilities.logging.Log
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities
import org.thoughtcrime.securesms.loki.viewmodel.DefaultGroup
import org.thoughtcrime.securesms.loki.viewmodel.DefaultGroupsViewModel
import org.thoughtcrime.securesms.loki.viewmodel.State
class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
private val adapter = JoinPublicChatActivityAdapter(this)
@@ -122,14 +124,34 @@ private class JoinPublicChatActivityAdapter(val activity: JoinPublicChatActivity
// region Enter Chat URL Fragment
class EnterChatURLFragment : Fragment() {
// factory producer is app scoped because default groups will want to stick around for app lifetime
private val viewModel by activityViewModels<DefaultGroupsViewModel>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_enter_chat_url, container, false)
}
private fun populateDefaultGroups(groups: List<DefaultGroup>) {
Log.d("Loki", "Got some default groups $groups")
}
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 ->
when (state) {
State.Loading -> {
// show a loader here probs
}
is State.Error -> {
// hide the loader and the
}
is State.Success -> {
populateDefaultGroups(state.value)
}
}
}
}
private fun joinPublicChatIfPossible() {

View File

@@ -30,7 +30,7 @@ class PublicChatManager(private val context: Context) {
public fun areAllCaughtUp(): Boolean {
var areAllCaughtUp = true
refreshChatsAndPollers()
for ((threadID, chat) in chats) {
for ((threadID, _) in chats) {
val poller = pollers[threadID]
areAllCaughtUp = if (poller != null) areAllCaughtUp && poller.isCaughtUp else true
}
@@ -83,9 +83,9 @@ class PublicChatManager(private val context: Context) {
@WorkerThread
fun addChat(server: String, room: String): OpenGroupV2 {
// Ensure the auth token is acquired.
OpenGroupAPIV2.getAuthToken(server).get()
OpenGroupAPIV2.getAuthToken(room, server).get()
val channelInfo = OpenGroupAPIV2.getChannelInfo(channel, server).get()
val channelInfo = OpenGroupAPIV2.getInfo(room, server).get()
return addChat(server, room, channelInfo)
}
@@ -116,17 +116,19 @@ class PublicChatManager(private val context: Context) {
}
@WorkerThread
fun addChat(server: String, room: String, info: OpenGroupInfo): OpenGroupV2 {
val chat = OpenGroupV2(server, room, info.displayName, )
var threadID = GroupManager.getOpenGroupThreadID(chat.id, context)
fun addChat(server: String, room: String, info: OpenGroupAPIV2.Info): OpenGroupV2 {
val chat = OpenGroupV2(server, room, info.id, info.name, info.imageID)
val threadID = GroupManager.getOpenGroupThreadID(chat.id, context)
var profilePicture: Bitmap? = null
if (threadID < 0) {
if (info.profilePictureURL.isNotEmpty()) {
val profilePictureAsByteArray = OpenGroupAPIV2.downloadOpenGroupProfilePicture(server, info.profilePictureURL)
val imageID = info.imageID
if (!imageID.isNullOrEmpty()) {
val profilePictureAsByteArray = OpenGroupAPIV2.downloadOpenGroupProfilePicture(imageID)
profilePicture = BitmapUtil.fromByteArray(profilePictureAsByteArray)
}
val result = GroupManager.createOpenGroup()
val result = GroupManager.createOpenGroup(chat.id, context, profilePicture, info.name)
}
return chat
}
public fun removeChat(server: String, channel: Long) {

View File

@@ -0,0 +1,39 @@
package org.thoughtcrime.securesms.loki.viewmodel
import androidx.lifecycle.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import org.session.libsession.messaging.opengroups.OpenGroupAPIV2
import org.session.libsignal.utilities.logging.Log
class DefaultGroupsViewModel : ViewModel() {
init {
OpenGroupAPIV2.getDefaultRoomsIfNeeded()
}
val defaultRooms = OpenGroupAPIV2.defaultRooms.asLiveData().distinctUntilChanged().switchMap { groups ->
liveData {
// load images etc
emit(State.Loading)
val images = groups.filterNot { it.imageID.isNullOrEmpty() }.map { group ->
val image = viewModelScope.async(Dispatchers.IO) {
try {
OpenGroupAPIV2.downloadOpenGroupProfilePicture(group.imageID!!)
} catch (e: Exception) {
Log.e("Loki", "Error getting group profile picture", e)
null
}
}
group.id to image
}.toMap()
val defaultGroups = groups.map { group ->
DefaultGroup(group.id, group.name, images[group.id]?.await())
}
emit(State.Success(defaultGroups))
}
}
}
data class DefaultGroup(val id: String, val name: String, val image: ByteArray?)

View File

@@ -0,0 +1,7 @@
package org.thoughtcrime.securesms.loki.viewmodel
sealed class State<T> {
object Loading : State<Nothing>()
data class Success<T>(val value: T): State<T>()
data class Error(val error: Exception): State<Nothing>()
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -22,12 +22,49 @@
android:layout_marginTop="@dimen/large_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:inputType="textWebEmailAddress"
android:hint="Enter an open group URL" />
android:hint="@string/fragment_enter_chat_url_edit_text_hint" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<androidx.gridlayout.widget.GridLayout
app:columnCount="2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:theme="@style/Theme.MaterialComponents.DayNight"
style="?attr/chipStyle"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:textStartPadding="10dp"
android:text="Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.chip.Chip
android:theme="@style/Theme.MaterialComponents.DayNight"
style="?attr/chipStyle"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:textStartPadding="10dp"
android:text="Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.chip.Chip
android:theme="@style/Theme.MaterialComponents.DayNight"
style="?attr/chipStyle"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:textStartPadding="10dp"
android:text="Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.chip.Chip
android:theme="@style/Theme.MaterialComponents.DayNight"
style="?attr/chipStyle"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:textStartPadding="10dp"
android:text="Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.gridlayout.widget.GridLayout>
<Button
style="@style/Widget.Session.Button.Common.ProminentOutline"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -29,6 +29,14 @@
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.chip.Chip
android:theme="@style/Theme.MaterialComponents.DayNight"
app:closeIconEnabled="true"
style="?attr/chipStyle"
android:text="Main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
style="@style/Widget.Session.Button.Common.ProminentOutline"
android:id="@+id/joinPublicChatButton"

View File

@@ -3,7 +3,7 @@
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
</domain-config>
<domain-config cleartextTrafficPermitted="false">
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">public.loki.foundation</domain>
<trust-anchors>
<certificates src="@raw/lf_session_cert"/>
@@ -21,4 +21,13 @@
<certificates src="@raw/seed3cert"/>
</trust-anchors>
</domain-config>
<debug-overrides>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
<certificates src="system" />
</trust-anchors>
</base-config>
</debug-overrides>
</network-security-config>