diff --git a/app/src/main/java/com/github/gotify/messages/MessagesActivity.kt b/app/src/main/java/com/github/gotify/messages/MessagesActivity.kt index 2c3df95..c035c24 100644 --- a/app/src/main/java/com/github/gotify/messages/MessagesActivity.kt +++ b/app/src/main/java/com/github/gotify/messages/MessagesActivity.kt @@ -6,7 +6,6 @@ import android.graphics.Canvas import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.net.Uri -import android.os.AsyncTask import android.os.Bundle import android.view.Menu import android.view.MenuItem @@ -31,6 +30,7 @@ import com.github.gotify.BuildConfig import com.github.gotify.MissedMessageUtil import com.github.gotify.R import com.github.gotify.Utils +import com.github.gotify.Utils.launchCoroutine import com.github.gotify.api.Api import com.github.gotify.api.ApiException import com.github.gotify.api.Callback @@ -56,6 +56,8 @@ import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.BaseTransientBottomBar.BaseCallback import com.google.android.material.snackbar.Snackbar import java.io.IOException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext internal class MessagesActivity : AppCompatActivity(), @@ -74,7 +76,9 @@ internal class MessagesActivity : messageJson, Message::class.java ) - NewSingleMessage().execute(message) + launchCoroutine { + addSingleMessage(message) + } } } @@ -126,8 +130,10 @@ internal class MessagesActivity : override fun onDrawerClosed(drawerView: View) { if (updateAppOnDrawerClose != null) { viewModel.appId = updateAppOnDrawerClose!! - UpdateMessagesForApplication(true).execute(updateAppOnDrawerClose) - updateAppOnDrawerClose = null + launchCoroutine { + updateMessagesForApplication(true, updateAppOnDrawerClose!!) + updateAppOnDrawerClose = null + } invalidateOptionsMenu() } } @@ -143,7 +149,9 @@ internal class MessagesActivity : swipeRefreshLayout.isEnabled = true } } - UpdateMessagesForApplication(true).execute(viewModel.appId) + launchCoroutine { + updateMessagesForApplication(true, viewModel.appId) + } } override fun onPostCreate(savedInstanceState: Bundle?) { @@ -167,7 +175,9 @@ internal class MessagesActivity : private fun onRefresh() { viewModel.messages.clear() - LoadMore().execute(viewModel.appId) + launchCoroutine { + loadMore(viewModel.appId) + } } private fun openDocumentation() { @@ -175,10 +185,6 @@ internal class MessagesActivity : startActivity(browserIntent) } - fun commitDelete() { - CommitDeleteMessage().execute() - } - private fun onUpdateApps(applications: List) { val menu: Menu = binding.navView.menu menu.removeGroup(R.id.apps) @@ -283,7 +289,9 @@ internal class MessagesActivity : private fun doLogout() { setContentView(R.layout.splash) - DeleteClientAndNavigateToLogin().execute() + launchCoroutine { + deleteClientAndNavigateToLogin() + } } private fun startLoading() { @@ -303,7 +311,9 @@ internal class MessagesActivity : val filter = IntentFilter() filter.addAction(NEW_MESSAGE_BROADCAST) registerReceiver(receiver, filter) - UpdateMissedMessages().execute(viewModel.messages.getLastReceivedMessage()) + launchCoroutine { + updateMissedMessages(viewModel.messages.getLastReceivedMessage()) + } var selectedIndex: Int = R.id.nav_all_messages val appId = viewModel.appId if (appId != MessageState.ALL_MESSAGES) { @@ -372,7 +382,9 @@ internal class MessagesActivity : // deletion to be sent to the server twice, since the deletion is sent to the server // in MessageFacade if a message is deleted while another message was already // waiting for deletion. - commitDelete() + launchCoroutine { + commitDeleteMessage() + } } } } @@ -474,32 +486,24 @@ internal class MessagesActivity : ) { if (!isLoadMore) { isLoadMore = true - LoadMore().execute(viewModel.appId) + launchCoroutine { + loadMore(viewModel.appId) + } } } } } } - private inner class UpdateMissedMessages : AsyncTask() { - override fun doInBackground(vararg ids: Long?): Boolean { - val id = ids.first()!! - if (id == -1L) { - return false - } - val newMessages = MissedMessageUtil( - viewModel.client.createService( - MessageApi::class.java - ) - ).missingMessages(id).filterNotNull() - viewModel.messages.addMessages(newMessages) - return newMessages.isNotEmpty() - } + private suspend fun updateMissedMessages(id: Long) { + if (id == -1L) return - override fun onPostExecute(update: Boolean) { - if (update) { - UpdateMessagesForApplication(true).execute(viewModel.appId) - } + val newMessages = MissedMessageUtil(viewModel.client.createService(MessageApi::class.java)) + .missingMessages(id).filterNotNull() + viewModel.messages.addMessages(newMessages) + + if (newMessages.isNotEmpty()) { + updateMessagesForApplication(true, viewModel.appId) } } @@ -512,7 +516,9 @@ internal class MessagesActivity : override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.action_delete_all) { - DeleteMessages().execute(viewModel.appId) + launchCoroutine { + deleteMessages(viewModel.appId) + } } if (item.itemId == R.id.action_delete_app) { val alert = android.app.AlertDialog.Builder(this) @@ -544,109 +550,74 @@ internal class MessagesActivity : }) } - private inner class LoadMore : AsyncTask>() { - override fun doInBackground(vararg appId: Long?): List { - return viewModel.messages.loadMore(appId.first()!!) - } - - override fun onPostExecute(messageWithImages: List) { - updateMessagesAndStopLoading(messageWithImages) + private suspend fun loadMore(appId: Long) { + val messagesWithImages = viewModel.messages.loadMore(appId) + withContext(Dispatchers.Main) { + updateMessagesAndStopLoading(messagesWithImages) } } - private inner class UpdateMessagesForApplication(withLoadingSpinner: Boolean) : - AsyncTask() { - init { - if (withLoadingSpinner) { + private suspend fun updateMessagesForApplication(withLoadingSpinner: Boolean, appId: Long) { + if (withLoadingSpinner) { + withContext(Dispatchers.Main) { startLoading() } } - - override fun doInBackground(vararg appIds: Long?): Long { - val appId = appIds.first()!! - viewModel.messages.loadMoreIfNotPresent(appId) - return appId - } - - override fun onPostExecute(appId: Long) { + viewModel.messages.loadMoreIfNotPresent(appId) + withContext(Dispatchers.Main) { updateMessagesAndStopLoading(viewModel.messages[appId]) } } - private inner class NewSingleMessage : AsyncTask() { - override fun doInBackground(vararg newMessages: Message?): Void? { - viewModel.messages.addMessages(listOfNotNull(*newMessages)) - return null - } - - override fun onPostExecute(data: Void?) { - UpdateMessagesForApplication(false).execute(viewModel.appId) - } + private suspend fun addSingleMessage(message: Message) { + viewModel.messages.addMessages(listOf(message)) + updateMessagesForApplication(false, viewModel.appId) } - private inner class CommitDeleteMessage : AsyncTask() { - override fun doInBackground(vararg messages: Void?): Void? { - viewModel.messages.commitDelete() - return null - } - - override fun onPostExecute(data: Void?) { - UpdateMessagesForApplication(false).execute(viewModel.appId) - } + private suspend fun commitDeleteMessage() { + viewModel.messages.commitDelete() + updateMessagesForApplication(false, viewModel.appId) } - private inner class DeleteMessages : AsyncTask() { - init { + private suspend fun deleteMessages(appId: Long) { + withContext(Dispatchers.Main) { startLoading() } - - override fun doInBackground(vararg appId: Long?): Boolean { - return viewModel.messages.deleteAll(appId.first()!!) - } - - override fun onPostExecute(success: Boolean) { - if (!success) { - Utils.showSnackBar(this@MessagesActivity, "Delete failed :(") - } - UpdateMessagesForApplication(false).execute(viewModel.appId) + val success = viewModel.messages.deleteAll(appId) + if (success) { + updateMessagesForApplication(false, viewModel.appId) + } else { + Utils.showSnackBar(this@MessagesActivity, "Delete failed :(") } } - private inner class DeleteClientAndNavigateToLogin : AsyncTask() { - override fun doInBackground(vararg ignore: Void?): Void? { - val settings = viewModel.settings - val api = ClientFactory.clientToken( - settings.url, settings.sslSettings(), settings.token - ) - .createService(ClientApi::class.java) - stopService(Intent(this@MessagesActivity, WebSocketService::class.java)) - try { - val clients = Api.execute(api.clients) ?: emptyList() - var currentClient: Client? = null - for (client in clients) { - if (client.token == settings.token) { - currentClient = client - break - } + private fun deleteClientAndNavigateToLogin() { + val settings = viewModel.settings + val api = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token) + .createService(ClientApi::class.java) + stopService(Intent(this@MessagesActivity, WebSocketService::class.java)) + try { + val clients = Api.execute(api.clients) ?: emptyList() + var currentClient: Client? = null + for (client in clients) { + if (client.token == settings.token) { + currentClient = client + break } - if (currentClient != null) { - Log.i("Delete client with id " + currentClient.id) - Api.execute(api.deleteClient(currentClient.id)) - } else { - Log.e("Could not delete client, client does not exist.") - } - } catch (e: ApiException) { - Log.e("Could not delete client", e) } - return null + if (currentClient != null) { + Log.i("Delete client with id " + currentClient.id) + Api.execute(api.deleteClient(currentClient.id)) + } else { + Log.e("Could not delete client, client does not exist.") + } + } catch (e: ApiException) { + Log.e("Could not delete client", e) } - override fun onPostExecute(aVoid: Void?) { - viewModel.settings.clear() - startActivity(Intent(this@MessagesActivity, LoginActivity::class.java)) - finish() - super.onPostExecute(aVoid) - } + viewModel.settings.clear() + startActivity(Intent(this@MessagesActivity, LoginActivity::class.java)) + finish() } private fun updateMessagesAndStopLoading(messageWithImages: List) {