remove withNullableControllerViewBinding

it seems async calls are not cancelled reliable so it was decided to always check for null bindings to avoid NPEs

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-01-16 15:11:58 +01:00
parent 4124a65c7a
commit b45794b0ca
No known key found for this signature in database
GPG key ID: C793F8B59F43CE7B
4 changed files with 27 additions and 79 deletions

View file

@ -419,10 +419,8 @@ class ChatController(args: Bundle) :
} }
) )
withNullableControllerViewBinding { val itemTouchHelper = ItemTouchHelper(messageSwipeController)
val itemTouchHelper = ItemTouchHelper(messageSwipeController) itemTouchHelper.attachToRecyclerView(binding?.messagesListView)
itemTouchHelper.attachToRecyclerView(binding?.messagesListView)
}
} }
} }

View file

@ -452,22 +452,16 @@ class ContactsController(args: Bundle) :
adapter?.filterItems() adapter?.filterItems()
} }
withNullableControllerViewBinding { binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
}
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
withNullableControllerViewBinding { binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
}
dispose(contactsQueryDisposable) dispose(contactsQueryDisposable)
} }
override fun onComplete() { override fun onComplete() {
withNullableControllerViewBinding { binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
}
dispose(contactsQueryDisposable) dispose(contactsQueryDisposable)
alreadyFetching = false alreadyFetching = false
disengageProgressBar() disengageProgressBar()
@ -699,9 +693,7 @@ class ContactsController(args: Bundle) :
adapter?.updateDataSet(contactItems as List<Nothing>?) adapter?.updateDataSet(contactItems as List<Nothing>?)
} }
withNullableControllerViewBinding { binding?.controllerGenericRv?.swipeRefreshLayout?.isEnabled = !adapter!!.hasFilter()
binding?.controllerGenericRv?.swipeRefreshLayout?.isEnabled = !adapter!!.hasFilter()
}
return true return true
} }
@ -929,25 +921,21 @@ class ContactsController(args: Bundle) :
} }
private fun toggleConversationPrivacyLayout(showInitialLayout: Boolean) { private fun toggleConversationPrivacyLayout(showInitialLayout: Boolean) {
withNullableControllerViewBinding { if (showInitialLayout) {
if (showInitialLayout) { binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.VISIBLE
binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.VISIBLE binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.GONE
binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.GONE } else {
} else { binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.GONE
binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.GONE binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.VISIBLE
binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.VISIBLE
}
} }
} }
private fun toggleConversationViaLinkVisibility(isPublicCall: Boolean) { private fun toggleConversationViaLinkVisibility(isPublicCall: Boolean) {
withNullableControllerViewBinding { if (isPublicCall) {
if (isPublicCall) { binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.GONE
binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.GONE updateGroupParticipantSelection()
updateGroupParticipantSelection() } else {
} else { binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.VISIBLE
binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.VISIBLE
}
} }
} }

View file

@ -409,9 +409,7 @@ class ConversationsListController(bundle: Bundle) :
adapter!!.setHeadersShown(true) adapter!!.setHeadersShown(true)
adapter!!.updateDataSet(searchableConversationItems, false) adapter!!.updateDataSet(searchableConversationItems, false)
adapter!!.showAllHeaders() adapter!!.showAllHeaders()
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isEnabled = false
binding?.swipeRefreshLayoutView?.isEnabled = false
}
return true return true
} }
@ -424,9 +422,7 @@ class ConversationsListController(bundle: Bundle) :
searchHelper!!.cancelSearch() searchHelper!!.cancelSearch()
binding?.swipeRefreshLayoutView?.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
} }
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isEnabled = true
binding?.swipeRefreshLayoutView?.isEnabled = true
}
searchView!!.onActionViewCollapsed() searchView!!.onActionViewCollapsed()
val mainActivity = getActivity() as MainActivity? val mainActivity = getActivity() as MainActivity?
if (mainActivity != null) { if (mainActivity != null) {
@ -514,21 +510,15 @@ class ConversationsListController(bundle: Bundle) :
adapter!!.updateDataSet(conversationItems, false) adapter!!.updateDataSet(conversationItems, false)
Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong()) Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong())
fetchOpenConversations(apiVersion) fetchOpenConversations(apiVersion)
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = false
binding?.swipeRefreshLayoutView?.isRefreshing = false
}
}, { throwable: Throwable -> }, { throwable: Throwable ->
handleHttpExceptions(throwable) handleHttpExceptions(throwable)
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = false
binding?.swipeRefreshLayoutView?.isRefreshing = false showErrorDialog()
showErrorDialog()
}
dispose(roomsQueryDisposable) dispose(roomsQueryDisposable)
}) { }) {
dispose(roomsQueryDisposable) dispose(roomsQueryDisposable)
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = false
binding?.swipeRefreshLayoutView?.isRefreshing = false
}
isRefreshing = false isRefreshing = false
} }
} }
@ -854,9 +844,7 @@ class ConversationsListController(bundle: Bundle) :
@SuppressLint("CheckResult") // handled by helper @SuppressLint("CheckResult") // handled by helper
private fun startMessageSearch(search: String?) { private fun startMessageSearch(search: String?) {
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = true
binding?.swipeRefreshLayoutView?.isRefreshing = true
}
searchHelper?.startMessageSearch(search!!) searchHelper?.startMessageSearch(search!!)
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
@ -1331,17 +1319,13 @@ class ConversationsListController(bundle: Bundle) :
binding?.recyclerView?.scrollToPosition(0) binding?.recyclerView?.scrollToPosition(0)
} }
} }
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = false
binding?.swipeRefreshLayoutView?.isRefreshing = false
}
} }
private fun onMessageSearchError(throwable: Throwable) { private fun onMessageSearchError(throwable: Throwable) {
handleHttpExceptions(throwable) handleHttpExceptions(throwable)
withNullableControllerViewBinding { binding?.swipeRefreshLayoutView?.isRefreshing = false
binding?.swipeRefreshLayoutView?.isRefreshing = false showErrorDialog()
showErrorDialog()
}
} }
companion object { companion object {

View file

@ -54,7 +54,6 @@ import com.nextcloud.talk.controllers.ServerSelectionController
import com.nextcloud.talk.controllers.SwitchAccountController import com.nextcloud.talk.controllers.SwitchAccountController
import com.nextcloud.talk.controllers.WebViewLoginController import com.nextcloud.talk.controllers.WebViewLoginController
import com.nextcloud.talk.controllers.base.providers.ActionBarProvider import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
import com.nextcloud.talk.controllers.util.ControllerViewBindingDelegate
import com.nextcloud.talk.databinding.ActivityMainBinding import com.nextcloud.talk.databinding.ActivityMainBinding
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
@ -304,27 +303,6 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
} }
} }
/**
* Mainly intended to be used in async listeners that may be called after the controller has been destroyed.
*
* If you need to use this function to patch a NPE crash, something is wrong in the way that the async calls are
* handled, they should have been cancelled when the controller UI was destroyed (if their only purpose was
* updating UI).
*/
@Suppress("Detekt.TooGenericExceptionCaught")
inline fun withNullableControllerViewBinding(block: () -> Unit) {
try {
block()
} catch (e: NullPointerException) {
// Handle only the exceptions we know about, let everything else pass through
if (e.stackTrace.firstOrNull()?.className == ControllerViewBindingDelegate::class.qualifiedName) {
Log.w("ControllerViewBinding", "Trying to update UI on a null ViewBinding.", e)
} else {
throw e
}
}
}
open val appBarLayoutType: AppBarLayoutType open val appBarLayoutType: AppBarLayoutType
get() = AppBarLayoutType.TOOLBAR get() = AppBarLayoutType.TOOLBAR
val searchHint: String val searchHint: String