diff --git a/app/src/main/java/app/pachli/MainActivity.kt b/app/src/main/java/app/pachli/MainActivity.kt index 98dfbc890..de190b0a2 100644 --- a/app/src/main/java/app/pachli/MainActivity.kt +++ b/app/src/main/java/app/pachli/MainActivity.kt @@ -181,6 +181,8 @@ import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import timber.log.Timber @AndroidEntryPoint @@ -254,6 +256,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { private var pachliAccountId by Delegates.notNull() + /** Mutex to protect modifications to the drawer's items. */ + private val drawerMutex = Mutex() + @SuppressLint("RestrictedApi") override fun onCreate(savedInstanceState: Bundle?) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { @@ -761,7 +766,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { * (because the top toolbar is hidden), false if any existing search item should be * removed. */ - private fun bindMainDrawerSearch(context: Context, pachliAccountId: Long, showSearchItem: Boolean) { + private suspend fun bindMainDrawerSearch(context: Context, pachliAccountId: Long, showSearchItem: Boolean) = drawerMutex.withLock { val searchItemPosition = binding.mainDrawer.getPosition(DRAWER_ITEM_SEARCH) val showing = searchItemPosition != -1 @@ -802,7 +807,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { * @param showSchedulePosts True if a "Scheduled posts" menu item should be added * to the list, false if any existing item should be removed. */ - private fun bindMainDrawerScheduledPosts(context: Context, pachliAccountId: Long, showSchedulePosts: Boolean) { + private suspend fun bindMainDrawerScheduledPosts(context: Context, pachliAccountId: Long, showSchedulePosts: Boolean) = drawerMutex.withLock { val existingPosition = binding.mainDrawer.getPosition(DRAWER_ITEM_SCHEDULED_POSTS) val showing = existingPosition != -1 @@ -834,7 +839,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { } /** Binds [lists] to the "Lists" section in the main drawer. */ - private fun bindMainDrawerLists(pachliAccountId: Long, lists: List) { + private suspend fun bindMainDrawerLists(pachliAccountId: Long, lists: List) = drawerMutex.withLock { binding.mainDrawer.removeItems(*listDrawerItems.toTypedArray()) listDrawerItems.clear() @@ -868,7 +873,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { * * See [bindMainDrawerLists] and [bindMainDrawerSearch]. */ - private fun bindMainDrawerItems(pachliAccount: PachliAccount, savedInstanceState: Bundle?) { + private suspend fun bindMainDrawerItems(pachliAccount: PachliAccount, savedInstanceState: Bundle?) = drawerMutex.withLock { val pachliAccountId = pachliAccount.id binding.mainDrawer.apply { @@ -1398,7 +1403,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { * * Shows/clears a badge showing the number of unread announcements. */ - private fun bindMainDrawerAnnouncements(announcements: List) { + private suspend fun bindMainDrawerAnnouncements(announcements: List) = drawerMutex.withLock { val unread = announcements.count { !it.read } binding.mainDrawer.updateBadge(DRAWER_ITEM_ANNOUNCEMENTS, StringHolder(if (unread <= 0) null else unread.toString())) }