mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-21 10:41:31 +00:00
Thread deletion cleanup.
This commit is contained in:
parent
4307140e5c
commit
0ebb382edd
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.groups;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
@ -23,7 +24,6 @@ import org.thoughtcrime.securesms.util.BitmapUtil;
|
|||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import android.database.Cursor
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
@ -18,11 +17,15 @@ import android.view.View
|
|||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.loader.app.LoaderManager
|
import androidx.loader.app.LoaderManager
|
||||||
import androidx.loader.content.Loader
|
import androidx.loader.content.Loader
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
@ -71,24 +74,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||||
super.onCreate(savedInstanceState, isReady)
|
super.onCreate(savedInstanceState, isReady)
|
||||||
// Process any outstanding deletes
|
|
||||||
val threadDatabase = DatabaseFactory.getThreadDatabase(this)
|
|
||||||
val archivedConversationCount = threadDatabase.archivedConversationListCount
|
|
||||||
if (archivedConversationCount > 0) {
|
|
||||||
val archivedConversations = threadDatabase.archivedConversationList
|
|
||||||
archivedConversations.moveToFirst()
|
|
||||||
fun deleteThreadAtCurrentPosition() {
|
|
||||||
val threadID = archivedConversations.getLong(archivedConversations.getColumnIndex(ThreadDatabase.ID))
|
|
||||||
AsyncTask.execute {
|
|
||||||
threadDatabase.deleteConversation(threadID)
|
|
||||||
(applicationContext as ApplicationContext).messageNotifier.updateNotification(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deleteThreadAtCurrentPosition()
|
|
||||||
while (archivedConversations.moveToNext()) {
|
|
||||||
deleteThreadAtCurrentPosition()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Double check that the long poller is up
|
// Double check that the long poller is up
|
||||||
(applicationContext as ApplicationContext).startPollingIfNeeded()
|
(applicationContext as ApplicationContext).startPollingIfNeeded()
|
||||||
// Set content view
|
// Set content view
|
||||||
@ -341,58 +326,56 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
|||||||
val threadID = thread.threadId
|
val threadID = thread.threadId
|
||||||
val recipient = thread.recipient
|
val recipient = thread.recipient
|
||||||
val threadDB = DatabaseFactory.getThreadDatabase(this)
|
val threadDB = DatabaseFactory.getThreadDatabase(this)
|
||||||
val deleteThread = Runnable {
|
|
||||||
//TODO Move open group related logic to OpenGroupUtilities / PublicChatManager / GroupManager
|
|
||||||
AsyncTask.execute {
|
|
||||||
val publicChat = DatabaseFactory.getLokiThreadDatabase(this@HomeActivity).getPublicChat(threadID)
|
|
||||||
if (publicChat != null) {
|
|
||||||
val apiDB = DatabaseFactory.getLokiAPIDatabase(this@HomeActivity)
|
|
||||||
apiDB.removeLastMessageServerID(publicChat.channel, publicChat.server)
|
|
||||||
apiDB.removeLastDeletionServerID(publicChat.channel, publicChat.server)
|
|
||||||
apiDB.clearOpenGroupProfilePictureURL(publicChat.channel, publicChat.server)
|
|
||||||
ApplicationContext.getInstance(this@HomeActivity).publicChatAPI!!.leave(publicChat.channel, publicChat.server)
|
|
||||||
|
|
||||||
//FIXME Group deletion should be synchronized with the related thread deletion.
|
|
||||||
val groupId = threadDB.getRecipientForThreadId(threadID)!!.address.serialize()
|
|
||||||
GroupManager.deleteGroup(groupId, this@HomeActivity)
|
|
||||||
}
|
|
||||||
threadDB.deleteConversation(threadID)
|
|
||||||
ApplicationContext.getInstance(this@HomeActivity).messageNotifier.updateNotification(this@HomeActivity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val dialogMessage = if (recipient.isGroupRecipient) R.string.activity_home_leave_group_dialog_message else R.string.activity_home_delete_conversation_dialog_message
|
val dialogMessage = if (recipient.isGroupRecipient) R.string.activity_home_leave_group_dialog_message else R.string.activity_home_delete_conversation_dialog_message
|
||||||
val dialog = AlertDialog.Builder(this)
|
val dialog = AlertDialog.Builder(this)
|
||||||
dialog.setMessage(dialogMessage)
|
dialog.setMessage(dialogMessage)
|
||||||
dialog.setPositiveButton(R.string.yes) { _, _ ->
|
dialog.setPositiveButton(R.string.yes) { _, _ -> lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
val context = this@HomeActivity as Context
|
||||||
|
|
||||||
val isClosedGroup = recipient.address.isClosedGroup
|
val isClosedGroup = recipient.address.isClosedGroup
|
||||||
// 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 (isClosedGroup && DatabaseFactory.getGroupDatabase(this).isActive(recipient.address.toGroupString())) {
|
if (isClosedGroup && DatabaseFactory.getGroupDatabase(context).isActive(recipient.address.toGroupString())) {
|
||||||
var isSSKBasedClosedGroup: Boolean
|
var isSSKBasedClosedGroup: Boolean
|
||||||
var groupPublicKey: String?
|
var groupPublicKey: String?
|
||||||
try {
|
try {
|
||||||
groupPublicKey = ClosedGroupsProtocol.doubleDecodeGroupID(recipient.address.toString()).toHexString()
|
groupPublicKey = ClosedGroupsProtocol.doubleDecodeGroupID(recipient.address.toString()).toHexString()
|
||||||
isSSKBasedClosedGroup = DatabaseFactory.getSSKDatabase(this).isSSKBasedClosedGroup(groupPublicKey)
|
isSSKBasedClosedGroup = DatabaseFactory.getSSKDatabase(context).isSSKBasedClosedGroup(groupPublicKey)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
groupPublicKey = null
|
groupPublicKey = null
|
||||||
isSSKBasedClosedGroup = false
|
isSSKBasedClosedGroup = false
|
||||||
}
|
}
|
||||||
if (isSSKBasedClosedGroup) {
|
if (isSSKBasedClosedGroup) {
|
||||||
ClosedGroupsProtocol.leave(this, groupPublicKey!!)
|
ClosedGroupsProtocol.leave(context, groupPublicKey!!)
|
||||||
} else if (!ClosedGroupsProtocol.leaveLegacyGroup(this, recipient)) {
|
} else if (!ClosedGroupsProtocol.leaveLegacyGroup(context, recipient)) {
|
||||||
Toast.makeText(this, R.string.activity_home_leaving_group_failed_message, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.activity_home_leaving_group_failed_message, Toast.LENGTH_LONG).show()
|
||||||
return@setPositiveButton
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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)
|
withContext(Dispatchers.IO) {
|
||||||
threadDB.archiveConversation(threadID)
|
val publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID)
|
||||||
val delay = if (isClosedGroup) 10000L else 1000L
|
//TODO Move open group related logic to OpenGroupUtilities / PublicChatManager / GroupManager
|
||||||
val handler = Handler()
|
if (publicChat != null) {
|
||||||
handler.postDelayed(deleteThread, delay)
|
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
||||||
|
apiDB.removeLastMessageServerID(publicChat.channel, publicChat.server)
|
||||||
|
apiDB.removeLastDeletionServerID(publicChat.channel, publicChat.server)
|
||||||
|
apiDB.clearOpenGroupProfilePictureURL(publicChat.channel, publicChat.server)
|
||||||
|
|
||||||
|
ApplicationContext.getInstance(context).publicChatAPI!!
|
||||||
|
.leave(publicChat.channel, publicChat.server)
|
||||||
|
|
||||||
|
ApplicationContext.getInstance(context).publicChatManager
|
||||||
|
.removeChat(publicChat.server, publicChat.channel)
|
||||||
|
} else {
|
||||||
|
threadDB.deleteConversation(threadID)
|
||||||
|
}
|
||||||
|
ApplicationContext.getInstance(context).messageNotifier.updateNotification(context)
|
||||||
|
}
|
||||||
|
|
||||||
// Notify the user
|
// Notify the user
|
||||||
val toastMessage = if (recipient.isGroupRecipient) 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(this, toastMessage, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show()
|
||||||
}
|
}}
|
||||||
dialog.setNegativeButton(R.string.no) { _, _ ->
|
dialog.setNegativeButton(R.string.no) { _, _ ->
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,6 @@ import android.database.ContentObserver
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import nl.komponents.kovenant.Promise
|
|
||||||
import nl.komponents.kovenant.functional.bind
|
|
||||||
import nl.komponents.kovenant.functional.map
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.database.DatabaseContentProviders
|
import org.thoughtcrime.securesms.database.DatabaseContentProviders
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
@ -101,6 +98,16 @@ class PublicChatManager(private val context: Context) {
|
|||||||
return chat
|
return chat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun removeChat(server: String, channel: Long) {
|
||||||
|
val threadDB = DatabaseFactory.getThreadDatabase(context)
|
||||||
|
val groupId = PublicChat.getId(channel, server)
|
||||||
|
val threadId = GroupManager.getOpenGroupThreadID(groupId, context)
|
||||||
|
val groupAddress = threadDB.getRecipientForThreadId(threadId)!!.address.serialize()
|
||||||
|
GroupManager.deleteGroup(groupAddress, context)
|
||||||
|
|
||||||
|
Util.runOnMain { startPollersIfNeeded() }
|
||||||
|
}
|
||||||
|
|
||||||
private fun refreshChatsAndPollers() {
|
private fun refreshChatsAndPollers() {
|
||||||
val chatsInDB = DatabaseFactory.getLokiThreadDatabase(context).getAllPublicChats()
|
val chatsInDB = DatabaseFactory.getLokiThreadDatabase(context).getAllPublicChats()
|
||||||
val removedChatThreadIds = chats.keys.filter { !chatsInDB.keys.contains(it) }
|
val removedChatThreadIds = chats.keys.filter { !chatsInDB.keys.contains(it) }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user