mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-25 11:57:21 +00:00
feat: handling default group requests and open group api updates for proper image endpoint handling
This commit is contained in:
parent
c601098065
commit
f9939aae92
@ -57,48 +57,49 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
|
|||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
|
||||||
|
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage;
|
||||||
import org.session.libsession.messaging.messages.visible.Quote;
|
import org.session.libsession.messaging.messages.visible.Quote;
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
||||||
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.sending_receiving.MessageSender;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
||||||
|
import org.session.libsession.messaging.threads.Address;
|
||||||
|
import org.session.libsession.messaging.threads.recipients.Recipient;
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
|
import org.session.libsession.utilities.Util;
|
||||||
|
import org.session.libsession.utilities.ViewUtil;
|
||||||
|
import org.session.libsession.utilities.concurrent.SimpleTask;
|
||||||
|
import org.session.libsession.utilities.task.ProgressDialogAsyncTask;
|
||||||
|
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||||
|
import org.session.libsignal.service.loki.api.opengroups.PublicChat;
|
||||||
|
import org.session.libsignal.utilities.logging.Log;
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.MessageDetailsActivity;
|
import org.thoughtcrime.securesms.MessageDetailsActivity;
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||||
import org.thoughtcrime.securesms.ShareActivity;
|
import org.thoughtcrime.securesms.ShareActivity;
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
|
||||||
import org.thoughtcrime.securesms.components.ConversationTypingView;
|
import org.thoughtcrime.securesms.components.ConversationTypingView;
|
||||||
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
|
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationAdapter.HeaderViewHolder;
|
import org.thoughtcrime.securesms.conversation.ConversationAdapter.HeaderViewHolder;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener;
|
import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener;
|
||||||
import org.session.libsession.messaging.threads.Address;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
|
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||||
import org.session.libsignal.utilities.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.longmessage.LongMessageActivity;
|
import org.thoughtcrime.securesms.longmessage.LongMessageActivity;
|
||||||
import org.thoughtcrime.securesms.mediasend.Media;
|
import org.thoughtcrime.securesms.mediasend.Media;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage;
|
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||||
import org.session.libsession.messaging.threads.recipients.Recipient;
|
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender;
|
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage;
|
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||||
import org.session.libsession.utilities.task.ProgressDialogAsyncTask;
|
|
||||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
|
||||||
import org.session.libsignal.service.loki.api.opengroups.PublicChat;
|
|
||||||
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
|
||||||
import org.session.libsession.utilities.Util;
|
|
||||||
import org.session.libsession.utilities.ViewUtil;
|
|
||||||
import org.session.libsession.utilities.concurrent.SimpleTask;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -396,7 +397,8 @@ public class ConversationFragment extends Fragment
|
|||||||
|
|
||||||
if (isGroupChat) {
|
if (isGroupChat) {
|
||||||
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
||||||
boolean isPublicChat = (publicChat != null);
|
OpenGroupV2 openGroupChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getOpenGroupChat(threadId);
|
||||||
|
boolean isPublicChat = (publicChat != null || openGroupChat != null);
|
||||||
int selectedMessageCount = messageRecords.size();
|
int selectedMessageCount = messageRecords.size();
|
||||||
boolean areAllSentByUser = true;
|
boolean areAllSentByUser = true;
|
||||||
Set<String> uniqueUserSet = new HashSet<>();
|
Set<String> uniqueUserSet = new HashSet<>();
|
||||||
@ -407,7 +409,11 @@ public class ConversationFragment extends Fragment
|
|||||||
menu.findItem(R.id.menu_context_copy_public_key).setVisible(selectedMessageCount == 1 && !areAllSentByUser);
|
menu.findItem(R.id.menu_context_copy_public_key).setVisible(selectedMessageCount == 1 && !areAllSentByUser);
|
||||||
menu.findItem(R.id.menu_context_reply).setVisible(selectedMessageCount == 1);
|
menu.findItem(R.id.menu_context_reply).setVisible(selectedMessageCount == 1);
|
||||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
|
||||||
boolean userCanModerate = isPublicChat && OpenGroupAPI.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer());
|
boolean userCanModerate =
|
||||||
|
(isPublicChat &&
|
||||||
|
(OpenGroupAPI.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer())
|
||||||
|
|| OpenGroupAPIV2.isUserModerator(userHexEncodedPublicKey, openGroupChat.getRoom(), openGroupChat.getServer()))
|
||||||
|
);
|
||||||
boolean isDeleteOptionVisible = !isPublicChat || (areAllSentByUser || userCanModerate);
|
boolean isDeleteOptionVisible = !isPublicChat || (areAllSentByUser || userCanModerate);
|
||||||
// allow banning if moderating a public chat and only one user's messages are selected
|
// allow banning if moderating a public chat and only one user's messages are selected
|
||||||
boolean isBanOptionVisible = isPublicChat && userCanModerate && !areAllSentByUser && uniqueUserSet.size() == 1;
|
boolean isBanOptionVisible = isPublicChat && userCanModerate && !areAllSentByUser && uniqueUserSet.size() == 1;
|
||||||
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.loki.activities
|
|||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Patterns
|
import android.util.Patterns
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -9,14 +10,20 @@ 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.view.isVisible
|
||||||
import androidx.fragment.app.*
|
import androidx.fragment.app.*
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
import kotlinx.android.synthetic.main.activity_join_public_chat.*
|
import kotlinx.android.synthetic.main.activity_join_public_chat.*
|
||||||
import kotlinx.android.synthetic.main.fragment_enter_chat_url.*
|
import kotlinx.android.synthetic.main.fragment_enter_chat_url.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import org.session.libsession.messaging.opengroups.OpenGroupAPIV2.DefaultGroup
|
||||||
import org.session.libsignal.utilities.logging.Log
|
import org.session.libsignal.utilities.logging.Log
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
@ -24,11 +31,13 @@ import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
|
|||||||
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
|
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate
|
||||||
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol
|
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol
|
||||||
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities
|
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.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
|
||||||
@ -70,12 +79,24 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode
|
|||||||
if (!Patterns.WEB_URL.matcher(url).matches() || !url.startsWith("https://")) {
|
if (!Patterns.WEB_URL.matcher(url).matches() || !url.startsWith("https://")) {
|
||||||
return Toast.makeText(this, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
return Toast.makeText(this, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 room = httpUrl.pathSegments().firstOrNull()
|
||||||
|
val publicKey = httpUrl.queryParameter("public_key")
|
||||||
|
val isV2OpenGroup = !room.isNullOrEmpty()
|
||||||
showLoader()
|
showLoader()
|
||||||
val channel: Long = 1
|
val channel: Long = 1
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, url, channel)
|
if (isV2OpenGroup) {
|
||||||
|
val server = httpUrl.newBuilder().removeAllQueryParameters("public_key").removePathSegment(0).build().toString()
|
||||||
|
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, server, room, publicKey)
|
||||||
|
} else {
|
||||||
|
OpenGroupUtilities.addGroup(this@JoinPublicChatActivity, url, channel)
|
||||||
|
}
|
||||||
MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity)
|
MultiDeviceProtocol.forceSyncConfigurationNowIfNeeded(this@JoinPublicChatActivity)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("JoinPublicChatActivity", "Fialed to join open group.", e)
|
Log.e("JoinPublicChatActivity", "Fialed to join open group.", e)
|
||||||
@ -111,7 +132,7 @@ private class JoinPublicChatActivityAdapter(val activity: JoinPublicChatActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPageTitle(index: Int): CharSequence? {
|
override fun getPageTitle(index: Int): CharSequence {
|
||||||
return when (index) {
|
return when (index) {
|
||||||
0 -> activity.resources.getString(R.string.activity_join_public_chat_enter_group_url_tab_title)
|
0 -> activity.resources.getString(R.string.activity_join_public_chat_enter_group_url_tab_title)
|
||||||
1 -> activity.resources.getString(R.string.activity_join_public_chat_scan_qr_code_tab_title)
|
1 -> activity.resources.getString(R.string.activity_join_public_chat_scan_qr_code_tab_title)
|
||||||
@ -124,7 +145,6 @@ private class JoinPublicChatActivityAdapter(val activity: JoinPublicChatActivity
|
|||||||
// region Enter Chat URL Fragment
|
// region Enter Chat URL Fragment
|
||||||
class EnterChatURLFragment : 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>()
|
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 {
|
||||||
@ -132,7 +152,23 @@ class EnterChatURLFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun populateDefaultGroups(groups: List<DefaultGroup>) {
|
private fun populateDefaultGroups(groups: List<DefaultGroup>) {
|
||||||
Log.d("Loki", "Got some default groups $groups")
|
defaultRoomsGridLayout.removeAllViews()
|
||||||
|
groups.forEach { defaultGroup ->
|
||||||
|
val chip = layoutInflater.inflate(R.layout.default_group_chip,defaultRoomsGridLayout, false) as Chip
|
||||||
|
val drawable = defaultGroup.image?.let { bytes ->
|
||||||
|
val bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.size)
|
||||||
|
RoundedBitmapDrawableFactory.create(resources,bitmap).apply {
|
||||||
|
isCircular = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chip.chipIcon = drawable
|
||||||
|
chip.text = defaultGroup.name
|
||||||
|
defaultRoomsGridLayout.addView(chip)
|
||||||
|
}
|
||||||
|
if (groups.size and 1 != 0) {
|
||||||
|
// add a filler weight 1 view
|
||||||
|
layoutInflater.inflate(R.layout.grid_layout_filler, defaultRoomsGridLayout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@ -140,6 +176,8 @@ class EnterChatURLFragment : Fragment() {
|
|||||||
chatURLEditText.imeOptions = chatURLEditText.imeOptions or 16777216 // Always use incognito keyboard
|
chatURLEditText.imeOptions = chatURLEditText.imeOptions or 16777216 // Always use incognito keyboard
|
||||||
joinPublicChatButton.setOnClickListener { joinPublicChatIfPossible() }
|
joinPublicChatButton.setOnClickListener { joinPublicChatIfPossible() }
|
||||||
viewModel.defaultRooms.observe(viewLifecycleOwner) { state ->
|
viewModel.defaultRooms.observe(viewLifecycleOwner) { state ->
|
||||||
|
defaultRoomsParent.isVisible = state is State.Success
|
||||||
|
defaultRoomsLoader.isVisible = state is State.Loading
|
||||||
when (state) {
|
when (state) {
|
||||||
State.Loading -> {
|
State.Loading -> {
|
||||||
// show a loader here probs
|
// show a loader here probs
|
||||||
|
@ -123,7 +123,7 @@ class PublicChatManager(private val context: Context) {
|
|||||||
if (threadID < 0) {
|
if (threadID < 0) {
|
||||||
val imageID = info.imageID
|
val imageID = info.imageID
|
||||||
if (!imageID.isNullOrEmpty()) {
|
if (!imageID.isNullOrEmpty()) {
|
||||||
val profilePictureAsByteArray = OpenGroupAPIV2.downloadOpenGroupProfilePicture(imageID)
|
val profilePictureAsByteArray = OpenGroupAPIV2.downloadOpenGroupProfilePicture(info.id,server)
|
||||||
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)
|
||||||
|
@ -25,8 +25,10 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
private val friendRequestStatus = "friend_request_status"
|
private val friendRequestStatus = "friend_request_status"
|
||||||
private val sessionResetStatus = "session_reset_status"
|
private val sessionResetStatus = "session_reset_status"
|
||||||
val publicChat = "public_chat"
|
val publicChat = "public_chat"
|
||||||
@JvmStatic val createSessionResetTableCommand = "CREATE TABLE $sessionResetTable ($threadID INTEGER PRIMARY KEY, $sessionResetStatus INTEGER DEFAULT 0);"
|
@JvmStatic
|
||||||
@JvmStatic val createPublicChatTableCommand = "CREATE TABLE $publicChatTable ($threadID INTEGER PRIMARY KEY, $publicChat TEXT);"
|
val createSessionResetTableCommand = "CREATE TABLE $sessionResetTable ($threadID INTEGER PRIMARY KEY, $sessionResetStatus INTEGER DEFAULT 0);"
|
||||||
|
@JvmStatic
|
||||||
|
val createPublicChatTableCommand = "CREATE TABLE $publicChatTable ($threadID INTEGER PRIMARY KEY, $publicChat TEXT);"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getThreadID(hexEncodedPublicKey: String): Long {
|
override fun getThreadID(hexEncodedPublicKey: String): Long {
|
||||||
@ -45,11 +47,13 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
val threadID = cursor.getLong(threadID)
|
val threadID = cursor.getLong(threadID)
|
||||||
val string = cursor.getString(publicChat)
|
val string = cursor.getString(publicChat)
|
||||||
val publicChat = PublicChat.fromJSON(string)
|
val publicChat = PublicChat.fromJSON(string)
|
||||||
if (publicChat != null) { result[threadID] = publicChat }
|
if (publicChat != null) {
|
||||||
|
result[threadID] = publicChat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
} finally {
|
} finally {
|
||||||
cursor?.close()
|
cursor?.close()
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -79,25 +83,40 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
return getAllPublicChats().values.fold(setOf()) { set, chat -> set.plus(chat.server) }
|
return getAllPublicChats().values.fold(setOf()) { set, chat -> set.plus(chat.server) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPublicChat(threadID: Long): PublicChat? {
|
fun getOpenGroupChat(threadID: Long): OpenGroupV2? {
|
||||||
if (threadID < 0) { return null }
|
if (threadID < 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
val database = databaseHelper.readableDatabase
|
val database = databaseHelper.readableDatabase
|
||||||
return database.get(publicChatTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor ->
|
return database.get(publicChat, "${Companion.threadID} = ?", arrayOf(threadID.toString())) { cursor ->
|
||||||
|
val json = cursor.getString(publicChat)
|
||||||
|
OpenGroupV2.fromJson(json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPublicChat(threadID: Long): PublicChat? {
|
||||||
|
if (threadID < 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val database = databaseHelper.readableDatabase
|
||||||
|
return database.get(publicChatTable, "${Companion.threadID} = ?", arrayOf(threadID.toString())) { cursor ->
|
||||||
val publicChatAsJSON = cursor.getString(publicChat)
|
val publicChatAsJSON = cursor.getString(publicChat)
|
||||||
PublicChat.fromJSON(publicChatAsJSON)
|
PublicChat.fromJSON(publicChatAsJSON)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setPublicChat(publicChat: PublicChat, threadID: Long) {
|
override fun setPublicChat(publicChat: PublicChat, threadID: Long) {
|
||||||
if (threadID < 0) { return }
|
if (threadID < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
val database = databaseHelper.writableDatabase
|
val database = databaseHelper.writableDatabase
|
||||||
val contentValues = ContentValues(2)
|
val contentValues = ContentValues(2)
|
||||||
contentValues.put(Companion.threadID, threadID)
|
contentValues.put(Companion.threadID, threadID)
|
||||||
contentValues.put(Companion.publicChat, JsonUtil.toJson(publicChat.toJSON()))
|
contentValues.put(Companion.publicChat, JsonUtil.toJson(publicChat.toJSON()))
|
||||||
database.insertOrUpdate(publicChatTable, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() ))
|
database.insertOrUpdate(publicChatTable, contentValues, "${Companion.threadID} = ?", arrayOf(threadID.toString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removePublicChat(threadID: Long) {
|
override fun removePublicChat(threadID: Long) {
|
||||||
databaseHelper.writableDatabase.delete(publicChatTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() ))
|
databaseHelper.writableDatabase.delete(publicChatTable, "${Companion.threadID} = ?", arrayOf(threadID.toString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import androidx.annotation.WorkerThread
|
|||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
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.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
|
||||||
import org.session.libsession.utilities.preferences.ProfileKeyUtil
|
import org.session.libsession.utilities.preferences.ProfileKeyUtil
|
||||||
@ -18,6 +19,18 @@ object OpenGroupUtilities {
|
|||||||
|
|
||||||
private const val TAG = "OpenGroupUtilities"
|
private const val TAG = "OpenGroupUtilities"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@WorkerThread
|
||||||
|
fun addGroup(context: Context, server: String, room: String, publicKey: String?): OpenGroupV2 {
|
||||||
|
val groupId = "$server.$room"
|
||||||
|
val threadID = GroupManager.getOpenGroupThreadID(groupId, context)
|
||||||
|
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getOpenGroupChat(threadID)
|
||||||
|
if (openGroup != null) return openGroup
|
||||||
|
|
||||||
|
val application = ApplicationContext.getInstance(context)
|
||||||
|
val group = application.publicChatManager.addChat(server, room, publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package org.thoughtcrime.securesms.loki.viewmodel
|
package org.thoughtcrime.securesms.loki.viewmodel
|
||||||
|
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.ViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import androidx.lifecycle.asLiveData
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.onStart
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroupAPIV2
|
import org.session.libsession.messaging.opengroups.OpenGroupAPIV2
|
||||||
import org.session.libsignal.utilities.logging.Log
|
|
||||||
|
typealias DefaultGroups = List<OpenGroupAPIV2.DefaultGroup>
|
||||||
|
typealias GroupState = State<DefaultGroups>
|
||||||
|
|
||||||
class DefaultGroupsViewModel : ViewModel() {
|
class DefaultGroupsViewModel : ViewModel() {
|
||||||
|
|
||||||
@ -12,28 +15,10 @@ class DefaultGroupsViewModel : ViewModel() {
|
|||||||
OpenGroupAPIV2.getDefaultRoomsIfNeeded()
|
OpenGroupAPIV2.getDefaultRoomsIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultRooms = OpenGroupAPIV2.defaultRooms.asLiveData().distinctUntilChanged().switchMap { groups ->
|
val defaultRooms = OpenGroupAPIV2.defaultRooms.map<DefaultGroups, GroupState> {
|
||||||
liveData {
|
State.Success(it)
|
||||||
// load images etc
|
}.onStart {
|
||||||
emit(State.Loading)
|
emit(State.Loading)
|
||||||
val images = groups.filterNot { it.imageID.isNullOrEmpty() }.map { group ->
|
}.asLiveData()
|
||||||
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?)
|
|
@ -1,6 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.loki.viewmodel
|
package org.thoughtcrime.securesms.loki.viewmodel
|
||||||
|
|
||||||
sealed class State<T> {
|
sealed class State<out T> {
|
||||||
object Loading : State<Nothing>()
|
object Loading : State<Nothing>()
|
||||||
data class Success<T>(val value: T): State<T>()
|
data class Success<T>(val value: T): State<T>()
|
||||||
data class Error(val error: Exception): State<Nothing>()
|
data class Error(val error: Exception): State<Nothing>()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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:id="@+id/contentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -24,47 +23,39 @@
|
|||||||
android:inputType="textWebEmailAddress"
|
android:inputType="textWebEmailAddress"
|
||||||
android:hint="@string/fragment_enter_chat_url_edit_text_hint" />
|
android:hint="@string/fragment_enter_chat_url_edit_text_hint" />
|
||||||
|
|
||||||
|
<com.github.ybq.android.spinkit.SpinKitView
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/defaultRoomsLoader"
|
||||||
|
style="@style/SpinKitView.Small.WanderingCubes"
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:id="@+id/defaultRoomsParent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/activity_join_public_chat_join_rooms"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<GridLayout
|
||||||
|
android:id="@+id/defaultRoomsGridLayout"
|
||||||
|
android:columnCount="2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1" />
|
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
|
<Button
|
||||||
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||||
|
15
app/src/main/res/layout/default_group_chip.xml
Normal file
15
app/src/main/res/layout/default_group_chip.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<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:tools="http://schemas.android.com/tools"
|
||||||
|
android:theme="@style/Theme.MaterialComponents.DayNight"
|
||||||
|
style="?attr/chipStyle"
|
||||||
|
app:textStartPadding="10dp"
|
||||||
|
app:textEndPadding="10dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_marginHorizontal="2dp"
|
||||||
|
tools:text="Main Group"
|
||||||
|
android:ellipsize="end"
|
||||||
|
tools:layout_width="wrap_content"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="52dp" />
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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:id="@+id/contentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -24,19 +23,40 @@
|
|||||||
android:inputType="textWebEmailAddress"
|
android:inputType="textWebEmailAddress"
|
||||||
android:hint="@string/fragment_enter_chat_url_edit_text_hint" />
|
android:hint="@string/fragment_enter_chat_url_edit_text_hint" />
|
||||||
|
|
||||||
|
<com.github.ybq.android.spinkit.SpinKitView
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/defaultRoomsLoader"
|
||||||
|
style="@style/SpinKitView.Small.WanderingCubes"
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:id="@+id/defaultRoomsParent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/activity_join_public_chat_join_rooms"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<GridLayout
|
||||||
|
android:id="@+id/defaultRoomsGridLayout"
|
||||||
|
android:columnCount="2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1" />
|
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
|
<Button
|
||||||
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||||
android:id="@+id/joinPublicChatButton"
|
android:id="@+id/joinPublicChatButton"
|
||||||
|
5
app/src/main/res/layout/grid_layout_filler.xml
Normal file
5
app/src/main/res/layout/grid_layout_filler.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_height="0dp"/>
|
@ -1884,5 +1884,6 @@
|
|||||||
<string name="activity_backup_restore_passphrase">30-digit passphrase</string>
|
<string name="activity_backup_restore_passphrase">30-digit passphrase</string>
|
||||||
<!-- LinkDeviceActivity -->
|
<!-- LinkDeviceActivity -->
|
||||||
<string name="activity_link_device_skip_prompt">This is taking a while, would you like to skip?</string>
|
<string name="activity_link_device_skip_prompt">This is taking a while, would you like to skip?</string>
|
||||||
|
<string name="activity_join_public_chat_join_rooms">Or join one of these...</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -30,10 +30,10 @@ import java.util.*
|
|||||||
object OpenGroupAPIV2 {
|
object OpenGroupAPIV2 {
|
||||||
|
|
||||||
private val moderators: HashMap<String, Set<String>> = hashMapOf() // Server URL to (channel ID to set of moderator IDs)
|
private val moderators: HashMap<String, Set<String>> = hashMapOf() // Server URL to (channel ID to set of moderator IDs)
|
||||||
private const val DEFAULT_SERVER = "https://sog.ibolpap.finance"
|
const val DEFAULT_SERVER = "https://sog.ibolpap.finance"
|
||||||
private const val DEFAULT_SERVER_PUBLIC_KEY = "b464aa186530c97d6bcf663a3a3b7465a5f782beaa67c83bee99468824b4aa10"
|
private const val DEFAULT_SERVER_PUBLIC_KEY = "b464aa186530c97d6bcf663a3a3b7465a5f782beaa67c83bee99468824b4aa10"
|
||||||
|
|
||||||
val defaultRooms = MutableSharedFlow<List<Info>>(replay = 1)
|
val defaultRooms = MutableSharedFlow<List<DefaultGroup>>(replay = 1)
|
||||||
|
|
||||||
private val sharedContext = Kovenant.createContext()
|
private val sharedContext = Kovenant.createContext()
|
||||||
private val curve = Curve25519.getInstance(Curve25519.BEST)
|
private val curve = Curve25519.getInstance(Curve25519.BEST)
|
||||||
@ -47,6 +47,10 @@ object OpenGroupAPIV2 {
|
|||||||
object NO_PUBLIC_KEY : Error()
|
object NO_PUBLIC_KEY : Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class DefaultGroup(val id: String,
|
||||||
|
val name: String,
|
||||||
|
val image: ByteArray?)
|
||||||
|
|
||||||
data class Info(
|
data class Info(
|
||||||
val id: String,
|
val id: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
@ -77,7 +81,7 @@ object OpenGroupAPIV2 {
|
|||||||
val urlBuilder = HttpUrl.Builder()
|
val urlBuilder = HttpUrl.Builder()
|
||||||
.scheme(parsed.scheme())
|
.scheme(parsed.scheme())
|
||||||
.host(parsed.host())
|
.host(parsed.host())
|
||||||
.addPathSegment(request.endpoint)
|
.addPathSegments(request.endpoint)
|
||||||
|
|
||||||
if (request.verb == GET) {
|
if (request.verb == GET) {
|
||||||
for ((key, value) in request.queryParameters) {
|
for ((key, value) in request.queryParameters) {
|
||||||
@ -139,6 +143,14 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun downloadOpenGroupProfilePicture(roomID: String, server: String): Promise<ByteArray, Exception> {
|
||||||
|
val request = Request(verb = GET, room = roomID, server = server, endpoint = "rooms/$roomID/image", isAuthRequired = false)
|
||||||
|
return send(request).map(sharedContext) { json ->
|
||||||
|
val result = json["result"] as? String ?: throw Error.PARSING_FAILED
|
||||||
|
decode(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getAuthToken(room: String, server: String): Promise<String, Exception> {
|
fun getAuthToken(room: String, server: String): Promise<String, Exception> {
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
return storage.getAuthToken(room, server)?.let {
|
return storage.getAuthToken(room, server)?.let {
|
||||||
@ -312,15 +324,30 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isUserModerator(publicKey: String, room: String, server: String): Boolean = moderators["$server.$room"]?.contains(publicKey)
|
@JvmStatic
|
||||||
?: false
|
fun isUserModerator(publicKey: String, room: String, server: String): Boolean =
|
||||||
|
moderators["$server.$room"]?.contains(publicKey) ?: false
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region General
|
// region General
|
||||||
fun getDefaultRoomsIfNeeded(): Promise<List<Info>, Exception> {
|
fun getDefaultRoomsIfNeeded(): Promise<List<DefaultGroup>, Exception> {
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
storage.setOpenGroupPublicKey(DEFAULT_SERVER, DEFAULT_SERVER_PUBLIC_KEY)
|
storage.setOpenGroupPublicKey(DEFAULT_SERVER, DEFAULT_SERVER_PUBLIC_KEY)
|
||||||
return getAllRooms(DEFAULT_SERVER).success { new ->
|
return getAllRooms(DEFAULT_SERVER).map { groups ->
|
||||||
|
val images = groups.map { group ->
|
||||||
|
group.id to downloadOpenGroupProfilePicture(group.id, DEFAULT_SERVER)
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
groups.map { group ->
|
||||||
|
val image = try {
|
||||||
|
images[group.id]!!.get()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// no image or image failed to download
|
||||||
|
null
|
||||||
|
}
|
||||||
|
DefaultGroup(group.id, group.name, image)
|
||||||
|
}
|
||||||
|
}.success { new ->
|
||||||
defaultRooms.tryEmit(new)
|
defaultRooms.tryEmit(new)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user