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