diff --git a/app/src/main/java/app/pachli/MainActivity.kt b/app/src/main/java/app/pachli/MainActivity.kt index e02b84b90..7d9ed5ad7 100644 --- a/app/src/main/java/app/pachli/MainActivity.kt +++ b/app/src/main/java/app/pachli/MainActivity.kt @@ -363,10 +363,18 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { } lifecycleScope.launch { - listsRepository.lists.collect { - it.onSuccess { refreshMainDrawerItems(addSearchButton = hideTopToolbar) } + listsRepository.lists.collect { result -> + result.onSuccess { lists -> + // Update the list of lists in the main drawer + refreshMainDrawerItems(addSearchButton = hideTopToolbar) - it.onFailure { + // Any lists in tabs might have changed titles, update those + if (lists is Lists.Loaded && tabAdapter.tabs.any { it.tabData is TabData.UserList }) { + setupTabs(false) + } + } + + result.onFailure { Snackbar.make(binding.root, R.string.error_list_load, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.action_retry) { listsRepository.refresh() } .show() @@ -875,11 +883,20 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { // Selected tab is either // - Notification tab (if appropriate) // - The previously selected tab (if it hasn't been removed) + // - Tabs containing lists are compared by list ID, in case the list was renamed // - Left-most tab val position = if (selectNotificationTab) { tabs.indexOfFirst { it.tabData is TabData.Notifications } } else { - previousTab?.let { tabs.indexOfFirst { it == previousTab } } + previousTab?.let { + tabs.indexOfFirst { + if (it.tabData is TabData.UserList && previousTab.tabData is TabData.UserList) { + it.tabData.listId == previousTab.tabData.listId + } else { + it == previousTab + } + } + } }.takeIf { it != -1 } ?: 0 binding.viewPager.setCurrentItem(position, false) diff --git a/core/data/src/main/kotlin/app/pachli/core/data/repository/NetworkListsRepository.kt b/core/data/src/main/kotlin/app/pachli/core/data/repository/NetworkListsRepository.kt index 1e28a0a62..5b6873b25 100644 --- a/core/data/src/main/kotlin/app/pachli/core/data/repository/NetworkListsRepository.kt +++ b/core/data/src/main/kotlin/app/pachli/core/data/repository/NetworkListsRepository.kt @@ -24,6 +24,7 @@ import app.pachli.core.data.repository.ListsError.Delete import app.pachli.core.data.repository.ListsError.GetListsWithAccount import app.pachli.core.data.repository.ListsError.Retrieve import app.pachli.core.data.repository.ListsError.Update +import app.pachli.core.database.model.TabData import app.pachli.core.network.model.MastoList import app.pachli.core.network.model.TimelineAccount import app.pachli.core.network.retrofit.MastodonApi @@ -60,12 +61,67 @@ class NetworkListsRepository @Inject constructor( _lists.value = Ok(Lists.Loading) _lists.value = api.getLists() .mapBoth( - { Ok(Lists.Loaded(it.body)) }, + { + updateTabPreferences(it.body.associateBy { it.id }) + Ok(Lists.Loaded(it.body)) + }, { Err(Retrieve(it)) }, ) } } + /** + * Updates the user's tab preferences when lists are loaded. + * + * The user may have added one or more lists to tabs. If they have then: + * + * - A list-in-a-tab might have been deleted + * - A list-in-a-tab might have been renamed + * + * Handle both of those scenarios. + * + * @param lists Map of listId -> [MastoList] + */ + private fun updateTabPreferences(lists: Map) { + val account = accountManager.activeAccount ?: return + val oldTabPreferences = account.tabPreferences + var changed = false + val newTabPreferences = buildList { + for (oldPref in oldTabPreferences) { + if (oldPref !is TabData.UserList) { + add(oldPref) + continue + } + + // List has been deleted? Don't add this pref, + // record there's been a change, and move on to the + // next one. + if (oldPref.listId !in lists) { + changed = true + continue + } + + // Title changed? Update the title in the pref and + // add it. + if (oldPref.title != lists[oldPref.listId]?.title) { + changed = true + add( + oldPref.copy( + title = lists[oldPref.listId]?.title!!, + ), + ) + continue + } + + add(oldPref) + } + } + if (changed) { + account.tabPreferences = newTabPreferences + accountManager.saveAccount(account) + } + } + override suspend fun createList(title: String, exclusive: Boolean): Result = binding { externalScope.async { api.createList(title, exclusive).mapError { Create(it) }.bind().run {