mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-12 07:37:42 +00:00
feat: adding default group handling to frontend viewmodel
This commit is contained in:
@@ -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() {
|
||||
|
@@ -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) {
|
||||
|
@@ -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?)
|
@@ -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>()
|
||||
}
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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>
|
Reference in New Issue
Block a user