mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-27 16:10:45 +00:00
Merge pull request #112 from loki-project/open-group-syncing
Open group syncing
This commit is contained in:
commit
0ebd29e4e5
@ -105,7 +105,7 @@ public class Address implements Parcelable, Comparable<Address> {
|
|||||||
|
|
||||||
public boolean isGroup() { return GroupUtil.isEncodedGroup(address); }
|
public boolean isGroup() { return GroupUtil.isEncodedGroup(address); }
|
||||||
|
|
||||||
public boolean isSignalGroup() { return !isPublicChat() && !isRSSFeed(); }
|
public boolean isSignalGroup() { return GroupUtil.isSignalGroup(address); }
|
||||||
|
|
||||||
public boolean isPublicChat() { return GroupUtil.isPublicChat(address); }
|
public boolean isPublicChat() { return GroupUtil.isPublicChat(address); }
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob;
|
|||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
||||||
|
import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob;
|
||||||
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
||||||
import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment;
|
import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment;
|
||||||
import org.thoughtcrime.securesms.push.MessageSenderEventListener;
|
import org.thoughtcrime.securesms.push.MessageSenderEventListener;
|
||||||
@ -111,7 +112,8 @@ import network.loki.messenger.BuildConfig;
|
|||||||
MultiDeviceStickerPackOperationJob.class,
|
MultiDeviceStickerPackOperationJob.class,
|
||||||
MultiDeviceStickerPackSyncJob.class,
|
MultiDeviceStickerPackSyncJob.class,
|
||||||
LinkPreviewRepository.class,
|
LinkPreviewRepository.class,
|
||||||
PushMessageSyncSendJob.class})
|
PushMessageSyncSendJob.class,
|
||||||
|
MultiDeviceOpenGroupUpdateJob.class})
|
||||||
|
|
||||||
public class SignalCommunicationModule {
|
public class SignalCommunicationModule {
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver;
|
|||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver;
|
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver;
|
||||||
|
import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob;
|
||||||
import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob;
|
import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob;
|
||||||
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
||||||
|
|
||||||
@ -73,6 +74,7 @@ public final class JobManagerFactories {
|
|||||||
put(UpdateApkJob.KEY, new UpdateApkJob.Factory());
|
put(UpdateApkJob.KEY, new UpdateApkJob.Factory());
|
||||||
put(PushMessageSyncSendJob.KEY, new PushMessageSyncSendJob.Factory());
|
put(PushMessageSyncSendJob.KEY, new PushMessageSyncSendJob.Factory());
|
||||||
put(PushBackgroundMessageSendJob.KEY, new PushBackgroundMessageSendJob.Factory());
|
put(PushBackgroundMessageSendJob.KEY, new PushBackgroundMessageSendJob.Factory());
|
||||||
|
put(MultiDeviceOpenGroupUpdateJob.KEY, new MultiDeviceOpenGroupUpdateJob.Factory());
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
|||||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||||
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
||||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
@ -72,6 +73,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
|
|||||||
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
||||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
||||||
|
import org.thoughtcrime.securesms.loki.redesign.utilities.OpenGroupUtilities;
|
||||||
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
|
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
|
||||||
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
|
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
|
||||||
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
|
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
|
||||||
@ -138,6 +140,7 @@ import org.whispersystems.signalservice.loki.api.DeviceLink;
|
|||||||
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities;
|
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiPublicChat;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiFileServerAPI;
|
import org.whispersystems.signalservice.loki.api.LokiFileServerAPI;
|
||||||
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||||
@ -394,6 +397,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
|
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
|
||||||
else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().get());
|
else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().get());
|
||||||
else if (syncMessage.getGroups().isPresent()) handleGroupSyncMessage(content, syncMessage.getGroups().get());
|
else if (syncMessage.getGroups().isPresent()) handleGroupSyncMessage(content, syncMessage.getGroups().get());
|
||||||
|
else if (syncMessage.getOpenGroups().isPresent()) handleOpenGroupSyncMessage(syncMessage.getOpenGroups().get());
|
||||||
else Log.w(TAG, "Contains no known sync types...");
|
else Log.w(TAG, "Contains no known sync types...");
|
||||||
} else if (content.getCallMessage().isPresent()) {
|
} else if (content.getCallMessage().isPresent()) {
|
||||||
Log.i(TAG, "Got call message...");
|
Log.i(TAG, "Got call message...");
|
||||||
@ -751,6 +755,24 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleOpenGroupSyncMessage(@NonNull List<LokiPublicChat> openGroups) {
|
||||||
|
try {
|
||||||
|
for (LokiPublicChat openGroup : openGroups) {
|
||||||
|
long threadID = GroupManager.getPublicChatThreadId(openGroup.getId(), context);
|
||||||
|
if (threadID > -1) continue;
|
||||||
|
|
||||||
|
String url = openGroup.getServer();
|
||||||
|
long channel = openGroup.getChannel();
|
||||||
|
OpenGroupUtilities.addGroup(context, url, channel).fail(e -> {
|
||||||
|
Log.d("Loki", "Failed to sync open group: " + url + " due to error: " + e + ".");
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d("Loki", "Failed to sync open groups due to error: " + e + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content,
|
private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content,
|
||||||
@NonNull SentTranscriptMessage message)
|
@NonNull SentTranscriptMessage message)
|
||||||
throws StorageFailedException
|
throws StorageFailedException
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.dependencies.InjectableType
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupManager
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.Data
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.Job
|
||||||
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||||
|
import org.thoughtcrime.securesms.jobs.BaseJob
|
||||||
|
import org.thoughtcrime.securesms.logging.Log
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender
|
||||||
|
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiPublicChat
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val KEY = "MultiDeviceGroupUpdateJob"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var messageSender: SignalServiceMessageSender
|
||||||
|
|
||||||
|
constructor() : this(Parameters.Builder()
|
||||||
|
.addConstraint(NetworkConstraint.KEY)
|
||||||
|
.setQueue("MultiDeviceGroupUpdateJob")
|
||||||
|
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||||
|
.setMaxAttempts(Parameters.UNLIMITED)
|
||||||
|
.build())
|
||||||
|
|
||||||
|
override fun getFactoryKey(): String { return KEY }
|
||||||
|
|
||||||
|
override fun serialize(): Data { return Data.EMPTY }
|
||||||
|
|
||||||
|
@Throws(Exception::class)
|
||||||
|
public override fun onRun() {
|
||||||
|
if (!TextSecurePreferences.isMultiDevice(context)) {
|
||||||
|
Log.d("Loki", "Not multi device; aborting...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val openGroups = mutableListOf<LokiPublicChat>()
|
||||||
|
DatabaseFactory.getGroupDatabase(context).groups.use { reader ->
|
||||||
|
while (true) {
|
||||||
|
val record = reader.next ?: return@use
|
||||||
|
if (!record.isPublicChat) { continue; }
|
||||||
|
|
||||||
|
val threadID = GroupManager.getThreadIdFromGroupId(record.encodedId, context)
|
||||||
|
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID)
|
||||||
|
if (openGroup != null) {
|
||||||
|
openGroups.add(openGroup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openGroups.size > 0) {
|
||||||
|
messageSender.sendMessage(0, SignalServiceSyncMessage.forOpenGroups(openGroups),
|
||||||
|
UnidentifiedAccessUtil.getAccessForSync(context))
|
||||||
|
} else {
|
||||||
|
Log.d("Loki", "No open groups to sync.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun onShouldRetry(exception: Exception): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCanceled() { }
|
||||||
|
|
||||||
|
class Factory : Job.Factory<MultiDeviceOpenGroupUpdateJob> {
|
||||||
|
|
||||||
|
override fun create(parameters: Parameters, data: Data): MultiDeviceOpenGroupUpdateJob {
|
||||||
|
return MultiDeviceOpenGroupUpdateJob(parameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -194,7 +194,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
|
|
||||||
private fun openConversation(thread: ThreadRecord) {
|
private fun openConversation(thread: ThreadRecord) {
|
||||||
val intent = Intent(this, ConversationActivity::class.java)
|
val intent = Intent(this, ConversationActivity::class.java)
|
||||||
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, thread.recipient.getAddress())
|
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, thread.recipient.address)
|
||||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, thread.threadId)
|
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, thread.threadId)
|
||||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, thread.distributionType)
|
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, thread.distributionType)
|
||||||
intent.putExtra(ConversationActivity.TIMING_EXTRA, System.currentTimeMillis())
|
intent.putExtra(ConversationActivity.TIMING_EXTRA, System.currentTimeMillis())
|
||||||
@ -255,9 +255,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
val dialog = AlertDialog.Builder(activity)
|
val dialog = AlertDialog.Builder(activity)
|
||||||
dialog.setMessage(dialogMessage)
|
dialog.setMessage(dialogMessage)
|
||||||
dialog.setPositiveButton(R.string.yes) { _, _ ->
|
dialog.setPositiveButton(R.string.yes) { _, _ ->
|
||||||
val isGroup = recipient.isGroupRecipient
|
val isClosedGroup = recipient.address.isSignalGroup
|
||||||
// Send a leave group message if this is an active closed group
|
// Send a leave group message if this is an active closed group
|
||||||
if (isGroup && DatabaseFactory.getGroupDatabase(activity).isActive(recipient.address.toGroupString())) {
|
if (isClosedGroup && DatabaseFactory.getGroupDatabase(activity).isActive(recipient.address.toGroupString())) {
|
||||||
if (!GroupUtil.leaveGroup(activity, recipient)) {
|
if (!GroupUtil.leaveGroup(activity, recipient)) {
|
||||||
Toast.makeText(activity, "Couldn't leave group", Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, "Couldn't leave group", Toast.LENGTH_LONG).show()
|
||||||
clearView(activity.recyclerView, viewHolder)
|
clearView(activity.recyclerView, viewHolder)
|
||||||
@ -267,10 +267,11 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
// Archive the conversation and then delete it after 10 seconds (the case where the
|
// Archive the conversation and then delete it after 10 seconds (the case where the
|
||||||
// app was closed before the conversation could be deleted is handled in onCreate)
|
// app was closed before the conversation could be deleted is handled in onCreate)
|
||||||
threadDatabase.archiveConversation(threadID)
|
threadDatabase.archiveConversation(threadID)
|
||||||
|
val delay = if (isClosedGroup) 10000L else 1000L
|
||||||
val handler = Handler()
|
val handler = Handler()
|
||||||
handler.postDelayed(deleteThread, 10000)
|
handler.postDelayed(deleteThread, delay)
|
||||||
// Notify the user
|
// Notify the user
|
||||||
val toastMessage = if (isGroup) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message
|
val toastMessage = if (recipient.isGroupRecipient) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message
|
||||||
Toast.makeText(activity, toastMessage, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, toastMessage, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
dialog.setNegativeButton(R.string.no) { _, _ ->
|
dialog.setNegativeButton(R.string.no) { _, _ ->
|
||||||
|
@ -16,14 +16,12 @@ import kotlinx.android.synthetic.main.fragment_enter_chat_url.*
|
|||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import nl.komponents.kovenant.ui.failUi
|
import nl.komponents.kovenant.ui.failUi
|
||||||
import nl.komponents.kovenant.ui.successUi
|
import nl.komponents.kovenant.ui.successUi
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
import org.thoughtcrime.securesms.loki.redesign.utilities.OpenGroupUtilities
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
|
||||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
|
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
|
||||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
|
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.sms.MessageSender
|
||||||
|
|
||||||
class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
|
class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
|
||||||
private val adapter = JoinPublicChatActivityAdapter(this)
|
private val adapter = JoinPublicChatActivityAdapter(this)
|
||||||
@ -68,19 +66,11 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode
|
|||||||
return Toast.makeText(this, "Invalid URL", Toast.LENGTH_SHORT).show()
|
return Toast.makeText(this, "Invalid URL", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
showLoader()
|
showLoader()
|
||||||
val application = ApplicationContext.getInstance(this)
|
|
||||||
val channel: Long = 1
|
val channel: Long = 1
|
||||||
val displayName = TextSecurePreferences.getProfileName(this)
|
OpenGroupUtilities.addGroup(this, url, channel).success {
|
||||||
val lokiPublicChatAPI = application.lokiPublicChatAPI!!
|
MessageSender.syncAllOpenGroups(this)
|
||||||
application.lokiPublicChatManager.addChat(url, channel).successUi {
|
}.successUi {
|
||||||
DatabaseFactory.getLokiAPIDatabase(this).removeLastMessageServerID(channel, url)
|
|
||||||
DatabaseFactory.getLokiAPIDatabase(this).removeLastDeletionServerID(channel, url)
|
|
||||||
lokiPublicChatAPI.getMessages(channel, url)
|
|
||||||
lokiPublicChatAPI.setDisplayName(displayName, url)
|
|
||||||
lokiPublicChatAPI.join(channel, url)
|
|
||||||
val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(this)
|
|
||||||
val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(this)
|
|
||||||
lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl)
|
|
||||||
finish()
|
finish()
|
||||||
}.failUi {
|
}.failUi {
|
||||||
hideLoader()
|
hideLoader()
|
||||||
|
@ -154,6 +154,7 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager
|
|||||||
Timer().schedule(4000) {
|
Timer().schedule(4000) {
|
||||||
MessageSender.syncAllGroups(this@LinkedDevicesActivity)
|
MessageSender.syncAllGroups(this@LinkedDevicesActivity)
|
||||||
MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey))
|
MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey))
|
||||||
|
MessageSender.syncAllOpenGroups(this@LinkedDevicesActivity)
|
||||||
}
|
}
|
||||||
}.fail {
|
}.fail {
|
||||||
LokiFileServerAPI.shared.removeDeviceLink(deviceLink) // If this fails we have a problem
|
LokiFileServerAPI.shared.removeDeviceLink(deviceLink) // If this fails we have a problem
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.redesign.utilities
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import nl.komponents.kovenant.Promise
|
||||||
|
import nl.komponents.kovenant.then
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
|
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupManager
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiPublicChat
|
||||||
|
|
||||||
|
object OpenGroupUtilities {
|
||||||
|
|
||||||
|
@JvmStatic fun addGroup(context: Context, url: String, channel: Long): Promise<LokiPublicChat, Exception> {
|
||||||
|
// Check for an existing group
|
||||||
|
val groupID = LokiPublicChat.getId(channel, url)
|
||||||
|
val threadID = GroupManager.getPublicChatThreadId(groupID, context)
|
||||||
|
val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID)
|
||||||
|
if (openGroup != null) { return Promise.of(openGroup) }
|
||||||
|
// Add the new group
|
||||||
|
val application = ApplicationContext.getInstance(context)
|
||||||
|
val displayName = TextSecurePreferences.getProfileName(context)
|
||||||
|
val lokiPublicChatAPI = application.lokiPublicChatAPI ?: throw Error("LokiPublicChatAPI is not initialized.")
|
||||||
|
return application.lokiPublicChatManager.addChat(url, channel).then { group ->
|
||||||
|
DatabaseFactory.getLokiAPIDatabase(context).removeLastMessageServerID(channel, url)
|
||||||
|
DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(channel, url)
|
||||||
|
lokiPublicChatAPI.getMessages(channel, url)
|
||||||
|
lokiPublicChatAPI.setDisplayName(displayName, url)
|
||||||
|
lokiPublicChatAPI.join(channel, url)
|
||||||
|
val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(context)
|
||||||
|
val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(context)
|
||||||
|
lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl)
|
||||||
|
group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||||||
import org.thoughtcrime.securesms.loki.BackgroundMessage;
|
import org.thoughtcrime.securesms.loki.BackgroundMessage;
|
||||||
import org.thoughtcrime.securesms.loki.FriendRequestHandler;
|
import org.thoughtcrime.securesms.loki.FriendRequestHandler;
|
||||||
import org.thoughtcrime.securesms.loki.GeneralUtilitiesKt;
|
import org.thoughtcrime.securesms.loki.GeneralUtilitiesKt;
|
||||||
|
import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob;
|
||||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
||||||
import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob;
|
import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob;
|
||||||
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
||||||
@ -86,6 +87,10 @@ public class MessageSender {
|
|||||||
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceGroupUpdateJob());
|
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceGroupUpdateJob());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void syncAllOpenGroups(Context context) {
|
||||||
|
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceOpenGroupUpdateJob());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a contact sync message to all our devices telling them that we want to sync `contact`
|
* Send a contact sync message to all our devices telling them that we want to sync `contact`
|
||||||
*/
|
*/
|
||||||
|
@ -4,15 +4,13 @@ import android.content.Context;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.WorkerThread;
|
import android.support.annotation.WorkerThread;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase.*;
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
@ -26,6 +24,8 @@ import java.util.Collections;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||||
|
|
||||||
public class GroupUtil {
|
public class GroupUtil {
|
||||||
@ -87,6 +87,10 @@ public class GroupUtil {
|
|||||||
return groupId.startsWith(ENCODED_RSS_FEED_GROUP_PREFIX);
|
return groupId.startsWith(ENCODED_RSS_FEED_GROUP_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSignalGroup(@NonNull String groupId) {
|
||||||
|
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public static Optional<OutgoingGroupMediaMessage> createGroupLeaveMessage(@NonNull Context context, @NonNull Recipient groupRecipient) {
|
public static Optional<OutgoingGroupMediaMessage> createGroupLeaveMessage(@NonNull Context context, @NonNull Recipient groupRecipient) {
|
||||||
String encodedGroupId = groupRecipient.getAddress().toGroupString();
|
String encodedGroupId = groupRecipient.getAddress().toGroupString();
|
||||||
@ -114,6 +118,8 @@ public class GroupUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean leaveGroup(@NonNull Context context, Recipient groupRecipient) {
|
public static boolean leaveGroup(@NonNull Context context, Recipient groupRecipient) {
|
||||||
|
if (!groupRecipient.getAddress().isSignalGroup()) { return true; }
|
||||||
|
|
||||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
|
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
|
||||||
Optional<OutgoingGroupMediaMessage> leaveMessage = GroupUtil.createGroupLeaveMessage(context, groupRecipient);
|
Optional<OutgoingGroupMediaMessage> leaveMessage = GroupUtil.createGroupLeaveMessage(context, groupRecipient);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user